Crates.io | cainome-cairo-serde |
lib.rs | cainome-cairo-serde |
version | 0.1.0 |
source | src |
created_at | 2025-02-07 02:14:21.108412+00 |
updated_at | 2025-02-07 02:14:21.108412+00 |
description | A compile time library to serialize and deserialize cairo types to native rust types. |
homepage | https://github.com/cartridge-gg/cainome |
repository | https://github.com/cartridge-gg/cainome |
max_upload_size | |
id | 1546430 |
size | 83,250 |
Cairo serde is a compile-time library that implement a trait CairoSerde
on Rust native types.
By implementing this trait, the Rust type becomes (de)serializable from / into an array of Felt
.
The types considered built-in by Cairo Serde are the following:
pub const CAIRO_BASIC_STRUCTS: [&str; 6] = [
"Span",
"ClassHash",
"ContractAddress",
"EthAddress",
"NonZero",
"U256",
];
pub const CAIRO_BASIC_ENUMS: [&str; 3] = ["Option", "Result", "bool"];
All those types, even if they are represented in the ABI as an enum
or a struct
, has their built-in Cairo Serde implementation in this crate.
Cairo Serde provides serialization support for the following types:
boolean
-> bool
.felt252
-> starknet::core::types::Felt
.integers (signed and unsigned)
-> u[8,16,32,64,128], i[8,16,32,64,128], usize
.Option
-> Option
Result
-> Result
ContractAddress
-> Custom type in this crate ContractAddress
.EthAddress
-> Custom type in this crate EthAddress
(TODO: use the EthAddress from starknet-rs
).ClassHash
-> Custom type in this crate ClassHash
.Array/Span
-> Vec
.Tuple
-> native tuples + the unit ()
type.NonZero
-> Custom type in this crate NonZero
.u256
-> Custom type in this crate U256
.CairoSerde
traitCairo Serde trait has for now a first interface that is the following:
pub trait CairoSerde {
type RustType;
fn serialized_size(_rust: &Self::RustType) -> usize;
fn serialize(rust: &Self::RustType) -> Vec<Felt>;
fn deserialize(felts: &[Felt], offset: usize) -> Result<Self::RustType>;
}
For now, while using the deserilialize
method, you must provide the index in the buffer.
Some work that is in the roadmap:
serialize_to(rust: &Self::RustType, out: &mut Vec<Felt>)
to avoid allocating a new array for each type in a big felt buffer.deserialize(felts: &[Felt]) -> Result<Self::RustType>
without the offset using rust slice. The motivation of using an explicit offset in the first version was to keep the context of the current deserialization operation in the global buffer.# Array/Span
# The length is automatically inserted as the first element of the `Vec`
# and all the values are converted into `Felt`.
let v: Vec<u32> = vec![1, 2, 3];
let felts = Vec::<u32>::serialize(&v);
let values = Vec::<u32>::deserialize(&felts, 0).unwrap();
# Option
# The variant index is handled by the library.
let o: Option<u32> = None;
let felts = Option::<u32>::serialize(&o);
let felts = vec![Felt::ONE];
let o = Option::<u32>::deserialize(&felts, 0).unwrap();
let o = Some(u32::MAX);
let felts = Option::<u32>::serialize(&o);
let felts = vec![Felt::ZERO, Felt::from(u32::MAX)];
let o = Option::<u32>::deserialize(&felts, 0).unwrap();
# Tuples
let v = (Felt::ONE, 128_u32);
let felts = <(Felt, u32)>::serialize(&v);
let felts = vec![Felt::THREE, 99_u32.into()];
let vals = <(Felt, u32)>::deserialize(&felts, 0).unwrap();