summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/11-transient-0/output/rust/src/gen/data/transient_0.rs342
-rw-r--r--examples/11-transient-0/output/rust/src/gen/transient_0.rs20
-rw-r--r--examples/11-transient-0/output/rust/src/lib.rs26
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttransient0/RustTransient0Generator.java179
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustTypes.java34
5 files changed, 462 insertions, 139 deletions
diff --git a/examples/11-transient-0/output/rust/src/gen/data/transient_0.rs b/examples/11-transient-0/output/rust/src/gen/data/transient_0.rs
index cffb318..6ee8baf 100644
--- a/examples/11-transient-0/output/rust/src/gen/data/transient_0.rs
+++ b/examples/11-transient-0/output/rust/src/gen/data/transient_0.rs
@@ -1,136 +1,136 @@
// Generated by hobgoblin.
-pub fn encode_struct_with_bool(value: &crate::data::StructWithBool, writer: &mut impl std::io::Write) -> ::std::io::Result::<()> {
- crate::transient_0::encode_bool(&value.a, writer)?;
- crate::transient_0::encode_bool(&value.b, writer)?;
+pub fn encode_struct_with_bool(value: &crate::data::StructWithBool, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> {
+ crate::transient_0::encode_bool(&value.a, writer, shared_values)?;
+ crate::transient_0::encode_bool(&value.b, writer, shared_values)?;
::std::io::Result::Ok(())
}
-pub fn decode_struct_with_bool(reader: &mut impl std::io::Read) -> ::std::io::Result::<crate::data::StructWithBool> {
- let a = crate::transient_0::decode_bool(reader)?;
- let b = crate::transient_0::decode_bool(reader)?;
+pub fn decode_struct_with_bool(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructWithBool> {
+ let a = crate::transient_0::decode_bool(reader, shared_values)?;
+ let b = crate::transient_0::decode_bool(reader, shared_values)?;
std::io::Result::Ok(crate::data::StructWithBool { a: a, b: b })
}
-pub fn encode_struct_with_int_32(value: &crate::data::StructWithInt32, writer: &mut impl std::io::Write) -> ::std::io::Result::<()> {
- crate::transient_0::encode_int_32(&value.a, writer)?;
- crate::transient_0::encode_int_32(&value.b, writer)?;
+pub fn encode_struct_with_int_32(value: &crate::data::StructWithInt32, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> {
+ crate::transient_0::encode_int_32(&value.a, writer, shared_values)?;
+ crate::transient_0::encode_int_32(&value.b, writer, shared_values)?;
::std::io::Result::Ok(())
}
-pub fn decode_struct_with_int_32(reader: &mut impl std::io::Read) -> ::std::io::Result::<crate::data::StructWithInt32> {
- let a = crate::transient_0::decode_int_32(reader)?;
- let b = crate::transient_0::decode_int_32(reader)?;
+pub fn decode_struct_with_int_32(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructWithInt32> {
+ let a = crate::transient_0::decode_int_32(reader, shared_values)?;
+ let b = crate::transient_0::decode_int_32(reader, shared_values)?;
std::io::Result::Ok(crate::data::StructWithInt32 { a: a, b: b })
}
-pub fn encode_struct_with_int_64(value: &crate::data::StructWithInt64, writer: &mut impl std::io::Write) -> ::std::io::Result::<()> {
- crate::transient_0::encode_int_64(&value.a, writer)?;
- crate::transient_0::encode_int_64(&value.b, writer)?;
+pub fn encode_struct_with_int_64(value: &crate::data::StructWithInt64, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> {
+ crate::transient_0::encode_int_64(&value.a, writer, shared_values)?;
+ crate::transient_0::encode_int_64(&value.b, writer, shared_values)?;
::std::io::Result::Ok(())
}
-pub fn decode_struct_with_int_64(reader: &mut impl std::io::Read) -> ::std::io::Result::<crate::data::StructWithInt64> {
- let a = crate::transient_0::decode_int_64(reader)?;
- let b = crate::transient_0::decode_int_64(reader)?;
+pub fn decode_struct_with_int_64(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructWithInt64> {
+ let a = crate::transient_0::decode_int_64(reader, shared_values)?;
+ let b = crate::transient_0::decode_int_64(reader, shared_values)?;
std::io::Result::Ok(crate::data::StructWithInt64 { a: a, b: b })
}
-pub fn encode_struct_with_string(value: &crate::data::StructWithString, writer: &mut impl std::io::Write) -> ::std::io::Result::<()> {
- crate::transient_0::encode_string(&value.a, writer)?;
- crate::transient_0::encode_string(&value.b, writer)?;
+pub fn encode_struct_with_string(value: &crate::data::StructWithString, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> {
+ crate::transient_0::encode_string(&value.a, writer, shared_values)?;
+ crate::transient_0::encode_string(&value.b, writer, shared_values)?;
::std::io::Result::Ok(())
}
-pub fn decode_struct_with_string(reader: &mut impl std::io::Read) -> ::std::io::Result::<crate::data::StructWithString> {
- let a = crate::transient_0::decode_string(reader)?;
- let b = crate::transient_0::decode_string(reader)?;
+pub fn decode_struct_with_string(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructWithString> {
+ let a = crate::transient_0::decode_string(reader, shared_values)?;
+ let b = crate::transient_0::decode_string(reader, shared_values)?;
std::io::Result::Ok(crate::data::StructWithString { a: a, b: b })
}
-pub fn encode_struct_with_struct(value: &crate::data::StructWithStruct, writer: &mut impl std::io::Write) -> ::std::io::Result::<()> {
- crate::data::transient_0::encode_struct_with_int_32(&value.inner, writer)?;
- crate::transient_0::encode_int_32(&value.c, writer)?;
+pub fn encode_struct_with_struct(value: &crate::data::StructWithStruct, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> {
+ crate::data::transient_0::encode_struct_with_int_32(&value.inner, writer, shared_values)?;
+ crate::transient_0::encode_int_32(&value.c, writer, shared_values)?;
::std::io::Result::Ok(())
}
-pub fn decode_struct_with_struct(reader: &mut impl std::io::Read) -> ::std::io::Result::<crate::data::StructWithStruct> {
- let inner = crate::data::transient_0::decode_struct_with_int_32(reader)?;
- let c = crate::transient_0::decode_int_32(reader)?;
+pub fn decode_struct_with_struct(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructWithStruct> {
+ let inner = crate::data::transient_0::decode_struct_with_int_32(reader, shared_values)?;
+ let c = crate::transient_0::decode_int_32(reader, shared_values)?;
std::io::Result::Ok(crate::data::StructWithStruct { inner: inner, c: c })
}
-pub fn encode_struct_with_list(value: &crate::data::StructWithList, writer: &mut impl std::io::Write) -> ::std::io::Result::<()> {
+pub fn encode_struct_with_list(value: &crate::data::StructWithList, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> {
{
- crate::transient_0::encode_int_64(&(((&value.a).len()).try_into()).map_err(|error| ::std::io::Error::new(::std::io::ErrorKind::InvalidData, error))?, writer)?;
+ crate::transient_0::encode_int_64(&(((&value.a).len()).try_into()).map_err(|error| ::std::io::Error::new(::std::io::ErrorKind::InvalidData, error))?, writer, shared_values)?;
for element in &value.a {
- crate::transient_0::encode_int_64(element, writer)?;
+ crate::transient_0::encode_int_64(element, writer, shared_values)?;
};
};
{
- crate::transient_0::encode_int_64(&(((&value.b).len()).try_into()).map_err(|error| ::std::io::Error::new(::std::io::ErrorKind::InvalidData, error))?, writer)?;
+ crate::transient_0::encode_int_64(&(((&value.b).len()).try_into()).map_err(|error| ::std::io::Error::new(::std::io::ErrorKind::InvalidData, error))?, writer, shared_values)?;
for element in &value.b {
- crate::data::transient_0::encode_struct_with_int_32(element, writer)?;
+ crate::data::transient_0::encode_struct_with_int_32(element, writer, shared_values)?;
};
};
::std::io::Result::Ok(())
}
-pub fn decode_struct_with_list(reader: &mut impl std::io::Read) -> ::std::io::Result::<crate::data::StructWithList> {
+pub fn decode_struct_with_list(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructWithList> {
let a = {
- let len = crate::transient_0::decode_int_64(reader)?;
+ let len = crate::transient_0::decode_int_64(reader, shared_values)?;
let mut elements = ::std::vec::Vec::with_capacity((len.try_into()).map_err(|error| ::std::io::Error::new(::std::io::ErrorKind::InvalidData, error))?);
for _ in 0..len {
- elements.push(crate::transient_0::decode_int_64(reader)?);
+ elements.push(crate::transient_0::decode_int_64(reader, shared_values)?);
};
elements
};
let b = {
- let len = crate::transient_0::decode_int_64(reader)?;
+ let len = crate::transient_0::decode_int_64(reader, shared_values)?;
let mut elements = ::std::vec::Vec::with_capacity((len.try_into()).map_err(|error| ::std::io::Error::new(::std::io::ErrorKind::InvalidData, error))?);
for _ in 0..len {
- elements.push(crate::data::transient_0::decode_struct_with_int_32(reader)?);
+ elements.push(crate::data::transient_0::decode_struct_with_int_32(reader, shared_values)?);
};
elements
};
std::io::Result::Ok(crate::data::StructWithList { a: a, b: b })
}
-pub fn encode_struct_with_option(value: &crate::data::StructWithOption, writer: &mut impl std::io::Write) -> ::std::io::Result::<()> {
+pub fn encode_struct_with_option(value: &crate::data::StructWithOption, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> {
match &value.a {
::std::option::Option::Some(value) => {
- crate::transient_0::encode_bool(&true, writer)?;
- crate::transient_0::encode_int_64(&value, writer)?;
+ crate::transient_0::encode_bool(&true, writer, shared_values)?;
+ crate::transient_0::encode_int_64(&value, writer, shared_values)?;
},
::std::option::Option::None => {
- crate::transient_0::encode_bool(&false, writer)?;
+ crate::transient_0::encode_bool(&false, writer, shared_values)?;
},
};
match &value.b {
::std::option::Option::Some(value) => {
- crate::transient_0::encode_bool(&true, writer)?;
- crate::data::transient_0::encode_struct_with_int_32(&value, writer)?;
+ crate::transient_0::encode_bool(&true, writer, shared_values)?;
+ crate::data::transient_0::encode_struct_with_int_32(&value, writer, shared_values)?;
},
::std::option::Option::None => {
- crate::transient_0::encode_bool(&false, writer)?;
+ crate::transient_0::encode_bool(&false, writer, shared_values)?;
},
};
::std::io::Result::Ok(())
}
-pub fn decode_struct_with_option(reader: &mut impl std::io::Read) -> ::std::io::Result::<crate::data::StructWithOption> {
+pub fn decode_struct_with_option(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructWithOption> {
let a = {
- let is_some = crate::transient_0::decode_bool(reader)?;
+ let is_some = crate::transient_0::decode_bool(reader, shared_values)?;
if is_some {
- ::std::option::Option::Some(crate::transient_0::decode_int_64(reader)?)
+ ::std::option::Option::Some(crate::transient_0::decode_int_64(reader, shared_values)?)
} else {
::std::option::Option::None
}
};
let b = {
- let is_some = crate::transient_0::decode_bool(reader)?;
+ let is_some = crate::transient_0::decode_bool(reader, shared_values)?;
if is_some {
- ::std::option::Option::Some(crate::data::transient_0::decode_struct_with_int_32(reader)?)
+ ::std::option::Option::Some(crate::data::transient_0::decode_struct_with_int_32(reader, shared_values)?)
} else {
::std::option::Option::None
}
@@ -138,17 +138,17 @@ pub fn decode_struct_with_option(reader: &mut impl std::io::Read) -> ::std::io::
std::io::Result::Ok(crate::data::StructWithOption { a: a, b: b })
}
-pub fn encode_enum_with_variants(value: &crate::data::EnumWithVariants, writer: &mut impl std::io::Write) -> ::std::io::Result::<()> {
+pub fn encode_enum_with_variants(value: &crate::data::EnumWithVariants, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> {
crate::transient_0::encode_int_32(&match value {
crate::data::EnumWithVariants::Zero => 0,
crate::data::EnumWithVariants::One => 1,
crate::data::EnumWithVariants::Two => 2,
- }, writer)?;
+ }, writer, shared_values)?;
::std::io::Result::Ok(())
}
-pub fn decode_enum_with_variants(reader: &mut impl std::io::Read) -> ::std::io::Result::<crate::data::EnumWithVariants> {
- std::io::Result::Ok(match &crate::transient_0::decode_int_32(reader)? {
+pub fn decode_enum_with_variants(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::EnumWithVariants> {
+ std::io::Result::Ok(match &crate::transient_0::decode_int_32(reader, shared_values)? {
0 => crate::data::EnumWithVariants::Zero,
1 => crate::data::EnumWithVariants::One,
2 => crate::data::EnumWithVariants::Two,
@@ -156,116 +156,248 @@ pub fn decode_enum_with_variants(reader: &mut impl std::io::Read) -> ::std::io::
})
}
-pub fn encode_struct_with_enum(value: &crate::data::StructWithEnum, writer: &mut impl std::io::Write) -> ::std::io::Result::<()> {
- crate::data::transient_0::encode_enum_with_variants(&value.inner, writer)?;
- crate::transient_0::encode_int_32(&value.c, writer)?;
+pub fn encode_struct_with_enum(value: &crate::data::StructWithEnum, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> {
+ crate::data::transient_0::encode_enum_with_variants(&value.inner, writer, shared_values)?;
+ crate::transient_0::encode_int_32(&value.c, writer, shared_values)?;
::std::io::Result::Ok(())
}
-pub fn decode_struct_with_enum(reader: &mut impl std::io::Read) -> ::std::io::Result::<crate::data::StructWithEnum> {
- let inner = crate::data::transient_0::decode_enum_with_variants(reader)?;
- let c = crate::transient_0::decode_int_32(reader)?;
+pub fn decode_struct_with_enum(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructWithEnum> {
+ let inner = crate::data::transient_0::decode_enum_with_variants(reader, shared_values)?;
+ let c = crate::transient_0::decode_int_32(reader, shared_values)?;
std::io::Result::Ok(crate::data::StructWithEnum { inner: inner, c: c })
}
-pub fn encode_sum_with_variants(value: &crate::data::SumWithVariants, writer: &mut impl std::io::Write) -> ::std::io::Result::<()> {
+pub fn encode_sum_with_variants(value: &crate::data::SumWithVariants, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> {
match value {
crate::data::SumWithVariants::VariantOne(value) => {
- crate::transient_0::encode_int_32(&0, writer)?;
- crate::data::transient_0::encode_variant_one(value, writer)?;
+ crate::transient_0::encode_int_32(&0, writer, shared_values)?;
+ crate::data::transient_0::encode_variant_one(value, writer, shared_values)?;
},
crate::data::SumWithVariants::VariantTwo(value) => {
- crate::transient_0::encode_int_32(&1, writer)?;
- crate::data::transient_0::encode_variant_two(value, writer)?;
+ crate::transient_0::encode_int_32(&1, writer, shared_values)?;
+ crate::data::transient_0::encode_variant_two(value, writer, shared_values)?;
},
};
::std::io::Result::Ok(())
}
-pub fn decode_sum_with_variants(reader: &mut impl std::io::Read) -> ::std::io::Result::<crate::data::SumWithVariants> {
- std::io::Result::Ok(match &crate::transient_0::decode_int_32(reader)? {
- 0 => crate::data::SumWithVariants::VariantOne(crate::data::transient_0::decode_variant_one(reader)?),
- 1 => crate::data::SumWithVariants::VariantTwo(crate::data::transient_0::decode_variant_two(reader)?),
+pub fn decode_sum_with_variants(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::SumWithVariants> {
+ std::io::Result::Ok(match &crate::transient_0::decode_int_32(reader, shared_values)? {
+ 0 => crate::data::SumWithVariants::VariantOne(crate::data::transient_0::decode_variant_one(reader, shared_values)?),
+ 1 => crate::data::SumWithVariants::VariantTwo(crate::data::transient_0::decode_variant_two(reader, shared_values)?),
_ => todo!(),
})
}
-pub fn encode_variant_one(value: &crate::data::VariantOne, writer: &mut impl std::io::Write) -> ::std::io::Result::<()> {
- crate::transient_0::encode_int_32(&value.a, writer)?;
+pub fn encode_variant_one(value: &crate::data::VariantOne, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> {
+ crate::transient_0::encode_int_32(&value.a, writer, shared_values)?;
::std::io::Result::Ok(())
}
-pub fn decode_variant_one(reader: &mut impl std::io::Read) -> ::std::io::Result::<crate::data::VariantOne> {
- let a = crate::transient_0::decode_int_32(reader)?;
+pub fn decode_variant_one(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::VariantOne> {
+ let a = crate::transient_0::decode_int_32(reader, shared_values)?;
std::io::Result::Ok(crate::data::VariantOne { a: a })
}
-pub fn encode_variant_two(value: &crate::data::VariantTwo, writer: &mut impl std::io::Write) -> ::std::io::Result::<()> {
- crate::transient_0::encode_int_64(&value.a, writer)?;
+pub fn encode_variant_two(value: &crate::data::VariantTwo, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> {
+ crate::transient_0::encode_int_64(&value.a, writer, shared_values)?;
::std::io::Result::Ok(())
}
-pub fn decode_variant_two(reader: &mut impl std::io::Read) -> ::std::io::Result::<crate::data::VariantTwo> {
- let a = crate::transient_0::decode_int_64(reader)?;
+pub fn decode_variant_two(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::VariantTwo> {
+ let a = crate::transient_0::decode_int_64(reader, shared_values)?;
std::io::Result::Ok(crate::data::VariantTwo { a: a })
}
-pub fn encode_struct_with_sum(value: &crate::data::StructWithSum, writer: &mut impl std::io::Write) -> ::std::io::Result::<()> {
- crate::data::transient_0::encode_sum_with_variants(&value.inner, writer)?;
- crate::transient_0::encode_int_32(&value.b, writer)?;
+pub fn encode_struct_with_sum(value: &crate::data::StructWithSum, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> {
+ crate::data::transient_0::encode_sum_with_variants(&value.inner, writer, shared_values)?;
+ crate::transient_0::encode_int_32(&value.b, writer, shared_values)?;
::std::io::Result::Ok(())
}
-pub fn decode_struct_with_sum(reader: &mut impl std::io::Read) -> ::std::io::Result::<crate::data::StructWithSum> {
- let inner = crate::data::transient_0::decode_sum_with_variants(reader)?;
- let b = crate::transient_0::decode_int_32(reader)?;
+pub fn decode_struct_with_sum(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructWithSum> {
+ let inner = crate::data::transient_0::decode_sum_with_variants(reader, shared_values)?;
+ let b = crate::transient_0::decode_int_32(reader, shared_values)?;
std::io::Result::Ok(crate::data::StructWithSum { inner: inner, b: b })
}
-pub fn encode_struct_with_list_of_shared(value: &crate::data::StructWithListOfShared, writer: &mut impl std::io::Write) -> ::std::io::Result::<()> {
+pub fn encode_struct_with_list_of_shared(value: &crate::data::StructWithListOfShared, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> {
{
- crate::transient_0::encode_int_64(&(((&value.inner).len()).try_into()).map_err(|error| ::std::io::Error::new(::std::io::ErrorKind::InvalidData, error))?, writer)?;
+ crate::transient_0::encode_int_64(&(((&value.inner).len()).try_into()).map_err(|error| ::std::io::Error::new(::std::io::ErrorKind::InvalidData, error))?, writer, shared_values)?;
for element in &value.inner {
- crate::data::transient_0::encode_struct_with_int_32(element.as_ref(), writer)?;
+ {
+ let ptr = ::std::sync::Arc::as_ptr(&element) as ::core::primitive::usize;
+ match (shared_values.get(&ptr)).copied() {
+ ::std::option::Option::Some(id) => {
+ crate::transient_0::encode_int_64(&id, writer, shared_values)?;
+ },
+ ::std::option::Option::None => {
+ let id = ((shared_values.len()).try_into()).map_err(|error| ::std::io::Error::new(::std::io::ErrorKind::InvalidData, error))?;
+ crate::transient_0::encode_int_64(&id, writer, shared_values)?;
+ shared_values.insert(ptr, id);
+ crate::data::transient_0::encode_struct_with_int_32(element.as_ref(), writer, shared_values)?;
+ },
+ };
+ };
};
};
::std::io::Result::Ok(())
}
-pub fn decode_struct_with_list_of_shared(reader: &mut impl std::io::Read) -> ::std::io::Result::<crate::data::StructWithListOfShared> {
+pub fn decode_struct_with_list_of_shared(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructWithListOfShared> {
let inner = {
- let len = crate::transient_0::decode_int_64(reader)?;
+ let len = crate::transient_0::decode_int_64(reader, shared_values)?;
let mut elements = ::std::vec::Vec::with_capacity((len.try_into()).map_err(|error| ::std::io::Error::new(::std::io::ErrorKind::InvalidData, error))?);
for _ in 0..len {
- elements.push(::std::sync::Arc::new(crate::data::transient_0::decode_struct_with_int_32(reader)?));
+ elements.push({
+ let id = crate::transient_0::decode_int_64(reader, shared_values)?;
+ if id < ((shared_values.len()).try_into()).map_err(|error| ::std::io::Error::new(::std::io::ErrorKind::InvalidData, error))? {
+ ((::std::sync::Arc::clone(&shared_values[id as ::core::primitive::usize])).downcast()).unwrap()
+ } else {
+ let decoded_value = ::std::sync::Arc::new(crate::data::transient_0::decode_struct_with_int_32(reader, shared_values)?);
+ shared_values.push(::std::sync::Arc::clone(&decoded_value) as ::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>);
+ decoded_value
+ }
+ });
};
elements
};
std::io::Result::Ok(crate::data::StructWithListOfShared { inner: inner })
}
-pub fn encode_struct_with_different_shared_types(value: &crate::data::StructWithDifferentSharedTypes, writer: &mut impl std::io::Write) -> ::std::io::Result::<()> {
- crate::data::transient_0::encode_struct_with_int_32((&value.a).as_ref(), writer)?;
- crate::data::transient_0::encode_struct_with_int_64((&value.b).as_ref(), writer)?;
- crate::data::transient_0::encode_struct_with_int_32((&value.c).as_ref(), writer)?;
+pub fn encode_struct_with_different_shared_types(value: &crate::data::StructWithDifferentSharedTypes, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> {
+ {
+ let ptr = ::std::sync::Arc::as_ptr(&&value.a) as ::core::primitive::usize;
+ match (shared_values.get(&ptr)).copied() {
+ ::std::option::Option::Some(id) => {
+ crate::transient_0::encode_int_64(&id, writer, shared_values)?;
+ },
+ ::std::option::Option::None => {
+ let id = ((shared_values.len()).try_into()).map_err(|error| ::std::io::Error::new(::std::io::ErrorKind::InvalidData, error))?;
+ crate::transient_0::encode_int_64(&id, writer, shared_values)?;
+ shared_values.insert(ptr, id);
+ crate::data::transient_0::encode_struct_with_int_32((&value.a).as_ref(), writer, shared_values)?;
+ },
+ };
+ };
+ {
+ let ptr = ::std::sync::Arc::as_ptr(&&value.b) as ::core::primitive::usize;
+ match (shared_values.get(&ptr)).copied() {
+ ::std::option::Option::Some(id) => {
+ crate::transient_0::encode_int_64(&id, writer, shared_values)?;
+ },
+ ::std::option::Option::None => {
+ let id = ((shared_values.len()).try_into()).map_err(|error| ::std::io::Error::new(::std::io::ErrorKind::InvalidData, error))?;
+ crate::transient_0::encode_int_64(&id, writer, shared_values)?;
+ shared_values.insert(ptr, id);
+ crate::data::transient_0::encode_struct_with_int_64((&value.b).as_ref(), writer, shared_values)?;
+ },
+ };
+ };
+ {
+ let ptr = ::std::sync::Arc::as_ptr(&&value.c) as ::core::primitive::usize;
+ match (shared_values.get(&ptr)).copied() {
+ ::std::option::Option::Some(id) => {
+ crate::transient_0::encode_int_64(&id, writer, shared_values)?;
+ },
+ ::std::option::Option::None => {
+ let id = ((shared_values.len()).try_into()).map_err(|error| ::std::io::Error::new(::std::io::ErrorKind::InvalidData, error))?;
+ crate::transient_0::encode_int_64(&id, writer, shared_values)?;
+ shared_values.insert(ptr, id);
+ crate::data::transient_0::encode_struct_with_int_32((&value.c).as_ref(), writer, shared_values)?;
+ },
+ };
+ };
::std::io::Result::Ok(())
}
-pub fn decode_struct_with_different_shared_types(reader: &mut impl std::io::Read) -> ::std::io::Result::<crate::data::StructWithDifferentSharedTypes> {
- let a = ::std::sync::Arc::new(crate::data::transient_0::decode_struct_with_int_32(reader)?);
- let b = ::std::sync::Arc::new(crate::data::transient_0::decode_struct_with_int_64(reader)?);
- let c = ::std::sync::Arc::new(crate::data::transient_0::decode_struct_with_int_32(reader)?);
+pub fn decode_struct_with_different_shared_types(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructWithDifferentSharedTypes> {
+ let a = {
+ let id = crate::transient_0::decode_int_64(reader, shared_values)?;
+ if id < ((shared_values.len()).try_into()).map_err(|error| ::std::io::Error::new(::std::io::ErrorKind::InvalidData, error))? {
+ ((::std::sync::Arc::clone(&shared_values[id as ::core::primitive::usize])).downcast()).unwrap()
+ } else {
+ let decoded_value = ::std::sync::Arc::new(crate::data::transient_0::decode_struct_with_int_32(reader, shared_values)?);
+ shared_values.push(::std::sync::Arc::clone(&decoded_value) as ::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>);
+ decoded_value
+ }
+ };
+ let b = {
+ let id = crate::transient_0::decode_int_64(reader, shared_values)?;
+ if id < ((shared_values.len()).try_into()).map_err(|error| ::std::io::Error::new(::std::io::ErrorKind::InvalidData, error))? {
+ ((::std::sync::Arc::clone(&shared_values[id as ::core::primitive::usize])).downcast()).unwrap()
+ } else {
+ let decoded_value = ::std::sync::Arc::new(crate::data::transient_0::decode_struct_with_int_64(reader, shared_values)?);
+ shared_values.push(::std::sync::Arc::clone(&decoded_value) as ::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>);
+ decoded_value
+ }
+ };
+ let c = {
+ let id = crate::transient_0::decode_int_64(reader, shared_values)?;
+ if id < ((shared_values.len()).try_into()).map_err(|error| ::std::io::Error::new(::std::io::ErrorKind::InvalidData, error))? {
+ ((::std::sync::Arc::clone(&shared_values[id as ::core::primitive::usize])).downcast()).unwrap()
+ } else {
+ let decoded_value = ::std::sync::Arc::new(crate::data::transient_0::decode_struct_with_int_32(reader, shared_values)?);
+ shared_values.push(::std::sync::Arc::clone(&decoded_value) as ::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>);
+ decoded_value
+ }
+ };
std::io::Result::Ok(crate::data::StructWithDifferentSharedTypes { a: a, b: b, c: c })
}
-pub fn encode_struct_with_shared_sum_and_variant(value: &crate::data::StructWithSharedSumAndVariant, writer: &mut impl std::io::Write) -> ::std::io::Result::<()> {
- crate::data::transient_0::encode_sum_with_variants((&value.a).as_ref(), writer)?;
- crate::data::transient_0::encode_variant_one((&value.b).as_ref(), writer)?;
+pub fn encode_struct_with_shared_sum_and_variant(value: &crate::data::StructWithSharedSumAndVariant, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> {
+ {
+ let ptr = ::std::sync::Arc::as_ptr(&&value.a) as ::core::primitive::usize;
+ match (shared_values.get(&ptr)).copied() {
+ ::std::option::Option::Some(id) => {
+ crate::transient_0::encode_int_64(&id, writer, shared_values)?;
+ },
+ ::std::option::Option::None => {
+ let id = ((shared_values.len()).try_into()).map_err(|error| ::std::io::Error::new(::std::io::ErrorKind::InvalidData, error))?;
+ crate::transient_0::encode_int_64(&id, writer, shared_values)?;
+ shared_values.insert(ptr, id);
+ crate::data::transient_0::encode_sum_with_variants((&value.a).as_ref(), writer, shared_values)?;
+ },
+ };
+ };
+ {
+ let ptr = ::std::sync::Arc::as_ptr(&&value.b) as ::core::primitive::usize;
+ match (shared_values.get(&ptr)).copied() {
+ ::std::option::Option::Some(id) => {
+ crate::transient_0::encode_int_64(&id, writer, shared_values)?;
+ },
+ ::std::option::Option::None => {
+ let id = ((shared_values.len()).try_into()).map_err(|error| ::std::io::Error::new(::std::io::ErrorKind::InvalidData, error))?;
+ crate::transient_0::encode_int_64(&id, writer, shared_values)?;
+ shared_values.insert(ptr, id);
+ crate::data::transient_0::encode_variant_one((&value.b).as_ref(), writer, shared_values)?;
+ },
+ };
+ };
::std::io::Result::Ok(())
}
-pub fn decode_struct_with_shared_sum_and_variant(reader: &mut impl std::io::Read) -> ::std::io::Result::<crate::data::StructWithSharedSumAndVariant> {
- let a = ::std::sync::Arc::new(crate::data::transient_0::decode_sum_with_variants(reader)?);
- let b = ::std::sync::Arc::new(crate::data::transient_0::decode_variant_one(reader)?);
+pub fn decode_struct_with_shared_sum_and_variant(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<crate::data::StructWithSharedSumAndVariant> {
+ let a = {
+ let id = crate::transient_0::decode_int_64(reader, shared_values)?;
+ if id < ((shared_values.len()).try_into()).map_err(|error| ::std::io::Error::new(::std::io::ErrorKind::InvalidData, error))? {
+ ((::std::sync::Arc::clone(&shared_values[id as ::core::primitive::usize])).downcast()).unwrap()
+ } else {
+ let decoded_value = ::std::sync::Arc::new(crate::data::transient_0::decode_sum_with_variants(reader, shared_values)?);
+ shared_values.push(::std::sync::Arc::clone(&decoded_value) as ::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>);
+ decoded_value
+ }
+ };
+ let b = {
+ let id = crate::transient_0::decode_int_64(reader, shared_values)?;
+ if id < ((shared_values.len()).try_into()).map_err(|error| ::std::io::Error::new(::std::io::ErrorKind::InvalidData, error))? {
+ ((::std::sync::Arc::clone(&shared_values[id as ::core::primitive::usize])).downcast()).unwrap()
+ } else {
+ let decoded_value = ::std::sync::Arc::new(crate::data::transient_0::decode_variant_one(reader, shared_values)?);
+ shared_values.push(::std::sync::Arc::clone(&decoded_value) as ::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>);
+ decoded_value
+ }
+ };
std::io::Result::Ok(crate::data::StructWithSharedSumAndVariant { a: a, b: b })
}
diff --git a/examples/11-transient-0/output/rust/src/gen/transient_0.rs b/examples/11-transient-0/output/rust/src/gen/transient_0.rs
index 560fe51..393b397 100644
--- a/examples/11-transient-0/output/rust/src/gen/transient_0.rs
+++ b/examples/11-transient-0/output/rust/src/gen/transient_0.rs
@@ -1,6 +1,6 @@
// Generated by hobgoblin.
-pub fn encode_bool(value: &::core::primitive::bool, writer: &mut impl std::io::Write) -> ::std::io::Result::<()> {
+pub fn encode_bool(value: &::core::primitive::bool, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> {
if *value {
writer.write_all(&1u8.to_le_bytes())?;
} else {
@@ -9,7 +9,7 @@ pub fn encode_bool(value: &::core::primitive::bool, writer: &mut impl std::io::W
::std::io::Result::Ok(())
}
-pub fn decode_bool(reader: &mut impl std::io::Read) -> ::std::io::Result::<::core::primitive::bool> {
+pub fn decode_bool(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<::core::primitive::bool> {
let int_value = {
let bytes = {
let mut bytes = [0; 1];
@@ -25,12 +25,12 @@ pub fn decode_bool(reader: &mut impl std::io::Read) -> ::std::io::Result::<::cor
})
}
-pub fn encode_int_32(value: &::core::primitive::i32, writer: &mut impl std::io::Write) -> ::std::io::Result::<()> {
+pub fn encode_int_32(value: &::core::primitive::i32, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> {
writer.write_all(&value.to_le_bytes())?;
::std::io::Result::Ok(())
}
-pub fn decode_int_32(reader: &mut impl std::io::Read) -> ::std::io::Result::<::core::primitive::i32> {
+pub fn decode_int_32(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<::core::primitive::i32> {
let bytes = {
let mut bytes = [0; 4];
reader.read_exact(&mut bytes)?;
@@ -39,12 +39,12 @@ pub fn decode_int_32(reader: &mut impl std::io::Read) -> ::std::io::Result::<::c
std::io::Result::Ok(::core::primitive::i32::from_le_bytes(bytes))
}
-pub fn encode_int_64(value: &::core::primitive::i64, writer: &mut impl std::io::Write) -> ::std::io::Result::<()> {
+pub fn encode_int_64(value: &::core::primitive::i64, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> {
writer.write_all(&value.to_le_bytes())?;
::std::io::Result::Ok(())
}
-pub fn decode_int_64(reader: &mut impl std::io::Read) -> ::std::io::Result::<::core::primitive::i64> {
+pub fn decode_int_64(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<::core::primitive::i64> {
let bytes = {
let mut bytes = [0; 8];
reader.read_exact(&mut bytes)?;
@@ -53,14 +53,14 @@ pub fn decode_int_64(reader: &mut impl std::io::Read) -> ::std::io::Result::<::c
std::io::Result::Ok(::core::primitive::i64::from_le_bytes(bytes))
}
-pub fn encode_string(value: &::std::string::String, writer: &mut impl std::io::Write) -> ::std::io::Result::<()> {
- crate::transient_0::encode_int_64(&((value.len()).try_into()).map_err(|error| ::std::io::Error::new(::std::io::ErrorKind::InvalidData, error))?, writer)?;
+pub fn encode_string(value: &::std::string::String, writer: &mut impl std::io::Write, shared_values: &mut ::std::collections::HashMap::<::core::primitive::usize, ::core::primitive::i64>) -> ::std::io::Result::<()> {
+ crate::transient_0::encode_int_64(&((value.len()).try_into()).map_err(|error| ::std::io::Error::new(::std::io::ErrorKind::InvalidData, error))?, writer, shared_values)?;
writer.write_all(value.as_bytes())?;
::std::io::Result::Ok(())
}
-pub fn decode_string(reader: &mut impl std::io::Read) -> ::std::io::Result::<::std::string::String> {
- let len = crate::transient_0::decode_int_64(reader)?;
+pub fn decode_string(reader: &mut impl std::io::Read, shared_values: &mut ::std::vec::Vec::<::std::sync::Arc::<dyn ::std::any::Any + ::std::marker::Sync + ::std::marker::Send>>) -> ::std::io::Result::<::std::string::String> {
+ let len = crate::transient_0::decode_int_64(reader, shared_values)?;
let bytes = {
let mut bytes = vec![0u8; (len.try_into()).map_err(|error| ::std::io::Error::new(::std::io::ErrorKind::InvalidData, error))?];
reader.read_exact(&mut bytes)?;
diff --git a/examples/11-transient-0/output/rust/src/lib.rs b/examples/11-transient-0/output/rust/src/lib.rs
index 63e7c67..63a2799 100644
--- a/examples/11-transient-0/output/rust/src/lib.rs
+++ b/examples/11-transient-0/output/rust/src/lib.rs
@@ -3,8 +3,10 @@ pub mod transient_0;
#[cfg(test)]
mod test {
+ use std::any::Any;
use std::io::Cursor;
use std::sync::Arc;
+ use std::collections::HashMap;
use super::data::{EnumWithVariants, StructWithBool, StructWithDifferentSharedTypes, StructWithEnum, StructWithInt32, StructWithInt64, StructWithList, StructWithListOfShared, StructWithOption, StructWithSharedSumAndVariant, StructWithString, StructWithStruct, StructWithSum, SumWithVariants, VariantOne, VariantTwo };
#[test]
@@ -171,17 +173,21 @@ mod test {
#[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::new(StructWithInt32 { a: 10, b: 25 }),
- ],
+ inner: vec![Arc::clone(&a), Arc::clone(&a), Arc::clone(&b), a, b],
};
- assert_round_trip_encoding(
+ let decoded_value = assert_round_trip_encoding(
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]
@@ -215,15 +221,17 @@ mod test {
fn assert_round_trip_encoding<T: std::cmp::PartialEq + std::fmt::Debug>(
value: T,
- encode: impl Fn(&T, &mut Cursor<Vec<u8>>) -> std::io::Result<()>,
- decode: impl Fn(&mut Cursor<Vec<u8>>) -> std::io::Result<T>,
- ) {
+ encode: impl Fn(&T, &mut Cursor<Vec<u8>>, &mut HashMap<usize, i64>) -> std::io::Result<()>,
+ decode: impl Fn(&mut Cursor<Vec<u8>>, &mut Vec<Arc<dyn Any + Sync + Send>>) -> std::io::Result<T>,
+ ) -> T {
let mut bytes = Cursor::new(Vec::new());
- encode(&value, &mut bytes).unwrap();
+ encode(&value, &mut bytes, &mut HashMap::new()).unwrap();
bytes.set_position(0);
- let decoded_value = decode(&mut bytes).unwrap();
+ let decoded_value = decode(&mut bytes, &mut Vec::new()).unwrap();
assert_eq!(value, decoded_value);
+
+ decoded_value
}
}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttransient0/RustTransient0Generator.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttransient0/RustTransient0Generator.java
index af28e96..e37a974 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttransient0/RustTransient0Generator.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/generators/rusttransient0/RustTransient0Generator.java
@@ -29,6 +29,7 @@ public class RustTransient0Generator implements Generator {
private static final RustIdentifier VALUE_NAME = RustIdentifier.of("value");
private static final RustIdentifier READER_NAME = RustIdentifier.of("reader");
private static final RustIdentifier WRITER_NAME = RustIdentifier.of("writer");
+ private static final RustIdentifier SHARED_VALUES_NAME = RustIdentifier.of("shared_values");
public static OutputConfig parseGeneratorConfig(
Path projectRoot,
@@ -508,7 +509,13 @@ public class RustTransient0Generator implements Generator {
encodeMethodName(type),
List.of(
new RustFunctionParam(VALUE_NAME, new RustSharedReferenceType(rustType)),
- new RustFunctionParam(WRITER_NAME, new RustMutableReferenceType(new RustImplTraitType(RustPath.of("std", "io", "Write"))))
+ new RustFunctionParam(WRITER_NAME, new RustMutableReferenceType(new RustImplTraitType(RustPath.of("std", "io", "Write")))),
+ new RustFunctionParam(
+ SHARED_VALUES_NAME,
+ new RustMutableReferenceType(
+ RustTypes.hashMap(RustTypes.USIZE, RustPath.primitive("i64"))
+ )
+ )
),
Optional.of(
RustPath.global("std", "io", "Result")
@@ -536,7 +543,10 @@ public class RustTransient0Generator implements Generator {
Optional.of(RustVisibility.PUB),
decodeMethodName(type),
List.of(
- new RustFunctionParam(READER_NAME, new RustMutableReferenceType(new RustImplTraitType(RustPath.of("std", "io", "Read"))))
+ new RustFunctionParam(READER_NAME, new RustMutableReferenceType(new RustImplTraitType(RustPath.of("std", "io", "Read")))),
+ new RustFunctionParam(SHARED_VALUES_NAME, new RustMutableReferenceType(
+ RustTypes.vec(RustTypes.arc(RustTypes.dyn(RustTypes.ANY, RustTypes.SYNC, RustTypes.SEND)))
+ ))
),
Optional.of(RustPath.global("std", "io", "Result").withArgs(List.of(rustType))),
Optional.of(new RustBlockExpression(
@@ -637,7 +647,7 @@ public class RustTransient0Generator implements Generator {
return new RustExpressionStatement(new RustTryPropagationExpression(new RustCallExpression(
rustEncodeFunctionPath,
- List.of(value, RustPath.of(WRITER_NAME))
+ List.of(value, RustPath.of(WRITER_NAME), RustPath.of(SHARED_VALUES_NAME))
)));
}
@@ -652,7 +662,7 @@ public class RustTransient0Generator implements Generator {
return new RustTryPropagationExpression(new RustCallExpression(
rustDecodeFunctionPath,
- List.of(RustPath.of(READER_NAME))
+ List.of(RustPath.of(READER_NAME), RustPath.of(SHARED_VALUES_NAME))
));
}
@@ -784,20 +794,161 @@ public class RustTransient0Generator implements Generator {
}
private RustStatement generateEncodeShared(RustExpression value, Type type) {
- return generateEncode(
- new RustCallExpression(
- new RustFieldExpression(value, RustIdentifier.of("as_ref")),
- List.of()
+ var ptr = RustIdentifier.of("ptr");
+ var id = RustIdentifier.of("id");
+
+ return new RustExpressionStatement(new RustBlockExpression(
+ List.of(
+ new RustLetStatement(
+ ptr,
+ false,
+ new RustTypeCastExpression(
+ new RustCallExpression(
+ RustTypes.ARC.addSegment(RustPathSegment.of("as_ptr")),
+ List.of(new RustPrefixExpression(RustPrefixOperator.BORROW, value))
+ ),
+ RustTypes.USIZE
+ )
+ ),
+ new RustExpressionStatement(new RustMatchExpression(
+ methodCall(
+ methodCall(
+ RustPath.of(SHARED_VALUES_NAME),
+ RustIdentifier.of("get"),
+ List.of(new RustPrefixExpression(RustPrefixOperator.BORROW, RustPath.of(ptr)))
+ ),
+ RustIdentifier.of("copied"),
+ List.of()
+ ),
+ List.of(
+ new RustMatchArm(
+ new RustTupleStructPattern(RustTypes.SOME, List.of(new RustIdentifierPattern(id))),
+ new RustBlockExpression(
+ List.of(
+ generateEncode(
+ new RustPrefixExpression(RustPrefixOperator.BORROW, RustPath.of(id)),
+ NativeTypes.INT_64
+ )
+ ),
+ Optional.empty()
+ )
+ ),
+ new RustMatchArm(
+ new RustPathPattern(RustTypes.NONE),
+ new RustBlockExpression(
+ List.of(
+ new RustLetStatement(
+ id,
+ false,
+ tryIntoOrInvalidData(
+ methodCall(RustPath.of(SHARED_VALUES_NAME), RustIdentifier.of("len"), List.of())
+ )
+ ),
+ generateEncode(
+ new RustPrefixExpression(RustPrefixOperator.BORROW, RustPath.of(id)),
+ NativeTypes.INT_64
+ ),
+ new RustExpressionStatement(
+ methodCall(
+ RustPath.of(SHARED_VALUES_NAME),
+ RustIdentifier.of("insert"),
+ List.of(RustPath.of(ptr), RustPath.of(id))
+ )
+ ),
+ generateEncode(
+ new RustCallExpression(
+ new RustFieldExpression(value, RustIdentifier.of("as_ref")),
+ List.of()
+ ),
+ type
+ )
+ ),
+ Optional.empty()
+ )
+ )
+ )
+ ))
),
- type
- );
+ Optional.empty()
+ ));
}
private RustExpression generateDecodeShared(Type type) {
- var value = generateDecode(type);
- return new RustCallExpression(
- RustPath.global("std", "sync", "Arc", "new"),
- List.of(value)
+ var id = RustIdentifier.of("id");
+ var decodedValue = RustIdentifier.of("decoded_value");
+
+ return new RustBlockExpression(
+ List.of(
+ new RustLetStatement(
+ id,
+ false,
+ generateDecode(NativeTypes.INT_64)
+ )
+ ),
+ Optional.of(new RustIfExpression(
+ new RustBinaryExpression(
+ RustBinaryOperator.LESS_THAN,
+ RustPath.of(id),
+ tryIntoOrInvalidData(methodCall(
+ RustPath.of(SHARED_VALUES_NAME),
+ RustIdentifier.of("len"),
+ List.of()
+ ))
+ ),
+ new RustBlockExpression(
+ List.of(),
+ Optional.of(
+ methodCall(
+ methodCall(
+ new RustCallExpression(
+ RustTypes.ARC.addSegment(RustPathSegment.of("clone")),
+ List.of(
+ new RustPrefixExpression(RustPrefixOperator.BORROW, new RustIndexExpression(
+ RustPath.of(SHARED_VALUES_NAME),
+ // TODO: use try_into()
+ new RustTypeCastExpression(RustPath.of(id), RustTypes.USIZE)
+ ))
+ )
+ ),
+ RustIdentifier.of("downcast"),
+ List.of()
+ ),
+ // TODO: remove unwrap
+ RustIdentifier.of("unwrap"),
+ List.of()
+ )
+ )
+ ),
+ new RustBlockExpression(
+ List.of(
+ new RustLetStatement(
+ decodedValue,
+ false,
+ new RustCallExpression(
+ RustTypes.ARC.addSegment(RustPathSegment.of("new")),
+ List.of(generateDecode(type))
+ )
+ ),
+ new RustExpressionStatement(methodCall(
+ RustPath.of(SHARED_VALUES_NAME),
+ RustIdentifier.of("push"),
+ List.of(
+ new RustTypeCastExpression(
+ new RustCallExpression(
+ RustTypes.ARC.addSegment(RustPathSegment.of("clone")),
+ List.of(new RustPrefixExpression(
+ RustPrefixOperator.BORROW,
+ RustPath.of(decodedValue)
+ ))
+ ),
+ RustTypes.arc(RustTypes.dyn(RustTypes.ANY, RustTypes.SYNC, RustTypes.SEND))
+ )
+ )
+ ))
+ ),
+ Optional.of(RustPath.of(decodedValue))
+ )
+ ))
);
}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustTypes.java b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustTypes.java
index c3d1cf0..1e43a24 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustTypes.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/output/lang/rust/RustTypes.java
@@ -1,20 +1,52 @@
package org.zwobble.hobgoblin.compiler.output.lang.rust;
import org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustPath;
+import org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustTraitObjectType;
import org.zwobble.hobgoblin.compiler.output.lang.rust.ast.RustType;
+import java.util.Arrays;
import java.util.List;
public class RustTypes {
private RustTypes() {}
+ public static RustType dyn(RustPath... bounds) {
+ return new RustTraitObjectType(Arrays.asList(bounds));
+ }
+
public static RustPath BOOL = RustPath.primitive("bool");
public static RustPath I32 = RustPath.primitive("i32");
public static RustPath I64 = RustPath.primitive("i64");
- public static RustPath STRING = RustPath.global("std", "string", "String");
+ public static RustPath USIZE = RustPath.primitive("usize");
+
+ public static RustPath ANY = RustPath.global("std", "any", "Any");
public static RustPath box(RustType elementType) {
return RustPath.global("std", "boxed", "Box")
.withArgs(List.of(elementType));
}
+
+ public static RustPath hashMap(RustType keyType, RustType valueType) {
+ return RustPath.global("std", "collections", "HashMap")
+ .withArgs(List.of(keyType, valueType));
+ }
+
+ public static RustPath SEND = RustPath.global("std", "marker", "Send");
+ public static RustPath SYNC = RustPath.global("std", "marker", "Sync");
+
+ public static RustPath NONE = RustPath.global("std", "option", "Option", "None");
+ public static RustPath SOME = RustPath.global("std", "option", "Option", "Some");
+
+ public static RustPath STRING = RustPath.global("std", "string", "String");
+
+ public static RustPath ARC = RustPath.global("std", "sync", "Arc");
+
+ public static RustPath arc(RustType innerType) {
+ return ARC.withArgs(List.of(innerType));
+ }
+
+ public static RustPath vec(RustType elementType) {
+ return RustPath.global("std", "vec", "Vec")
+ .withArgs(List.of(elementType));
+ }
}