Introduction
The molecule is a serialization format used on CKB. It has several implementations in different languages (C, Rust, JavaScript). In Rust, the implementation introduces numerous types and functions, making it difficult to remember. However, with the power of the serde framework, this process can be greatly simplified. This project offers an implementation of Molecule using Serde.
How to use
Here is a simple case about how to use:
use ;
use ;
First step is to add dependency in Cargo.toml:
= { = "???", = ["derive"] }
= { = "???" }
Then to annotate the types with #[derive(Serialize, Deserialize)]. After that,
use to_vec or from_slice to serialize/deserialize.
Types mapping
Rust types are mapping to molecule types, according to the RFC:
| Rust Type | Molecule Type | Fixed Size |
|---|---|---|
| i8,u8 | byte | yes |
| i16, u16, i32, u32, i64, u64, i128, u128 | array | yes |
| f32 | array([byte; 4]) | yes |
| f64 | array([byte; 8]) | yes |
| [u8; N] | array([byte; N]) | yes |
| [T; N] | array([T; N]) | yes |
| Vec | fixvec | no |
| struct | table | no |
| #[serde(with = "struct_serde")] | struct | yes |
| #[serde(with = "dynvec_serde")] | dynvec | no |
| Option | option | no |
| enum | union | no |
| String | fixvec | no |
| BTreeMap | dynvec | no |
| HashMap | dynvec | no |
| BinaryHeap | fixvec | no |
| LinkedList | fixvec | no |
| VecDeque | fixvec | no |
| HashSet | fixvec | no |
By default, Vec-like containers (such as Vec, BinaryHeap, etc.) are
serialized into fixvec. Every element in the Vec must have a fixed size
(like a molecule struct, array, or primitive type). If the element is not of a
fixed size, it should be annotated with #[serde(with = "dynvec_serde")]:
use dynvec_serde;
By default, every field is considered as molecule table. If it is molecule struct, we should annotate it explicitly.
use struct_serde;
If the top-level type is a molecule struct, the second argument to to_vec or
from_slice should be true. If the value is false, the top-level type is
considered a molecule table.
Map
The Rust map types (like BTreeMap and HashMap) can be mapped to the following Molecule schemas:
table MapEntry {
key: KEY_TYPE,
value: VALUE_TYPE,
}
vector Map <MapEntry>;
It is not recommended to use HashMap because its key-value pairs are stored in arbitrary order.
Union with customized id
For molecule union with customized id, see example.
no_std support
To use this library in a no_std environment:
- Disable default features for both
serde_moleculeandserde - Enable the
allocfeature forserde_molecule - Enable the
derivefeature forserde
Add the following to your Cargo.toml:
= { = "x.x.x", = false, = ["alloc"] }
= { = "x.x.x", = false, = ["derive"] }
See the no_std example for more details.
Big Array Support
The Serde framework doesn't support arrays with element sizes greater than 32.
See this solution. This limitation
can be addressed using a new serde with annotation (big_array_serde):
use ;
use big_array_serde;
Example
Here is an example definition of CKB types.