feat: implement mismatched model id + improvement
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
use bincode::{config, Decode, Encode};
|
||||
use native_model::Result;
|
||||
use native_model::{DecodeBodyError, DecodeResult, EncodeBodyError, EncodeResult, Model};
|
||||
|
||||
// Add this function to the macro for custom serialization
|
||||
fn native_model_encode<T: Encode>(obj: &T) -> anyhow::Result<Vec<u8>> {
|
||||
let result = bincode::encode_to_vec(obj, config::standard())?;
|
||||
@@ -29,16 +28,16 @@ impl Model for A {
|
||||
1
|
||||
}
|
||||
|
||||
fn native_model_decode_upgrade_body(_data: Vec<u8>, x: u32) -> Result<Self> {
|
||||
fn native_model_decode_upgrade_body(_data: Vec<u8>, _id: u32, version: u32) -> Result<Self> {
|
||||
println!(
|
||||
"A::deserialization_and_upgrade({}, {})",
|
||||
x,
|
||||
version,
|
||||
Self::native_model_version()
|
||||
);
|
||||
if x == Self::native_model_version() {
|
||||
if version == Self::native_model_version() {
|
||||
Ok(Self {})
|
||||
} else if x < Self::native_model_version() {
|
||||
panic!("The version {} not supported", x);
|
||||
} else if version < Self::native_model_version() {
|
||||
panic!("The version {} not supported", version);
|
||||
} else {
|
||||
panic!("Not implemented");
|
||||
}
|
||||
@@ -54,11 +53,11 @@ impl Model for A {
|
||||
})
|
||||
}
|
||||
|
||||
fn native_model_decode_body(data: Vec<u8>) -> DecodeResult<Self>
|
||||
fn native_model_decode_body(data: Vec<u8>, _id: u32) -> DecodeResult<Self>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
native_model_decode(data).map_err(|e| DecodeBodyError {
|
||||
native_model_decode(data).map_err(|e| DecodeBodyError::DecodeError {
|
||||
msg: format!("{}", e),
|
||||
source: e.into(),
|
||||
})
|
||||
@@ -95,16 +94,16 @@ impl Model for B {
|
||||
2
|
||||
}
|
||||
|
||||
fn native_model_decode_upgrade_body(_data: Vec<u8>, x: u32) -> Result<Self> {
|
||||
fn native_model_decode_upgrade_body(_data: Vec<u8>, id: u32, version: u32) -> Result<Self> {
|
||||
println!(
|
||||
"B::deserialization_and_upgrade({}, {})",
|
||||
x,
|
||||
version,
|
||||
Self::native_model_version()
|
||||
);
|
||||
if x == Self::native_model_version() {
|
||||
if version == Self::native_model_version() {
|
||||
Ok(Self {})
|
||||
} else if x < Self::native_model_version() {
|
||||
A::native_model_decode_upgrade_body(_data, x).map(|a| a.into())
|
||||
} else if version < Self::native_model_version() {
|
||||
A::native_model_decode_upgrade_body(_data, id, version).map(|a| a.into())
|
||||
} else {
|
||||
panic!("Not implemented");
|
||||
}
|
||||
@@ -120,11 +119,11 @@ impl Model for B {
|
||||
})
|
||||
}
|
||||
|
||||
fn native_model_decode_body(data: Vec<u8>) -> DecodeResult<Self>
|
||||
fn native_model_decode_body(data: Vec<u8>, _id: u32) -> DecodeResult<Self>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
native_model_decode(data).map_err(|e| DecodeBodyError {
|
||||
native_model_decode(data).map_err(|e| DecodeBodyError::DecodeError {
|
||||
msg: format!("{}", e),
|
||||
source: e.into(),
|
||||
})
|
||||
@@ -173,16 +172,16 @@ impl Model for C {
|
||||
3
|
||||
}
|
||||
|
||||
fn native_model_decode_upgrade_body(_data: Vec<u8>, x: u32) -> Result<Self> {
|
||||
fn native_model_decode_upgrade_body(_data: Vec<u8>, id: u32, version: u32) -> Result<Self> {
|
||||
println!(
|
||||
"C::deserialization_and_upgrade({}, {})",
|
||||
x,
|
||||
version,
|
||||
Self::native_model_version()
|
||||
);
|
||||
if x == Self::native_model_version() {
|
||||
if version == Self::native_model_version() {
|
||||
Ok(Self {})
|
||||
} else if x < Self::native_model_version() {
|
||||
let result = B::native_model_decode_upgrade_body(_data, x).map(|b| {
|
||||
} else if version < Self::native_model_version() {
|
||||
let result = B::native_model_decode_upgrade_body(_data, id, version).map(|b| {
|
||||
b.try_into()
|
||||
.map_err(|e: anyhow::Error| native_model::UpgradeError {
|
||||
msg: format!("{}", e),
|
||||
@@ -205,11 +204,11 @@ impl Model for C {
|
||||
})
|
||||
}
|
||||
|
||||
fn native_model_decode_body(data: Vec<u8>) -> DecodeResult<Self>
|
||||
fn native_model_decode_body(data: Vec<u8>, _id: u32) -> DecodeResult<Self>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
native_model_decode(data).map_err(|e| DecodeBodyError {
|
||||
native_model_decode(data).map_err(|e| DecodeBodyError::DecodeError {
|
||||
msg: format!("{}", e),
|
||||
source: e.into(),
|
||||
})
|
||||
@@ -289,16 +288,17 @@ fn test_encode_downgrade() {
|
||||
|
||||
#[test]
|
||||
fn test_decode_upgrade() {
|
||||
let x = 3;
|
||||
let result = C::native_model_decode_upgrade_body(vec![], x);
|
||||
let id = 1;
|
||||
let version = 3;
|
||||
let result = C::native_model_decode_upgrade_body(vec![], id, version);
|
||||
dbg!(&result);
|
||||
|
||||
let x = 2;
|
||||
let result = C::native_model_decode_upgrade_body(vec![], x);
|
||||
let version = 2;
|
||||
let result = C::native_model_decode_upgrade_body(vec![], id, version);
|
||||
dbg!(&result);
|
||||
|
||||
let x = 1;
|
||||
let result = C::native_model_decode_upgrade_body(vec![], x);
|
||||
let version = 1;
|
||||
let result = C::native_model_decode_upgrade_body(vec![], id, version);
|
||||
dbg!(&result);
|
||||
}
|
||||
|
||||
@@ -311,7 +311,7 @@ where
|
||||
T: Model,
|
||||
{
|
||||
if model_id == T::native_model_id() {
|
||||
T::native_model_decode_upgrade_body(_data, version)
|
||||
T::native_model_decode_upgrade_body(_data, model_id, version)
|
||||
} else {
|
||||
panic!("The model id {} not supported", model_id);
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ impl From<Foo3> for Foo2 {
|
||||
fn test_decode_foo1_to_foo2() {
|
||||
let foo1 = Foo1 { x: 100 };
|
||||
let foo1_encoded = foo1.native_model_encode_body().unwrap();
|
||||
let foo2_decoded = Foo2::native_model_decode_upgrade_body(foo1_encoded, 1).unwrap();
|
||||
let foo2_decoded = Foo2::native_model_decode_upgrade_body(foo1_encoded, 1, 1).unwrap();
|
||||
assert_eq!(foo1.x.to_string(), foo2_decoded.x);
|
||||
}
|
||||
|
||||
@@ -72,7 +72,7 @@ fn test_decode_foo2_to_foo3() {
|
||||
x: "100".to_string(),
|
||||
};
|
||||
let foo2_encoded = foo2.native_model_encode_body().unwrap();
|
||||
let foo3_decoded = Foo3::native_model_decode_upgrade_body(foo2_encoded, 2).unwrap();
|
||||
let foo3_decoded = Foo3::native_model_decode_upgrade_body(foo2_encoded, 1, 2).unwrap();
|
||||
assert_eq!(Foo3::X(100), foo3_decoded);
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ fn test_decode_foo2_to_foo3() {
|
||||
fn test_decode_foo1_to_foo3() {
|
||||
let foo1 = Foo1 { x: 100 };
|
||||
let foo1_encoded = foo1.native_model_encode_body().unwrap();
|
||||
let foo3_decoded = Foo3::native_model_decode_upgrade_body(foo1_encoded, 1).unwrap();
|
||||
let foo3_decoded = Foo3::native_model_decode_upgrade_body(foo1_encoded, 1, 1).unwrap();
|
||||
assert_eq!(Foo3::X(100), foo3_decoded);
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ fn test_decode_foo1_to_foo3() {
|
||||
fn test_decode_foo1_to_foo1() {
|
||||
let foo1 = Foo1 { x: 100 };
|
||||
let foo1_encoded = foo1.native_model_encode_body().unwrap();
|
||||
let foo1_decoded = Foo1::native_model_decode_upgrade_body(foo1_encoded, 1).unwrap();
|
||||
let foo1_decoded = Foo1::native_model_decode_upgrade_body(foo1_encoded, 1, 1).unwrap();
|
||||
assert_eq!(foo1, foo1_decoded);
|
||||
}
|
||||
|
||||
@@ -98,7 +98,7 @@ fn test_decode_foo2_to_foo2() {
|
||||
x: "100".to_string(),
|
||||
};
|
||||
let foo2_encoded = foo2.native_model_encode_body().unwrap();
|
||||
let foo2_decoded = Foo2::native_model_decode_upgrade_body(foo2_encoded, 2).unwrap();
|
||||
let foo2_decoded = Foo2::native_model_decode_upgrade_body(foo2_encoded, 1, 2).unwrap();
|
||||
assert_eq!(foo2, foo2_decoded);
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ fn test_decode_foo2_to_foo2() {
|
||||
fn test_decode_foo3_to_foo3() {
|
||||
let foo3 = Foo3::X(100);
|
||||
let foo3_encoded = foo3.native_model_encode_body().unwrap();
|
||||
let foo3_decoded = Foo3::native_model_decode_upgrade_body(foo3_encoded, 3).unwrap();
|
||||
let foo3_decoded = Foo3::native_model_decode_upgrade_body(foo3_encoded, 1, 3).unwrap();
|
||||
assert_eq!(foo3, foo3_decoded);
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ fn test_decode_foo3_to_foo3() {
|
||||
fn test_should_fail_decode_foo3_to_foo2() {
|
||||
let foo3 = Foo3::X(100);
|
||||
let foo3_encoded = foo3.native_model_encode_body().unwrap();
|
||||
let foo3_decoded = Foo2::native_model_decode_upgrade_body(foo3_encoded, 3);
|
||||
let foo3_decoded = Foo2::native_model_decode_upgrade_body(foo3_encoded, 1, 3);
|
||||
assert!(foo3_decoded.is_err());
|
||||
assert!(matches!(
|
||||
foo3_decoded.unwrap_err(),
|
||||
@@ -126,7 +126,7 @@ fn test_should_fail_decode_foo3_to_foo2() {
|
||||
fn test_should_fail_decode_foo3_to_foo1() {
|
||||
let foo3 = Foo3::X(100);
|
||||
let foo3_encoded = foo3.native_model_encode_body().unwrap();
|
||||
let foo3_decoded = Foo1::native_model_decode_upgrade_body(foo3_encoded, 3);
|
||||
let foo3_decoded = Foo1::native_model_decode_upgrade_body(foo3_encoded, 1, 3);
|
||||
assert!(foo3_decoded.is_err());
|
||||
assert!(matches!(
|
||||
foo3_decoded.unwrap_err(),
|
||||
@@ -140,10 +140,32 @@ fn test_should_fail_decode_foo2_to_foo1() {
|
||||
x: "100".to_string(),
|
||||
};
|
||||
let foo2_encoded = foo2.native_model_encode_body().unwrap();
|
||||
let foo2_decoded = Foo1::native_model_decode_upgrade_body(foo2_encoded, 2);
|
||||
let foo2_decoded = Foo1::native_model_decode_upgrade_body(foo2_encoded, 1, 2);
|
||||
assert!(foo2_decoded.is_err());
|
||||
assert!(matches!(
|
||||
foo2_decoded.unwrap_err(),
|
||||
native_model::Error::UpgradeNotSupported { from: 2, to: 1 }
|
||||
));
|
||||
}
|
||||
|
||||
#[derive(Debug, Encode, Decode, PartialEq)]
|
||||
#[native_model(id = 2, version = 1)]
|
||||
struct Foo1Bis {
|
||||
x: i32,
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_prevent_to_decode_the_wrong_model() {
|
||||
let foo1 = Foo1 { x: 100 };
|
||||
let foo1_encoded = foo1.native_model_encode_body().unwrap();
|
||||
let foo1_decoded = Foo1Bis::native_model_decode_upgrade_body(foo1_encoded, 1, 1);
|
||||
dbg!(&foo1_decoded);
|
||||
// assert!(foo1_decoded.is_err());
|
||||
// assert!(matches!(
|
||||
// foo1_decoded.unwrap_err(),
|
||||
// native_model::Error::TypeIdMismatch {
|
||||
// expected: 1,
|
||||
// actual: 1
|
||||
// }
|
||||
// ));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user