-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
100 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
## Molecule API | ||
|
||
Molecule is based on schema serialization. The serialization format generated by any language based on the same schema should be consistent. The most basic API for multiple languages should include data verification, schema compatibility reading, serialization and deserialization, and obtaining raw data (excluding the molecule header). | ||
|
||
### Rust API | ||
|
||
In the basic implementation of rust, the generated code uses three traits to implement three different functions of a structure: | ||
|
||
#### Entity | ||
```rust | ||
pub trait Entity: fmt::Debug + Default + Clone { | ||
type Builder: Builder; | ||
const NAME: &'static str; | ||
fn new_unchecked(data: Bytes) -> Self; | ||
fn as_bytes(&self) -> Bytes; | ||
fn as_slice(&self) -> &[u8]; | ||
fn from_slice(slice: &[u8]) -> VerificationResult<Self>; | ||
fn from_compatible_slice(slice: &[u8]) -> VerificationResult<Self>; | ||
fn new_builder() -> Self::Builder; | ||
fn as_builder(self) -> Self::Builder; | ||
} | ||
``` | ||
Entity corresponds to a serialized data structure. There are two APIs that are easily confused: `as_slice` defined in the trait and `raw_data` that comes with its own structure. | ||
|
||
`as_slice`: Complete molecule format data | ||
`raw_data`: Original data, i.e. without the molecule header | ||
|
||
Molecule supports compatible reading of data. The so-called compatibility refers to a structure like table, which can dynamically add fields. The old schema can read the data generated by the schema after adding fields, but it does not support deleting fields. | ||
|
||
```mol | ||
vector Inner <byte>; | ||
table Old { | ||
a: Inner, | ||
b: Inner, | ||
} | ||
table New { | ||
a: Inner, | ||
b: Inner, | ||
c: Inner, | ||
} | ||
``` | ||
|
||
Like the scheme in the example above, `Old` can use the `from_compatible_slice` api to read `New's` data.At the same time, the structure will have APIs such as `count_extra_fields`/`has_extra_fields`/`has_extra_fields` to let users know that there is extra data in the read data. It is currently compatible with reading. | ||
|
||
#### Reader | ||
```rust | ||
pub trait Reader<'r>: Sized + fmt::Debug + Clone + Copy { | ||
type Entity: Entity; | ||
const NAME: &'static str; | ||
fn verify(slice: &[u8], compatible: bool) -> VerificationResult<()>; | ||
fn new_unchecked(slice: &'r [u8]) -> Self; | ||
fn as_slice(&self) -> &'r [u8]; | ||
fn from_slice(slice: &'r [u8]) -> VerificationResult<Self> { | ||
Self::verify(slice, false).map(|_| Self::new_unchecked(slice)) | ||
} | ||
fn from_compatible_slice(slice: &'r [u8]) -> VerificationResult<Self> { | ||
Self::verify(slice, true).map(|_| Self::new_unchecked(slice)) | ||
} | ||
fn to_entity(&self) -> Self::Entity; | ||
} | ||
``` | ||
|
||
Each structure will generate at least one corresponding `Reader` structure, which has the ability to obtain the field data inside the structure. | ||
|
||
|
||
#### Builder | ||
|
||
```rust | ||
pub trait Builder: Default { | ||
type Entity: Entity; | ||
const NAME: &'static str; | ||
fn expected_length(&self) -> usize; | ||
fn write<W: io::Write>(&self, writer: &mut W) -> io::Result<()>; | ||
fn build(&self) -> Self::Entity; | ||
} | ||
``` | ||
|
||
Builder is the key to building and serializing the molecule structure. Use the builder mode to generate a builder structure, put all fields into it, and convert it into a serialized structure(Entity) through the `build` API. | ||
|
||
|
||
#### Union | ||
|
||
The union structure will have two more structures than other structures when generating code, corresponding to different internal data types, and ends with Union. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters