pub mod data; pub mod transient_0; #[cfg(test)] mod test { use std::any::Any; use std::io::Cursor; use std::path::PathBuf; use std::sync::Arc; use std::collections::HashMap; use super::data::{EnumWithVariants, StructSingleton, StructWithBool, StructWithBox, StructWithDifferentSharedTypes, StructWithEnum, StructWithInt8, StructWithInt32, StructWithInt64, StructWithList, StructWithListOfShared, StructWithOption, StructWithSharedSumAndVariant, StructWithString, StructWithStruct, StructWithSum, SumWithBoxedVariants, SumWithVariants, VariantOne, VariantTwo }; #[test] fn struct_singleton() { let value = StructSingleton; assert_round_trip_encoding( "StructSingleton", value, super::data::transient_0::encode_struct_singleton, super::data::transient_0::decode_struct_singleton, ); } #[test] fn struct_with_bool() { let value = StructWithBool { a: true, b: false }; assert_round_trip_encoding( "StructWithBool", value, super::data::transient_0::encode_struct_with_bool, super::data::transient_0::decode_struct_with_bool, ); } #[test] fn struct_with_int_8() { let value = StructWithInt8 { a: 10, b: 25 }; assert_round_trip_encoding( "StructWithInt8", value, super::data::transient_0::encode_struct_with_int_8, super::data::transient_0::decode_struct_with_int_8, ); } #[test] fn struct_with_int_32() { let value = StructWithInt32 { a: 10, b: 25 }; assert_round_trip_encoding( "StructWithInt32", value, super::data::transient_0::encode_struct_with_int_32, super::data::transient_0::decode_struct_with_int_32, ); } #[test] fn struct_with_int_64() { let value = StructWithInt64 { a: 10, b: 25 }; assert_round_trip_encoding( "StructWithInt64", value, super::data::transient_0::encode_struct_with_int_64, super::data::transient_0::decode_struct_with_int_64, ); } #[test] fn struct_with_string() { let value = StructWithString { a: "abc".to_string(), b: "def".to_string() }; assert_round_trip_encoding( "StructWithString", value, super::data::transient_0::encode_struct_with_string, super::data::transient_0::decode_struct_with_string, ); } #[test] fn struct_with_struct() { let value = StructWithStruct { inner: StructWithInt32 { a: 10, b: 25 }, c: 42 }; assert_round_trip_encoding( "StructWithStruct", value, super::data::transient_0::encode_struct_with_struct, super::data::transient_0::decode_struct_with_struct, ); } #[test] fn struct_with_list() { let value = StructWithList { a: vec![10, 25], b: vec![ StructWithInt32 { a: 42, b: 47 }, StructWithInt32 { a: 52, b: 57 }, StructWithInt32 { a: 62, b: 67 }, ], }; assert_round_trip_encoding( "StructWithList", value, super::data::transient_0::encode_struct_with_list, super::data::transient_0::decode_struct_with_list, ); } #[test] fn struct_with_option_none() { let value = StructWithOption { a: None, b: None, }; assert_round_trip_encoding( "StructWithOption_None", value, super::data::transient_0::encode_struct_with_option, super::data::transient_0::decode_struct_with_option, ); } #[test] fn struct_with_option_some() { let value = StructWithOption { a: Some(10), b: Some(StructWithInt32 { a: 42, b: 47 }), }; assert_round_trip_encoding( "StructWithOption_Some", value, super::data::transient_0::encode_struct_with_option, super::data::transient_0::decode_struct_with_option, ); } #[test] fn enum_with_variants() { assert_round_trip_encoding( "EnumWithVariants_zero", EnumWithVariants::Zero, super::data::transient_0::encode_enum_with_variants, super::data::transient_0::decode_enum_with_variants, ); assert_round_trip_encoding( "EnumWithVariants_one", EnumWithVariants::One, super::data::transient_0::encode_enum_with_variants, super::data::transient_0::decode_enum_with_variants, ); assert_round_trip_encoding( "EnumWithVariants_two", EnumWithVariants::Two, super::data::transient_0::encode_enum_with_variants, super::data::transient_0::decode_enum_with_variants, ); } #[test] fn struct_with_enum() { let value = StructWithEnum { inner: EnumWithVariants::One, c: 42 }; assert_round_trip_encoding( "StructWithEnum", value, super::data::transient_0::encode_struct_with_enum, super::data::transient_0::decode_struct_with_enum, ); } #[test] fn sum_with_variants() { assert_round_trip_encoding( "SumWithVariants_VariantOne", SumWithVariants::VariantOne(VariantOne { a: 10 }), super::data::transient_0::encode_sum_with_variants, super::data::transient_0::decode_sum_with_variants, ); assert_round_trip_encoding( "SumWithVariants_VariantTwo", SumWithVariants::VariantTwo(VariantTwo { a: 25 }), super::data::transient_0::encode_sum_with_variants, super::data::transient_0::decode_sum_with_variants, ); } #[test] fn sum_with_boxed_variants() { assert_round_trip_encoding( "SumWithBoxedVariants_VariantOne", SumWithBoxedVariants::VariantOne(Box::new(VariantOne { a: 10 })), super::data::transient_0::encode_sum_with_boxed_variants, super::data::transient_0::decode_sum_with_boxed_variants, ); assert_round_trip_encoding( "SumWithBoxedVariants_VariantTwo", SumWithBoxedVariants::VariantTwo(Box::new(VariantTwo { a: 25 })), super::data::transient_0::encode_sum_with_boxed_variants, super::data::transient_0::decode_sum_with_boxed_variants, ); } #[test] fn struct_with_sum() { let value = StructWithSum { inner: SumWithVariants::VariantTwo(VariantTwo { a: 25 }), b: 42, }; assert_round_trip_encoding( "StructWithSum", value, super::data::transient_0::encode_struct_with_sum, super::data::transient_0::decode_struct_with_sum, ); } #[test] fn struct_with_box() { let value = StructWithBox { inner: Box::new(StructWithInt32 { a: 10, b: 25 }), }; assert_round_trip_encoding( "StructWithBox", value, super::data::transient_0::encode_struct_with_box, super::data::transient_0::decode_struct_with_box, ); } #[test] fn struct_with_list_of_shared() { let a = Arc::new(StructWithInt32 { a: 10, b: 25 }); let b = Arc::new(StructWithInt32 { a: 42, b: 47 }); let value = StructWithListOfShared { inner: vec![Arc::clone(&a), Arc::clone(&a), Arc::clone(&b), a, b], }; let decoded_value = assert_round_trip_encoding( "StructWithListOfShared", value, super::data::transient_0::encode_struct_with_list_of_shared, super::data::transient_0::decode_struct_with_list_of_shared, ); assert!(Arc::ptr_eq(&decoded_value.inner[0], &decoded_value.inner[1])); assert!(Arc::ptr_eq(&decoded_value.inner[0], &decoded_value.inner[3])); assert!(Arc::ptr_eq(&decoded_value.inner[2], &decoded_value.inner[4])); } #[test] fn struct_with_different_shared_types() { let a = Arc::new(StructWithInt32 { a: 10, b: 25 }); let b = Arc::new(StructWithInt64 { a: 42, b: 47 }); let c = Arc::new(StructWithInt32 { a: 52, b: 57 }); let value = StructWithDifferentSharedTypes { a, b, c }; assert_round_trip_encoding( "StructWithDifferentSharedTypes", value, super::data::transient_0::encode_struct_with_different_shared_types, super::data::transient_0::decode_struct_with_different_shared_types, ); } #[test] fn struct_with_shared_sum_and_variant() { let a = Arc::new(SumWithVariants::VariantOne(VariantOne { a: 10 })); let b = Arc::new(VariantOne { a: 10 }); let value = StructWithSharedSumAndVariant { a, b }; assert_round_trip_encoding( "StructWithSharedSumAndVariant", value, super::data::transient_0::encode_struct_with_shared_sum_and_variant, super::data::transient_0::decode_struct_with_shared_sum_and_variant, ); } fn assert_round_trip_encoding( name: &str, value: T, encode: impl Fn(&T, &mut Cursor>, &mut HashMap) -> std::io::Result<()>, decode: impl Fn(&mut Cursor>, &mut Vec>) -> std::io::Result, ) -> T { let mut bytes = Cursor::new(Vec::new()); encode(&value, &mut bytes, &mut HashMap::new()).unwrap(); let output_dir = std::env::var("HOBGOBLIN_OUTPUT_DIR").unwrap(); let transient_0_output_dir = PathBuf::from(output_dir).join("transient-0"); std::fs::create_dir_all(&transient_0_output_dir).unwrap(); let transient_0_output_path = transient_0_output_dir.join(name); std::fs::write(transient_0_output_path, bytes.get_ref()).unwrap(); bytes.set_position(0); let decoded_value = decode(&mut bytes, &mut Vec::new()).unwrap(); assert_eq!(value, decoded_value); decoded_value } }