use multi_trait::{EncodeInto, EncodeIntoBuffer, Null, TryDecodeFrom, TryNull};
fn main() {
println!("=== Multitrait Custom Type Example ===\n");
simple_newtype();
multi_field_struct();
null_trait_example();
try_null_trait_example();
nested_structures();
}
fn simple_newtype() {
println!("1. Simple Newtype Wrapper");
println!("-------------------------");
#[derive(Debug, PartialEq)]
struct UserId(u64);
impl EncodeInto for UserId {
fn encode_into(&self) -> Vec<u8> {
self.0.encode_into()
}
}
impl<'a> TryDecodeFrom<'a> for UserId {
type Error = multi_trait::Error;
fn try_decode_from(bytes: &'a [u8]) -> Result<(Self, &'a [u8]), Self::Error> {
let (id, remaining) = u64::try_decode_from(bytes)?;
Ok((UserId(id), remaining))
}
}
let user_id = UserId(12345);
println!("Original UserId: {:?}", user_id);
let encoded = user_id.encode_into();
println!("Encoded: {:?}", encoded);
let (decoded, _) = UserId::try_decode_from(&encoded).unwrap();
println!("Decoded: {:?}", decoded);
assert_eq!(user_id, decoded);
println!();
}
fn multi_field_struct() {
println!("2. Struct with Multiple Fields");
println!("-------------------------------");
#[derive(Debug, PartialEq)]
struct Person {
id: u32,
age: u8,
score: u16,
}
impl EncodeInto for Person {
fn encode_into(&self) -> Vec<u8> {
let mut buffer = Vec::new();
self.id.encode_into_buffer(&mut buffer);
self.age.encode_into_buffer(&mut buffer);
self.score.encode_into_buffer(&mut buffer);
buffer
}
}
impl<'a> TryDecodeFrom<'a> for Person {
type Error = multi_trait::Error;
fn try_decode_from(bytes: &'a [u8]) -> Result<(Self, &'a [u8]), Self::Error> {
let (id, remaining) = u32::try_decode_from(bytes)?;
let (age, remaining) = u8::try_decode_from(remaining)?;
let (score, remaining) = u16::try_decode_from(remaining)?;
Ok((Person { id, age, score }, remaining))
}
}
let person = Person {
id: 1001,
age: 25,
score: 9500,
};
println!("Original Person: {:?}", person);
let encoded = person.encode_into();
println!("Encoded ({} bytes): {:?}", encoded.len(), encoded);
let (decoded, remaining) = Person::try_decode_from(&encoded).unwrap();
println!("Decoded: {:?}", decoded);
println!("Remaining bytes: {:?}", remaining);
assert_eq!(person, decoded);
println!();
}
fn null_trait_example() {
println!("3. Implementing Null Trait");
println!("--------------------------");
#[derive(Debug, PartialEq)]
struct SessionId(u64);
impl Null for SessionId {
fn null() -> Self {
SessionId(0)
}
fn is_null(&self) -> bool {
self.0 == 0
}
}
let null_session = SessionId::null();
let valid_session = SessionId(98765);
println!(
"Null session: {:?}, is_null: {}",
null_session,
null_session.is_null()
);
println!(
"Valid session: {:?}, is_null: {}",
valid_session,
valid_session.is_null()
);
assert!(null_session.is_null());
assert!(!valid_session.is_null());
println!();
}
fn try_null_trait_example() {
println!("4. Implementing TryNull Trait");
println!("------------------------------");
#[derive(Debug, PartialEq)]
struct ValidatedToken(String);
impl TryNull for ValidatedToken {
type Error = &'static str;
fn try_null() -> Result<Self, Self::Error> {
Ok(ValidatedToken(String::from("NULL_TOKEN")))
}
fn is_null(&self) -> bool {
self.0 == "NULL_TOKEN"
}
}
match ValidatedToken::try_null() {
Ok(token) => {
println!("Created null token: {:?}", token);
println!("Is null: {}", token.is_null());
assert!(token.is_null());
}
Err(e) => {
println!("Failed to create null token: {}", e);
}
}
let valid_token = ValidatedToken(String::from("abc123"));
println!(
"Valid token: {:?}, is_null: {}",
valid_token,
valid_token.is_null()
);
assert!(!valid_token.is_null());
println!();
}
fn nested_structures() {
println!("5. Complex Nested Structures");
println!("-----------------------------");
#[derive(Debug, PartialEq)]
struct Metadata {
version: u8,
flags: u16,
}
#[derive(Debug, PartialEq)]
struct Message {
metadata: Metadata,
sender_id: u64,
message_type: u8,
}
impl EncodeInto for Metadata {
fn encode_into(&self) -> Vec<u8> {
let mut buffer = Vec::new();
self.version.encode_into_buffer(&mut buffer);
self.flags.encode_into_buffer(&mut buffer);
buffer
}
}
impl<'a> TryDecodeFrom<'a> for Metadata {
type Error = multi_trait::Error;
fn try_decode_from(bytes: &'a [u8]) -> Result<(Self, &'a [u8]), Self::Error> {
let (version, remaining) = u8::try_decode_from(bytes)?;
let (flags, remaining) = u16::try_decode_from(remaining)?;
Ok((Metadata { version, flags }, remaining))
}
}
impl EncodeInto for Message {
fn encode_into(&self) -> Vec<u8> {
let mut buffer = Vec::new();
buffer.extend_from_slice(&self.metadata.encode_into());
self.sender_id.encode_into_buffer(&mut buffer);
self.message_type.encode_into_buffer(&mut buffer);
buffer
}
}
impl<'a> TryDecodeFrom<'a> for Message {
type Error = multi_trait::Error;
fn try_decode_from(bytes: &'a [u8]) -> Result<(Self, &'a [u8]), Self::Error> {
let (metadata, remaining) = Metadata::try_decode_from(bytes)?;
let (sender_id, remaining) = u64::try_decode_from(remaining)?;
let (message_type, remaining) = u8::try_decode_from(remaining)?;
Ok((
Message {
metadata,
sender_id,
message_type,
},
remaining,
))
}
}
let message = Message {
metadata: Metadata {
version: 1,
flags: 0x0F00,
},
sender_id: 999888777,
message_type: 42,
};
println!("Original message: {:#?}", message);
let encoded = message.encode_into();
println!("Encoded ({} bytes): {:?}", encoded.len(), encoded);
let (decoded, remaining) = Message::try_decode_from(&encoded).unwrap();
println!("Decoded message: {:#?}", decoded);
println!("Remaining bytes: {:?}", remaining);
assert_eq!(message, decoded);
println!();
}