diff --git a/Cargo.toml b/Cargo.toml index bd60504..0abc1a7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,6 @@ description = "A thin wrapper around serialized data which add information of id license = "MIT" repository = "https://github.com/vincent-herlemont/native_model" readme = "README.md" -build = "build.rs" keywords = ["serialization", "interoperability", "data-consistency", "flexibility", "performance"] categories = ["data-structures", "encoding", "rust-patterns"] rust-version = "1.73.0" @@ -26,11 +25,11 @@ bincode_1_3 = { package = "bincode", version = "1.3.3", optional = true } bincode_2_rc = { package = "bincode", version = "2.0.0-rc.3", features = ["serde"], optional = true } postcard_1_0 = { package = "postcard", version = "1.0.8", features = ["alloc"], optional = true } rmp_serde_1_3 = { package = "rmp-serde", version = "1.3", optional = true } +doc-comment = "0.3.3" [dev-dependencies] serde_json = "1.0.116" criterion = { version = "0.5.1" } -skeptic = "0.13.7" [features] default = ["serde", "bincode_1_3"] @@ -38,6 +37,3 @@ default = ["serde", "bincode_1_3"] [[bench]] name = "overhead" harness = false - -[build-dependencies] -skeptic = "0.13.7" diff --git a/README.md b/README.md index 08f7eaf..f7e0dab 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ See [concepts](#concepts) for more details. ## Usage -``` +```text Application 1 (DotV1) Application 2 (DotV1 and DotV2) | | Encode DotV1 |--------------------------------> | Decode DotV1 to DotV2 @@ -29,7 +29,38 @@ See [concepts](#concepts) for more details. ``` -```rust,skt-main +```rust +use native_model::native_model; +use serde::{Deserialize, Serialize}; + +#[derive(Deserialize, Serialize, PartialEq, Debug)] +#[native_model(id = 1, version = 1)] +struct DotV1(u32, u32); + +#[derive(Deserialize, Serialize, PartialEq, Debug)] +#[native_model(id = 1, version = 2, from = DotV1)] +struct DotV2 { + name: String, + x: u64, + y: u64, +} + +impl From for DotV2 { + fn from(dot: DotV1) -> Self { + DotV2 { + name: "".to_string(), + x: dot.0 as u64, + y: dot.1 as u64, + } + } +} + +impl From for DotV1 { + fn from(dot: DotV2) -> Self { + DotV1(dot.x as u32, dot.y as u32) + } +} + // Application 1 let dot = DotV1(1, 2); let bytes = native_model::encode(&dot).unwrap(); @@ -54,7 +85,7 @@ let bytes = native_model::encode_downgrade(dot, source_version).unwrap(); // Application 1 let (dot, _) = native_model::decode::(bytes).unwrap(); assert_eq!(dot, DotV1(5, 2)); - ``` +``` - Full example [here](./tests_crate/tests/example/example_main.rs). @@ -121,8 +152,9 @@ Attributes: - `type`: The previous version of the model that you use for the TryFrom implementation. - `error`: The error type that you use for the TryFrom implementation. -```rust,skt-define-models +```rust use native_model::native_model; +use serde::{Deserialize, Serialize}; #[derive(Deserialize, Serialize, PartialEq, Debug)] #[native_model(id = 1, version = 1)] @@ -138,6 +170,22 @@ struct DotV2 { // Implement the conversion between versions From for DotV2 and From for DotV1. +impl From for DotV2 { + fn from(dot: DotV1) -> Self { + DotV2 { + name: "".to_string(), + x: dot.0 as u64, + y: dot.1 as u64, + } + } +} + +impl From for DotV1 { + fn from(dot: DotV2) -> Self { + DotV1(dot.x as u32, dot.y as u32) + } +} + #[derive(Deserialize, Serialize, PartialEq, Debug)] #[native_model(id = 1, version = 3, try_from = (DotV2, anyhow::Error))] struct DotV3 { @@ -152,6 +200,30 @@ struct Cord { } // Implement the conversion between versions From for DotV3 and From for DotV2. + +impl TryFrom for DotV3 { + type Error = anyhow::Error; + + fn try_from(dot: DotV2) -> Result { + Ok(DotV3 { + name: dot.name, + cord: Cord { x: dot.x, y: dot.y }, + }) + } +} + +impl TryFrom for DotV2 { + type Error = anyhow::Error; + + fn try_from(dot: DotV3) -> Result { + Ok(DotV2 { + name: dot.name, + x: dot.cord.x, + y: dot.cord.y, + }) + } +} + ``` ## Codecs @@ -189,6 +261,8 @@ native_model = { version = "0.4", features = [ "rmp_serde_1_3" ] } 2. Assign the `rmp_serde_1_3` codec to your `struct` using the `with` attribute: ```rust +use native_model::native_model; + #[derive(Clone, Default, serde::Deserialize, serde::Serialize)] #[native_model(id = 1, version = 1, with = native_model::rmp_serde_1_3::RmpSerde)] struct MyStruct { @@ -220,7 +294,7 @@ In order to understand how the native model works, you need to understand the fo Under the hood, the native model is a thin wrapper around serialized data. The `id` and the `version` are twice encoded with a [`little_endian::U32`](https://docs.rs/zerocopy/latest/zerocopy/byteorder/little_endian/type.U32.html). That represents 8 bytes, that are added at the beginning of the data. -``` +``` text +------------------+------------------+------------------------------------+ | ID (4 bytes) | Version (4 bytes)| Data (indeterminate-length bytes) | +------------------+------------------+------------------------------------+ diff --git a/README.md.skt.md b/README.md.skt.md deleted file mode 100644 index a8ab5d4..0000000 --- a/README.md.skt.md +++ /dev/null @@ -1,119 +0,0 @@ -```rust,skt-main -use native_model_macro::native_model; -use serde::{{Deserialize, Serialize}}; - -#[derive(Deserialize, Serialize, PartialEq, Debug)] -#[native_model(id = 1, version = 1)] -struct DotV1(u32, u32); - -#[derive(Deserialize, Serialize, PartialEq, Debug)] -#[native_model(id = 1, version = 2, from = DotV1)] -struct DotV2 {{ - name: String, - x: u64, - y: u64, -}} - -impl From for DotV2 {{ - fn from(dot: DotV1) -> Self {{ - DotV2 {{ - name: "".to_string(), - x: dot.0 as u64, - y: dot.1 as u64, - }} - }} -}} - -impl From for DotV1 {{ - fn from(dot: DotV2) -> Self {{ - DotV1(dot.x as u32, dot.y as u32) - }} -}} - - -fn main() {{ - {} -}} -``` - -```rust,skt-define-models -use serde::{{Deserialize, Serialize}}; - -{} - -impl From for DotV2 {{ - fn from(dot: DotV1) -> Self {{ - DotV2 {{ - name: "".to_string(), - x: dot.0 as u64, - y: dot.1 as u64, - }} - }} -}} - -impl From for DotV1 {{ - fn from(dot: DotV2) -> Self {{ - DotV1(dot.x as u32, dot.y as u32) - }} -}} - -impl TryFrom for DotV3 {{ - type Error = anyhow::Error; - - fn try_from(dot: DotV2) -> Result {{ - Ok(DotV3 {{ - name: dot.name, - cord: Cord {{ x: dot.x, y: dot.y }}, - }}) - }} -}} - -impl TryFrom for DotV2 {{ - type Error = anyhow::Error; - - fn try_from(dot: DotV3) -> Result {{ - Ok(DotV2 {{ - name: dot.name, - x: dot.cord.x, - y: dot.cord.y, - }}) - }} -}} - - - -fn main() {{ - let dot = DotV1(1, 2); - let bytes = native_model::encode(&dot).unwrap(); - - let (dot_decoded, _) = native_model::decode::(bytes.clone()).unwrap(); - assert_eq!(dot, dot_decoded); - - let (dot_decoded, _) = native_model::decode::(bytes.clone()).unwrap(); - assert_eq!( - DotV2 {{ - name: "".to_string(), - x: 1, - y: 2 - }}, - dot_decoded - ); - - let (dot_decoded, _) = native_model::decode::(bytes.clone()).unwrap(); - assert_eq!( - DotV3 {{ - name: "".to_string(), - cord: Cord {{ x: 1, y: 2 }} - }}, - dot_decoded - ); -}} - -``` - -```rust,skt-define-serilization-format -{} - -fn main() {{ -}} -``` \ No newline at end of file diff --git a/build.rs b/build.rs deleted file mode 100644 index 5be349f..0000000 --- a/build.rs +++ /dev/null @@ -1,11 +0,0 @@ -extern crate skeptic; - -use skeptic::{generate_doc_tests, markdown_files_of_directory}; - -fn main() { - { - let mut mdbook_files = markdown_files_of_directory("doc/"); - mdbook_files.push("README.md".into()); - generate_doc_tests(&mdbook_files); - } -} diff --git a/src/lib.rs b/src/lib.rs index d4fd5be..bcddfc5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,6 +15,15 @@ //! //! See examples in the [README.md](https://github.com/vincent-herlemont/native_model) file. +#[cfg(doctest)] +#[macro_use] +extern crate doc_comment; + +#[cfg(doctest)] +doc_comment! { + include_str!("../README.md") +} + #[cfg(any( feature = "serde", feature = "bincode_1_3", diff --git a/tests/skeptic.rs b/tests/skeptic.rs deleted file mode 100644 index ff46c9c..0000000 --- a/tests/skeptic.rs +++ /dev/null @@ -1 +0,0 @@ -include!(concat!(env!("OUT_DIR"), "/skeptic-tests.rs"));