feat: add with macro option

This commit is contained in:
Vincent Herlemont
2023-10-29 09:34:45 +01:00
parent dc725a3380
commit fd5bbfd964
17 changed files with 240 additions and 120 deletions
+20 -12
View File
@@ -100,21 +100,28 @@ Under the hood, the native model is a thin wrapper around serialized data. The `
First, you need to set up your serialization format. You can use any serialization format.
Just define the following functions, so they must be imported in the scope where you use the native model.
Just define a struct with the name you want. This struct must implement [`native_model::Encode`](https://docs.rs/native_model/latest/native_model/trait.Encode.html) and [`native_model::Decode`](https://docs.rs/native_model/latest/native_model/trait.Decode.html) traits.
```rust,ignore
fn native_model_encode_body<T>(obj: &T) -> Result<Vec<u8>, E> {
...
In the below example we have created a struct `Bincode` that use the [bincode](https://docs.rs/bincode/latest/bincode/) crate:
```rust,skt-define-serilization-format
pub struct Bincode;
impl<T: bincode::Encode> native_model::Encode<T> for Bincode {
type Error = bincode::error::EncodeError;
fn encode(obj: &T) -> Result<Vec<u8>, bincode::error::EncodeError> {
bincode::encode_to_vec(obj, bincode::config::standard())
}
}
fn native_model_decode_body<T>(data: Vec<u8>) -> Result<T, E> {
...
impl<T: bincode::Decode> native_model::Decode<T> for Bincode {
type Error = bincode::error::DecodeError;
fn decode(data: Vec<u8>) -> Result<T, bincode::error::DecodeError> {
bincode::decode_from_slice(&data, bincode::config::standard()).map(|(result, _)| result)
}
}
```
With `T` and `E` the type depending on the serialization format you use. Just `E` need to implement the `std::error::Error` trait.
Examples:
Full examples:
- [bincode with encode/decode](./tests/example/encode_decode/bincode.rs)
- [bincode with serde](./tests/example/encode_decode/bincode_serde.rs)
@@ -126,6 +133,7 @@ Define your model using the macro [`native_model`](file:///home/vincentherlemont
Attributes:
- `id = u32`: The unique identifier of the model.
- `version = u32`: The version of the model.
- `with = type`: The serialization format that you use for the Encode/Decode implementation. Setup [here](#setup-your-serialization-format).
- `from = type`: Optional, the previous version of the model.
- `type`: The previous version of the model that you use for the From implementation.
- `try_from = (type, error)`: Optional, the previous version of the model with error handling.
@@ -136,11 +144,11 @@ Attributes:
use native_model::native_model;
#[derive(Encode, Decode, PartialEq, Debug)]
#[native_model(id = 1, version = 1)]
#[native_model(id = 1, version = 1, with = Bincode)]
struct DotV1(u32, u32);
#[derive(Encode, Decode, PartialEq, Debug)]
#[native_model(id = 1, version = 2, from = DotV1)]
#[native_model(id = 1, version = 2, with = Bincode, from = DotV1)]
struct DotV2 {
name: String,
x: u64,
@@ -150,7 +158,7 @@ struct DotV2 {
// Implement the conversion between versions From<DotV1> for DotV2 and From<DotV2> for DotV1.
#[derive(Encode, Decode, PartialEq, Debug)]
#[native_model(id = 1, version = 3, try_from = (DotV2, anyhow::Error))]
#[native_model(id = 1, version = 3, with = Bincode, try_from = (DotV2, anyhow::Error))]
struct DotV3 {
name: String,
cord: Cord,
+32 -20
View File
@@ -1,30 +1,30 @@
```rust,skt-main
use bincode;
use bincode::{{Decode, Encode}};
use bincode::{{Decode, Encode, config}};
use native_model_macro::native_model;
fn native_model_encode_body<T: bincode::Encode>(
model: &T,
) -> Result<Vec<u8>, bincode::error::EncodeError> {{
{{
bincode::encode_to_vec(model, bincode::config::standard())
pub struct Bincode;
impl<T: bincode::Encode> native_model::Encode<T> for Bincode {{
type Error = bincode::error::EncodeError;
fn encode(obj: &T) -> Result<Vec<u8>, bincode::error::EncodeError> {{
bincode::encode_to_vec(obj, config::standard())
}}
}}
fn native_model_decode_body<T: bincode::Decode>(
data: Vec<u8>,
) -> Result<T, bincode::error::DecodeError> {{
{{
bincode::decode_from_slice(&data, bincode::config::standard()).map(|(result, _)| result)
impl<T: bincode::Decode> native_model::Decode<T> for Bincode {{
type Error = bincode::error::DecodeError;
fn decode(data: Vec<u8>) -> Result<T, bincode::error::DecodeError> {{
bincode::decode_from_slice(&data, config::standard()).map(|(result, _)| result)
}}
}}
#[derive(Encode, Decode, PartialEq, Debug)]
#[native_model(id = 1, version = 1)]
#[native_model(id = 1, version = 1, with = Bincode)]
struct DotV1(u32, u32);
#[derive(Encode, Decode, PartialEq, Debug)]
#[native_model(id = 1, version = 2, from = DotV1)]
#[native_model(id = 1, version = 2, with = Bincode, from = DotV1)]
struct DotV2 {{
name: String,
x: u64,
@@ -56,17 +56,22 @@ fn main() {{
```rust,skt-define-models
use bincode::{{config, Decode, Encode}};
#[allow(dead_code)]
fn native_model_encode_body<T: Encode>(obj: &T) -> Result<Vec<u8>, bincode::error::EncodeError> {{
bincode::encode_to_vec(obj, config::standard())
pub struct Bincode;
impl<T: bincode::Encode> native_model::Encode<T> for Bincode {{
type Error = bincode::error::EncodeError;
fn encode(obj: &T) -> Result<Vec<u8>, bincode::error::EncodeError> {{
bincode::encode_to_vec(obj, config::standard())
}}
}}
#[allow(dead_code)]
fn native_model_decode_body<T: Decode>(data: Vec<u8>) -> Result<T, bincode::error::DecodeError> {{
bincode::decode_from_slice(&data, config::standard()).map(|(result, _)| result)
impl<T: bincode::Decode> native_model::Decode<T> for Bincode {{
type Error = bincode::error::DecodeError;
fn decode(data: Vec<u8>) -> Result<T, bincode::error::DecodeError> {{
bincode::decode_from_slice(&data, config::standard()).map(|(result, _)| result)
}}
}}
{}
impl From<DotV1> for DotV2 {{
@@ -137,4 +142,11 @@ fn main() {{
);
}}
```
```rust,skt-define-serilization-format
{}
fn main() {{
}}
```
@@ -21,6 +21,8 @@ pub(crate) struct ModelAttributes {
pub(crate) id: Option<LitInt>,
pub(crate) version: Option<LitInt>,
// type
pub(crate) with: Option<Path>,
// type
pub(crate) from: Option<Path>,
// (type, try_from::Error type)
pub(crate) try_from: Option<(Path, Path)>,
@@ -32,6 +34,8 @@ impl ModelAttributes {
self.id = Some(meta.value()?.parse()?);
} else if meta.path.is_ident("version") {
self.version = Some(meta.value()?.parse()?);
} else if meta.path.is_ident("with") {
self.with = Some(meta.value()?.parse()?);
} else if meta.path.is_ident("from") {
self.from = Some(meta.value()?.parse()?);
} else if meta.path.is_ident("try_from") {
@@ -72,6 +76,7 @@ impl Parse for TupleTryFrom {
/// Attributes:
/// - `id = u32`: The unique identifier of the model.
/// - `version = u32`: The version of the model.
/// - `with` = type: Required, the serialization/deserialization library that you use. Must implement `native_model::Encode` and `native_model::Decode`.
/// - `from = type`: Optional, the previous version of the model.
/// - `type`: The previous version of the model that you use for the From implementation.
/// - `try_from = (type, error)`: Optional, the previous version of the model with error handling.
@@ -92,7 +97,7 @@ pub fn native_model(args: TokenStream, input: TokenStream) -> TokenStream {
let native_model_id_fn = generate_native_model_id(&attrs);
let native_model_version_fn = generate_native_model_version(&attrs);
let native_model_encode_body_fn = generate_native_model_encode_body();
let native_model_encode_body_fn = generate_native_model_encode_body(&attrs);
let native_model_encode_downgrade_body_fn = generate_native_model_encode_downgrade_body(&attrs);
let native_model_decode_body_fn = generate_native_model_decode_body(&attrs);
let native_model_decode_upgrade_body_fn = generate_native_model_decode_upgrade_body(&attrs);
@@ -3,7 +3,8 @@ use proc_macro2::TokenStream;
use quote::quote;
pub(crate) fn generate_native_model_decode_body(attrs: &ModelAttributes) -> TokenStream {
let id = attrs.id.clone().expect("id is required");
let id = attrs.id.clone().expect("`id` is required");
let with = attrs.with.clone().expect("`with` is required");
let gen = quote! {
fn native_model_decode_body(data: Vec<u8>, id: u32) -> Result<Self, native_model::DecodeBodyError> {
println!("id: {}, {}", id, #id);
@@ -11,7 +12,8 @@ pub(crate) fn generate_native_model_decode_body(attrs: &ModelAttributes) -> Toke
return Err(native_model::DecodeBodyError::MismatchedModelId);
}
native_model_decode_body(data).map_err(|e| native_model::DecodeBodyError::DecodeError {
use native_model::Decode;
#with::decode(data).map_err(|e| native_model::DecodeBodyError::DecodeError {
msg: format!("{}", e),
source: e.into(),
})
@@ -1,10 +1,13 @@
use crate::ModelAttributes;
use proc_macro2::TokenStream;
use quote::quote;
pub(crate) fn generate_native_model_encode_body() -> TokenStream {
pub(crate) fn generate_native_model_encode_body(attrs: &ModelAttributes) -> TokenStream {
let with = attrs.with.clone().expect("`with` is required");
let gen = quote! {
fn native_model_encode_body(&self) -> Result<Vec<u8>, native_model::EncodeBodyError> {
native_model_encode_body(self).map_err(|e| native_model::EncodeBodyError {
use native_model::Encode;
#with::encode(self).map_err(|e| native_model::EncodeBodyError {
msg: format!("{}", e),
source: e.into(),
})
@@ -12,4 +15,4 @@ pub(crate) fn generate_native_model_encode_body() -> TokenStream {
};
gen.into()
}
}
@@ -0,0 +1,34 @@
/// Encode trait for your own encoding method.
///
/// Example:
/// ```rust
/// pub struct Bincode;
///
/// impl<T: bincode::Encode> native_model::Encode<T> for Bincode {
/// type Error = bincode::error::EncodeError;
/// fn encode(obj: &T) -> Result<Vec<u8>, bincode::error::EncodeError> {
/// bincode::encode_to_vec(obj, bincode::config::standard())
/// }
/// }
/// ```
pub trait Encode<T> {
type Error;
fn encode(obj: &T) -> Result<Vec<u8>, Self::Error>;
}
/// Decode trait for your own decoding method.
///
/// Example:
/// ```rust
/// pub struct Bincode;
///
/// impl<T: bincode::Decode> native_model::Decode<T> for Bincode {
/// type Error = bincode::error::DecodeError;
/// fn decode(data: Vec<u8>) -> Result<T, bincode::error::DecodeError> {
/// bincode::decode_from_slice(&data, bincode::config::standard()).map(|(result, _)| result)
/// }
/// }
pub trait Decode<T> {
type Error;
fn decode(data: Vec<u8>) -> Result<T, Self::Error>;
}
+2
View File
@@ -15,10 +15,12 @@
//!
//! See examples in the [README.md](https://github.com/vincent-herlemont/native_model) file.
mod encode_decode;
mod header;
mod model;
pub mod wrapper;
pub use encode_decode::*;
pub use model::*;
/// Macro to generate a [`native_model`] implementation for a struct.
-1
View File
@@ -5,7 +5,6 @@ pub trait Model: Sized {
fn native_model_version() -> u32;
// --------------- Decode ---------------
fn native_model_decode_body(data: Vec<u8>, id: u32) -> DecodeResult<Self>
where
Self: Sized;
@@ -1,26 +1,26 @@
use bincode;
use bincode::{Decode, Encode};
use bincode::{config, Decode, Encode};
fn native_model_encode_body<T: bincode::Encode>(
model: &T,
) -> Result<Vec<u8>, bincode::error::EncodeError> {
{
bincode::encode_to_vec(model, bincode::config::standard())
pub struct Bincode;
impl<T: bincode::Encode> native_model::Encode<T> for Bincode {
type Error = bincode::error::EncodeError;
fn encode(obj: &T) -> Result<Vec<u8>, bincode::error::EncodeError> {
bincode::encode_to_vec(obj, config::standard())
}
}
fn native_model_decode_body<T: bincode::Decode>(
data: Vec<u8>,
) -> Result<T, bincode::error::DecodeError> {
{
bincode::decode_from_slice(&data, bincode::config::standard()).map(|(result, _)| result)
impl<T: bincode::Decode> native_model::Decode<T> for Bincode {
type Error = bincode::error::DecodeError;
fn decode(data: Vec<u8>) -> Result<T, bincode::error::DecodeError> {
bincode::decode_from_slice(&data, config::standard()).map(|(result, _)| result)
}
}
use native_model_macro::native_model;
#[derive(Encode, Decode, PartialEq, Debug)]
#[native_model(id = 1, version = 1)]
#[native_model(id = 1, version = 1, with = Bincode)]
struct DotV1(u32, u32);
#[test]
@@ -1,18 +1,34 @@
use bincode;
use serde::{Deserialize, Serialize};
fn native_model_encode_body<T: Serialize>(
model: &T,
) -> Result<Vec<u8>, bincode::error::EncodeError> {
{
bincode::serde::encode_to_vec(model, bincode::config::standard())
// fn native_model_encode_body<T: Serialize>(
// model: &T,
// ) -> Result<Vec<u8>, bincode::error::EncodeError> {
// {
// bincode::serde::encode_to_vec(model, bincode::config::standard())
// }
// }
//
// fn native_model_decode_body<T: for<'a> Deserialize<'a>>(
// data: Vec<u8>,
// ) -> Result<T, bincode::error::DecodeError> {
// {
// Ok(bincode::serde::decode_from_slice(&data, bincode::config::standard())?.0)
// }
// }
pub struct Bincode;
impl<T: Serialize> native_model::Encode<T> for Bincode {
type Error = bincode::error::EncodeError;
fn encode(obj: &T) -> Result<Vec<u8>, bincode::error::EncodeError> {
bincode::serde::encode_to_vec(obj, bincode::config::standard())
}
}
fn native_model_decode_body<T: for<'a> Deserialize<'a>>(
data: Vec<u8>,
) -> Result<T, bincode::error::DecodeError> {
{
impl<T: for<'a> Deserialize<'a>> native_model::Decode<T> for Bincode {
type Error = bincode::error::DecodeError;
fn decode(data: Vec<u8>) -> Result<T, bincode::error::DecodeError> {
Ok(bincode::serde::decode_from_slice(&data, bincode::config::standard())?.0)
}
}
@@ -20,7 +36,7 @@ fn native_model_decode_body<T: for<'a> Deserialize<'a>>(
use native_model_macro::native_model;
#[derive(Serialize, Deserialize, PartialEq, Debug)]
#[native_model(id = 1, version = 1)]
#[native_model(id = 1, version = 1, with = Bincode)]
struct DotV1(u32, u32);
#[test]
@@ -1,22 +1,28 @@
use bincode::{config, Decode, Encode};
use native_model_macro::native_model;
#[allow(dead_code)]
fn native_model_encode_body<T: Encode>(obj: &T) -> Result<Vec<u8>, bincode::error::EncodeError> {
bincode::encode_to_vec(obj, config::standard())
pub struct Bincode;
impl<T: bincode::Encode> native_model::Encode<T> for Bincode {
type Error = bincode::error::EncodeError;
fn encode(obj: &T) -> Result<Vec<u8>, bincode::error::EncodeError> {
bincode::encode_to_vec(obj, config::standard())
}
}
#[allow(dead_code)]
fn native_model_decode_body<T: Decode>(data: Vec<u8>) -> Result<T, bincode::error::DecodeError> {
bincode::decode_from_slice(&data, config::standard()).map(|(result, _)| result)
impl<T: bincode::Decode> native_model::Decode<T> for Bincode {
type Error = bincode::error::DecodeError;
fn decode(data: Vec<u8>) -> Result<T, bincode::error::DecodeError> {
bincode::decode_from_slice(&data, config::standard()).map(|(result, _)| result)
}
}
#[derive(Encode, Decode, PartialEq, Debug)]
#[native_model(id = 1, version = 1)]
#[native_model(id = 1, version = 1, with = Bincode)]
struct DotV1(u32, u32);
#[derive(Encode, Decode, PartialEq, Debug)]
#[native_model(id = 1, version = 2, from = DotV1)]
#[native_model(id = 1, version = 2, with = Bincode, from = DotV1)]
struct DotV2 {
name: String,
x: u64,
@@ -40,7 +46,7 @@ impl From<DotV2> for DotV1 {
}
#[derive(Encode, Decode, PartialEq, Debug)]
#[native_model(id = 1, version = 3, try_from = (DotV2, anyhow::Error))]
#[native_model(id = 1, version = 3, with = Bincode, try_from = (DotV2, anyhow::Error))]
struct DotV3 {
name: String,
cord: Cord,
@@ -1,29 +1,28 @@
use bincode;
use bincode::{Decode, Encode};
use bincode::{config, Decode, Encode};
use native_model::native_model;
fn native_model_encode_body<T: bincode::Encode>(
model: &T,
) -> Result<Vec<u8>, bincode::error::EncodeError> {
{
bincode::encode_to_vec(model, bincode::config::standard())
pub struct Bincode;
impl<T: bincode::Encode> native_model::Encode<T> for Bincode {
type Error = bincode::error::EncodeError;
fn encode(obj: &T) -> Result<Vec<u8>, bincode::error::EncodeError> {
bincode::encode_to_vec(obj, config::standard())
}
}
fn native_model_decode_body<T: bincode::Decode>(
data: Vec<u8>,
) -> Result<T, bincode::error::DecodeError> {
{
bincode::decode_from_slice(&data, bincode::config::standard()).map(|(result, _)| result)
impl<T: bincode::Decode> native_model::Decode<T> for Bincode {
type Error = bincode::error::DecodeError;
fn decode(data: Vec<u8>) -> Result<T, bincode::error::DecodeError> {
bincode::decode_from_slice(&data, config::standard()).map(|(result, _)| result)
}
}
#[derive(Encode, Decode, PartialEq, Debug)]
#[native_model(id = 1, version = 1)]
#[native_model(id = 1, version = 1, with = Bincode)]
struct DotV1(u32, u32);
#[derive(Encode, Decode, PartialEq, Debug)]
#[native_model(id = 1, version = 2, from = DotV1)]
#[native_model(id = 1, version = 2, with = Bincode, from = DotV1)]
struct DotV2 {
name: String,
x: u64,
+14 -8
View File
@@ -2,24 +2,30 @@ use bincode::{config, Decode, Encode};
use native_model::Model;
use native_model_macro::native_model;
#[allow(dead_code)]
fn native_model_encode_body<T: Encode>(obj: &T) -> Result<Vec<u8>, bincode::error::EncodeError> {
bincode::encode_to_vec(obj, config::standard())
pub struct Bincode;
impl<T: bincode::Encode> native_model::Encode<T> for Bincode {
type Error = bincode::error::EncodeError;
fn encode(obj: &T) -> Result<Vec<u8>, bincode::error::EncodeError> {
bincode::encode_to_vec(obj, config::standard())
}
}
#[allow(dead_code)]
fn native_model_decode_body<T: Decode>(data: Vec<u8>) -> Result<T, bincode::error::DecodeError> {
bincode::decode_from_slice(&data, config::standard()).map(|(result, _)| result)
impl<T: bincode::Decode> native_model::Decode<T> for Bincode {
type Error = bincode::error::DecodeError;
fn decode(data: Vec<u8>) -> Result<T, bincode::error::DecodeError> {
bincode::decode_from_slice(&data, config::standard()).map(|(result, _)| result)
}
}
#[derive(Debug, Encode, Decode)]
#[native_model(id = 1, version = 1)]
#[native_model(id = 1, version = 1, with = Bincode)]
struct Foo1 {
x: i32,
}
#[derive(Debug, Encode, Decode)]
#[native_model(id = 1, version = 2, from = Foo1)]
#[native_model(id = 1, version = 2, with = Bincode, from = Foo1)]
struct Foo2 {
x: i32,
}
@@ -2,22 +2,30 @@ use bincode::{config, Decode, Encode};
use native_model::Model;
use native_model_macro::native_model;
fn native_model_encode_body<T: Encode>(obj: &T) -> Result<Vec<u8>, bincode::error::EncodeError> {
bincode::encode_to_vec(obj, config::standard())
pub struct Bincode;
impl<T: bincode::Encode> native_model::Encode<T> for Bincode {
type Error = bincode::error::EncodeError;
fn encode(obj: &T) -> Result<Vec<u8>, bincode::error::EncodeError> {
bincode::encode_to_vec(obj, config::standard())
}
}
fn native_model_decode_body<T: Decode>(data: Vec<u8>) -> Result<T, bincode::error::DecodeError> {
bincode::decode_from_slice(&data, config::standard()).map(|(result, _)| result)
impl<T: bincode::Decode> native_model::Decode<T> for Bincode {
type Error = bincode::error::DecodeError;
fn decode(data: Vec<u8>) -> Result<T, bincode::error::DecodeError> {
bincode::decode_from_slice(&data, config::standard()).map(|(result, _)| result)
}
}
#[derive(Debug, Encode, Decode, PartialEq)]
#[native_model(id = 1, version = 1)]
#[native_model(id = 1, version = 1, with = Bincode)]
struct Foo1 {
x: i32,
}
#[derive(Debug, Encode, Decode, PartialEq)]
#[native_model(id = 1, version = 2, from = Foo1)]
#[native_model(id = 1, version = 2, with = Bincode, from = Foo1)]
struct Foo2 {
x: String,
}
@@ -39,7 +47,7 @@ impl From<Foo2> for Foo1 {
}
#[derive(Debug, Encode, Decode, PartialEq)]
#[native_model(id = 1, version = 3, from = Foo2)]
#[native_model(id = 1, version = 3, with = Bincode, from = Foo2)]
enum Foo3 {
X(i32),
}
@@ -149,7 +157,7 @@ fn test_should_fail_decode_foo2_to_foo1() {
}
#[derive(Debug, Encode, Decode, PartialEq)]
#[native_model(id = 2, version = 1)]
#[native_model(id = 2, version = 1, with = Bincode)]
struct Foo1Bis {
x: i32,
}
@@ -2,22 +2,30 @@ use bincode::{config, Decode, Encode};
use native_model::Model;
use native_model_macro::native_model;
fn native_model_encode_body<T: Encode>(obj: &T) -> Result<Vec<u8>, bincode::error::EncodeError> {
bincode::encode_to_vec(obj, config::standard())
pub struct Bincode;
impl<T: bincode::Encode> native_model::Encode<T> for Bincode {
type Error = bincode::error::EncodeError;
fn encode(obj: &T) -> Result<Vec<u8>, bincode::error::EncodeError> {
bincode::encode_to_vec(obj, config::standard())
}
}
fn native_model_decode_body<T: Decode>(data: Vec<u8>) -> Result<T, bincode::error::DecodeError> {
bincode::decode_from_slice(&data, config::standard()).map(|(result, _)| result)
impl<T: bincode::Decode> native_model::Decode<T> for Bincode {
type Error = bincode::error::DecodeError;
fn decode(data: Vec<u8>) -> Result<T, bincode::error::DecodeError> {
bincode::decode_from_slice(&data, config::standard()).map(|(result, _)| result)
}
}
#[derive(Debug, Encode, Decode, PartialEq)]
#[native_model(id = 1, version = 1)]
#[native_model(id = 1, version = 1, with = Bincode)]
struct Foo1 {
x: i32,
}
#[derive(Debug, Encode, Decode, PartialEq)]
#[native_model(id = 1, version = 2, from = Foo1)]
#[native_model(id = 1, version = 2, with = Bincode, from = Foo1)]
struct Foo2 {
x: i32,
}
@@ -1,22 +1,27 @@
use bincode::{config, Decode, Encode};
use native_model_macro::native_model;
fn native_model_encode_body<T: Encode>(obj: &T) -> Result<Vec<u8>, bincode::error::EncodeError> {
bincode::encode_to_vec(obj, config::standard())
pub struct Bincode;
impl<T: bincode::Encode> native_model::Encode<T> for Bincode {
type Error = bincode::error::EncodeError;
fn encode(obj: &T) -> Result<Vec<u8>, bincode::error::EncodeError> {
bincode::encode_to_vec(obj, config::standard())
}
}
fn native_model_decode_body<T: Decode>(data: Vec<u8>) -> Result<T, bincode::error::DecodeError> {
bincode::decode_from_slice(&data, config::standard()).map(|(result, _)| result)
impl<T: bincode::Decode> native_model::Decode<T> for Bincode {
type Error = bincode::error::DecodeError;
fn decode(data: Vec<u8>) -> Result<T, bincode::error::DecodeError> {
bincode::decode_from_slice(&data, config::standard()).map(|(result, _)| result)
}
}
#[derive(Debug, Encode, Decode, PartialEq)]
#[native_model(id = 1, version = 1)]
#[native_model(id = 1, version = 1, with = Bincode)]
struct Foo1 {
x: i32,
}
#[derive(Debug, Encode, Decode, PartialEq)]
#[native_model(id = 1, version = 2, from = Foo1)]
#[native_model(id = 1, version = 2, with = Bincode, from = Foo1)]
struct Foo2 {
x: i32,
c: char,
@@ -1,22 +1,29 @@
use bincode::{config, Decode, Encode};
use native_model_macro::native_model;
fn native_model_encode_body<T: Encode>(obj: &T) -> Result<Vec<u8>, bincode::error::EncodeError> {
bincode::encode_to_vec(obj, config::standard())
pub struct Bincode;
impl<T: bincode::Encode> native_model::Encode<T> for Bincode {
type Error = bincode::error::EncodeError;
fn encode(obj: &T) -> Result<Vec<u8>, bincode::error::EncodeError> {
bincode::encode_to_vec(obj, config::standard())
}
}
fn native_model_decode_body<T: Decode>(data: Vec<u8>) -> Result<T, bincode::error::DecodeError> {
bincode::decode_from_slice(&data, config::standard()).map(|(result, _)| result)
impl<T: bincode::Decode> native_model::Decode<T> for Bincode {
type Error = bincode::error::DecodeError;
fn decode(data: Vec<u8>) -> Result<T, bincode::error::DecodeError> {
bincode::decode_from_slice(&data, config::standard()).map(|(result, _)| result)
}
}
#[derive(Debug, Encode, Decode, PartialEq)]
#[native_model(id = 1, version = 1)]
#[native_model(id = 1, version = 1, with = Bincode)]
struct Foo1 {
x: i32,
}
#[derive(Debug, Encode, Decode, PartialEq)]
#[native_model(id = 1, version = 2, try_from = (Foo1, anyhow::Error))]
#[native_model(id = 1, version = 2, with = Bincode, try_from = (Foo1, anyhow::Error))]
struct Foo2 {
x: i32,
}