use justcode_core::{config, Decode, Encode};
#[derive(Encode, Decode, PartialEq, Debug, Clone)]
struct Point {
x: f32,
y: f32,
}
#[derive(Encode, Decode, PartialEq, Debug, Clone)]
struct Entity {
id: u32,
position: Point,
health: f32,
active: bool,
}
#[derive(Encode, Decode, PartialEq, Debug, Clone)]
struct World {
entities: Vec<Entity>,
name: String,
}
#[test]
fn test_complex_struct_roundtrip() {
let config = config::standard();
let world = World {
entities: vec![
Entity {
id: 1,
position: Point { x: 0.0, y: 4.0 },
health: 100.0,
active: true,
},
Entity {
id: 2,
position: Point { x: 10.0, y: 20.5 },
health: 75.5,
active: false,
},
],
name: "Test World".to_string(),
};
let encoded = justcode_core::encode_to_vec(&world, config).unwrap();
let (decoded, len): (World, usize) = justcode_core::decode_from_slice(&encoded, config).unwrap();
assert_eq!(world, decoded);
assert_eq!(len, encoded.len());
}
#[test]
fn test_nested_structures() {
let config = config::standard();
let entities = vec![
Entity {
id: 1,
position: Point { x: 1.0, y: 2.0 },
health: 100.0,
active: true,
},
Entity {
id: 2,
position: Point { x: 3.0, y: 4.0 },
health: 50.0,
active: false,
},
];
let encoded = justcode_core::encode_to_vec(&entities, config).unwrap();
let (decoded, _): (Vec<Entity>, usize) = justcode_core::decode_from_slice(&encoded, config).unwrap();
assert_eq!(entities, decoded);
}
#[test]
fn test_empty_collections() {
let config = config::standard();
let empty_world = World {
entities: vec![],
name: "Empty".to_string(),
};
let encoded = justcode_core::encode_to_vec(&empty_world, config).unwrap();
let (decoded, _): (World, usize) = justcode_core::decode_from_slice(&encoded, config).unwrap();
assert_eq!(empty_world, decoded);
}
#[test]
fn test_large_dataset() {
let config = config::standard();
let mut entities = Vec::new();
for i in 0..1000 {
entities.push(Entity {
id: i,
position: Point {
x: i as f32,
y: (i * 2) as f32,
},
health: 100.0,
active: i % 2 == 0,
});
}
let encoded = justcode_core::encode_to_vec(&entities, config).unwrap();
let (decoded, _): (Vec<Entity>, usize) = justcode_core::decode_from_slice(&encoded, config).unwrap();
assert_eq!(entities.len(), decoded.len());
assert_eq!(entities, decoded);
}
#[test]
fn test_option_fields() {
#[derive(Encode, Decode, PartialEq, Debug)]
struct OptionalEntity {
id: u32,
name: Option<String>,
metadata: Option<Vec<u8>>,
}
let config = config::standard();
let entity1 = OptionalEntity {
id: 1,
name: Some("Entity 1".to_string()),
metadata: Some(vec![1, 2, 3]),
};
let entity2 = OptionalEntity {
id: 2,
name: None,
metadata: None,
};
let entities = vec![entity1, entity2];
let encoded = justcode_core::encode_to_vec(&entities, config).unwrap();
let (decoded, _): (Vec<OptionalEntity>, usize) = justcode_core::decode_from_slice(&encoded, config).unwrap();
assert_eq!(entities, decoded);
}
#[test]
fn test_config_with_limit() {
let config = config::standard().with_limit(100);
let small_data = vec![1u8, 2, 3, 4, 5];
let encoded = justcode_core::encode_to_vec(&small_data, config).unwrap();
let (decoded, _): (Vec<u8>, usize) = justcode_core::decode_from_slice(&encoded, config).unwrap();
assert_eq!(small_data, decoded);
let large_data = vec![0u8; 200];
let encoded = justcode_core::encode_to_vec(&large_data, config).unwrap();
let result: Result<(Vec<u8>, usize), _> = justcode_core::decode_from_slice(&encoded, config);
assert!(result.is_err());
}
#[test]
fn test_config_without_varint() {
let config = config::standard().with_variable_int_encoding(false);
let value = vec![1u32, 2, 3];
let encoded = justcode_core::encode_to_vec(&value, config).unwrap();
let (decoded, _): (Vec<u32>, usize) = justcode_core::decode_from_slice(&encoded, config).unwrap();
assert_eq!(value, decoded);
}
#[test]
fn test_streaming_api() {
use justcode_core::{reader::Reader, writer::Writer};
let config = config::standard();
let mut writer = Writer::new(config);
let entity = Entity {
id: 42,
position: Point { x: 1.0, y: 2.0 },
health: 100.0,
active: true,
};
entity.encode(&mut writer).unwrap();
let bytes = writer.into_bytes();
let mut reader = Reader::new(&bytes, config);
let decoded = Entity::decode(&mut reader).unwrap();
assert_eq!(entity, decoded);
assert_eq!(reader.bytes_read(), bytes.len());
}
#[test]
fn test_multiple_values_streaming() {
use justcode_core::{reader::Reader, writer::Writer};
let config = config::standard();
let mut writer = Writer::new(config);
let values = vec![
Entity {
id: 1,
position: Point { x: 1.0, y: 2.0 },
health: 100.0,
active: true,
},
Entity {
id: 2,
position: Point { x: 3.0, y: 4.0 },
health: 50.0,
active: false,
},
];
values.encode(&mut writer).unwrap();
let bytes = writer.into_bytes();
let mut reader = Reader::new(&bytes, config);
let decoded = Vec::<Entity>::decode(&mut reader).unwrap();
assert_eq!(values, decoded);
}
#[test]
fn test_error_handling() {
let config = config::standard();
let incomplete_data = vec![0u8, 1, 2];
let result: Result<(u32, usize), _> = justcode_core::decode_from_slice(&incomplete_data, config);
assert!(result.is_err());
let config = config::standard().with_limit(10);
let large_data = vec![0u8; 100];
let encoded = justcode_core::encode_to_vec(&large_data, config).unwrap();
let result: Result<(Vec<u8>, usize), _> = justcode_core::decode_from_slice(&encoded, config);
assert!(result.is_err());
}
#[test]
fn test_roundtrip_consistency() {
let config = config::standard();
let original = World {
entities: vec![
Entity {
id: 1,
position: Point { x: 10.5, y: 20.75 },
health: 100.0,
active: true,
},
],
name: "Test".to_string(),
};
let mut current = original.clone();
for _ in 0..5 {
let encoded = justcode_core::encode_to_vec(¤t, config).unwrap();
let (decoded, _): (World, usize) = justcode_core::decode_from_slice(&encoded, config).unwrap();
current = decoded;
}
assert_eq!(original, current);
}