https://github.com/is-it-ayush/rust-fr
a simple, non-self-describing data-interchange format.
https://github.com/is-it-ayush/rust-fr
crate data-interchange format rust
Last synced: 7 days ago
JSON representation
a simple, non-self-describing data-interchange format.
- Host: GitHub
- URL: https://github.com/is-it-ayush/rust-fr
- Owner: is-it-ayush
- License: mit
- Created: 2024-02-11T16:14:02.000Z (about 1 year ago)
- Default Branch: master
- Last Pushed: 2024-02-28T13:40:12.000Z (about 1 year ago)
- Last Synced: 2024-10-12T00:46:39.275Z (7 months ago)
- Topics: crate, data-interchange, format, rust
- Language: Rust
- Homepage: https://crates.io/crates/rust-fr
- Size: 83 KB
- Stars: 4
- Watchers: 1
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE.md
Awesome Lists containing this project
README
### rust-fr
'rust-fr' (aka `rust for real`) is a simple, non-self-describing data-interchange format.
### installation
You can use either of these methods.
- Add via `cargo add rust-fr`
- Add via `Cargo.toml`
```.toml
[dependencies]
rust-fr = "1"
```### usage.
```rs
use serde::{Serialize, Deserialize};
use rust_fr::{serializer, deserializer};// define some data
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
struct Human {
name: String,
age: u8
};
let human = Human {
name: "Ayush".to_string(),
age: 19
};// serialize the data to bytes (Vec)
let human_bytes = serializer::to_bytes(&human).unwrap();// deserialize the data from serialized bytes.
let deserialized_human = deserializer::from_bytes::(&human_bytes).unwrap();assert_eq!(human, deserialized_human);
```### benchmark.
- Run `cargo test -- --nocapture --ignored` to run the benchmark tests.
```sh
running 3 tests
---- Small Data ----
rust_fr: 218 bytes
serde_json: 332 bytes
rmp_serde: 146 bytes
ciborium: 170 bytes
test tests::length_test_small_data ... ok
---- Medium Data ----
rust_fr: 14264 bytes
serde_json: 30125 bytes
rmp_serde: 10731 bytes
ciborium: 18347 bytes
test tests::length_test_medium_data ... ok
---- Large Data ----
rust_fr: 139214 bytes
serde_json: 367595 bytes
rmp_serde: 157219 bytes
ciborium: 198277 bytes
test tests::length_test_large_data ... oktest result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 4 filtered out; finished in 0.01s
```### why?
The goal was to learn/understand. I wrote this so I can learn how serde internally works
and how to encode data into bytes that can ultimately be transferred over the wire
or elsewhere.### format specification.
- The format is non-self-describing.
- Primitive types are serialized as is.
- bool: 0 -> false, 1 -> true (1 bit)
- i8, i16, i32, i64: as is.
- u8, u16, u32, u64: as is.
- f32, f64: as is.
- char: as u32 (4 bytes)
- Delimiters are used to separate different types of data.
- String, Byte and Map Delimiters are 1 byte long while all other delimiters are 3 bits long.
- Delimiters:
- String = 134; 0b10000110
- Byte = 135; 0b10000111
- Unit = 2; 0b010
- Seq = 3; 0b011
- SeqValue = 4; 0b100
- Map = 139; 0b10001011
- MapKey = 6; 0b110
- MapValue = 7; 0b111
- String, Bytes, Unit, Option are serialized as:
- str: bytes + STRING_DELIMITER
- bytes: bytes + BYTE_DELIMITER
- unit: UNIT (null)
- option: None -> unit(), Some -> self
- Structs are serialized as:
- unit_struct: unit()
- newtype_struct: self
- tuple_struct: seq()
- Enums are serialized as:
- unit_variant: variant_index
- newtype_variant: variant_index + self
- tuple_variant: variant_index + tuple()
- struct_variant: variant_index + struct()
- seq(): Sequences are serialized as:
- SEQ_DELIMITER + value_1 + SEQ_VALUE_DELIMITER + value_2 + SEQ_VALUE_DELIMITER + ... + SEQ_DELIMITER
- map(): Maps are serialized as:
- key_1 + MAP_KEY_DELIMITER +
value_1 + MAP_VALUE_DELIMITER +
key_2 + MAP_KEY_DELIMITER +
value_2 + MAP_VALUE_DELIMITER +
... + MAP_DELIMITER
- Tuples and Structs are serialized as:
- tuple: seq()
- struct: map()### license.
It's MIT so you can do whatever you want. You can still read it [here](./LICENSE.md).