diff --git a/haskell/compiler/adlc-lib1/ADL/Compiler/Backends/Rust.hs b/haskell/compiler/adlc-lib1/ADL/Compiler/Backends/Rust.hs index f2966b8a..c827e390 100644 --- a/haskell/compiler/adlc-lib1/ADL/Compiler/Backends/Rust.hs +++ b/haskell/compiler/adlc-lib1/ADL/Compiler/Backends/Rust.hs @@ -243,14 +243,44 @@ genNewType m decl Newtype{n_typeParams=typeParams, n_typeExpr=te} = do phantomFields <- mapM phantomData phantomTypeParams rustUse (rustScopedName "serde::Serialize") rustUse (rustScopedName "serde::Deserialize") + rustUse (rustScopedName "serde::Serializer") + rustUse (rustScopedName "serde::Deserializer") + addDeclaration $ renderCommentForDeclaration decl <> render typeName typeParams typeExprStr phantomFields where render :: T.Text -> [Ident] -> T.Text -> [T.Text] -> Code render name typeParams typeExprStr phantomFields - = ctemplate "#[derive($1)]" [T.intercalate "," (S.toList (stdTraitsFor te))] + = ctemplate "#[derive($1)]" [T.intercalate "," (S.toList traits)] <> ctemplate "pub struct $1$2($3);" [name, typeParamsExpr typeParams, T.intercalate ", " (["pub " <> typeExprStr] <> (map ("pub " <>) phantomFields))] + <> cline "" + <> ctemplate "impl$2 Serialize for $1$2" [name, typeParamsExpr typeParams] + <> (if null (typeExprTypeParams te) then mempty else ctemplate " where $1: Serialize" [typeExprStr]) + <> cline "{" + <> cline " fn serialize(&self, serializer: S) -> Result" + <> cline " where" + <> cline " S: Serializer," + <> cline " {" + <> cline " self.0.serialize(serializer)" + <> cline " }" + <> cline "}" + <> cline "" + <> ctemplate "impl$1 Deserialize<'de> for $2$3" [typeParamsExpr (["'de"] <>typeParams), name, typeParamsExpr typeParams] + <> (if null (typeExprTypeParams te) then mempty else ctemplate " where $1: Deserialize<'de>" [typeExprStr]) + <> cline "{" + <> ctemplate " fn deserialize(deserializer: D) -> Result<$1$2, D::Error>" [name, typeParamsExpr typeParams] + <> cline " where" + <> cline " D: Deserializer<'de>," + <> cline " {" + <> ctemplate " let v = $1::deserialize(deserializer)?;" [turboize typeExprStr] + <> ctemplate " Ok($1($2))" [name, T.intercalate ", " (["v"] <> map (\_ -> "PhantomData") phantomFields)] + <> cline " }" + <> cline "}" + realTypeParams = S.toList (S.difference (S.fromList typeParams) (typeExprTypeParams te)) phantomTypeParams = S.toList (S.difference (S.fromList typeParams) (typeExprTypeParams te)) + traits = S.difference (stdTraitsFor te) (S.fromList ["Serialize", "Deserialize"]) + turboize s = let (a,b) = T.breakOn "<" s in if T.null b then a else (a <> "::" <> b) -- hack + serdeRenameAttribute :: FieldDetails -> Ident -> Code diff --git a/haskell/compiler/tests/test14/rs-output/test14/adl/test14.rs b/haskell/compiler/tests/test14/rs-output/test14/adl/test14.rs index c39c36ee..74f22d5b 100644 --- a/haskell/compiler/tests/test14/rs-output/test14/adl/test14.rs +++ b/haskell/compiler/tests/test14/rs-output/test14/adl/test14.rs @@ -1,7 +1,9 @@ // @generated from adl module test14 use serde::Deserialize; +use serde::Deserializer; use serde::Serialize; +use serde::Serializer; #[derive(Clone,Deserialize,PartialEq,Serialize)] pub struct Switch { @@ -36,5 +38,26 @@ pub enum Unsigned { Null, } -#[derive(Clone,Deserialize,Eq,Hash,PartialEq,Serialize)] +#[derive(Clone,Eq,Hash,PartialEq)] pub struct Factory(pub String); + +impl Serialize for Factory +{ + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + self.0.serialize(serializer) + } +} + +impl<'de> Deserialize<'de> for Factory +{ + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let v = String::deserialize(deserializer)?; + Ok(Factory(v)) + } +} diff --git a/haskell/compiler/tests/test7/rs-output/test7/adl/test7.rs b/haskell/compiler/tests/test7/rs-output/test7/adl/test7.rs index dc28eaeb..412ef837 100644 --- a/haskell/compiler/tests/test7/rs-output/test7/adl/test7.rs +++ b/haskell/compiler/tests/test7/rs-output/test7/adl/test7.rs @@ -1,7 +1,9 @@ // @generated from adl module test7 use serde::Deserialize; +use serde::Deserializer; use serde::Serialize; +use serde::Serializer; use std::marker::PhantomData; #[derive(Clone,Deserialize,Eq,Hash,PartialEq,Serialize)] @@ -22,49 +24,282 @@ impl Point { pub type Int1 = i64; -#[derive(Clone,Deserialize,Eq,Hash,PartialEq,Serialize)] +#[derive(Clone,Eq,Hash,PartialEq)] pub struct Int2(pub i64); -#[derive(Clone,Deserialize,Eq,Hash,PartialEq,Serialize)] +impl Serialize for Int2 +{ + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + self.0.serialize(serializer) + } +} + +impl<'de> Deserialize<'de> for Int2 +{ + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let v = i64::deserialize(deserializer)?; + Ok(Int2(v)) + } +} + +#[derive(Clone,Eq,Hash,PartialEq)] pub struct Int3(pub i64); +impl Serialize for Int3 +{ + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + self.0.serialize(serializer) + } +} + +impl<'de> Deserialize<'de> for Int3 +{ + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let v = i64::deserialize(deserializer)?; + Ok(Int3(v)) + } +} + pub type Int4 = i64; -#[derive(Clone,Deserialize,Eq,Hash,PartialEq,Serialize)] +#[derive(Clone,Eq,Hash,PartialEq)] pub struct Int5(pub i64, pub PhantomData); -#[derive(Clone,Deserialize,Eq,Hash,PartialEq,Serialize)] +impl Serialize for Int5 +{ + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + self.0.serialize(serializer) + } +} + +impl<'de, X> Deserialize<'de> for Int5 +{ + fn deserialize(deserializer: D) -> Result, D::Error> + where + D: Deserializer<'de>, + { + let v = i64::deserialize(deserializer)?; + Ok(Int5(v, PhantomData)) + } +} + +#[derive(Clone,Eq,Hash,PartialEq)] pub struct Int6(pub i64, pub PhantomData); +impl Serialize for Int6 +{ + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + self.0.serialize(serializer) + } +} + +impl<'de, X> Deserialize<'de> for Int6 +{ + fn deserialize(deserializer: D) -> Result, D::Error> + where + D: Deserializer<'de>, + { + let v = i64::deserialize(deserializer)?; + Ok(Int6(v, PhantomData)) + } +} + pub type String1 = String; -#[derive(Clone,Deserialize,Eq,Hash,PartialEq,Serialize)] +#[derive(Clone,Eq,Hash,PartialEq)] pub struct String2(pub String); -#[derive(Clone,Deserialize,Eq,Hash,PartialEq,Serialize)] +impl Serialize for String2 +{ + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + self.0.serialize(serializer) + } +} + +impl<'de> Deserialize<'de> for String2 +{ + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let v = String::deserialize(deserializer)?; + Ok(String2(v)) + } +} + +#[derive(Clone,Eq,Hash,PartialEq)] pub struct String3(pub String); +impl Serialize for String3 +{ + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + self.0.serialize(serializer) + } +} + +impl<'de> Deserialize<'de> for String3 +{ + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let v = String::deserialize(deserializer)?; + Ok(String3(v)) + } +} + pub type String4 = String; -#[derive(Clone,Deserialize,Eq,Hash,PartialEq,Serialize)] +#[derive(Clone,Eq,Hash,PartialEq)] pub struct String5(pub String, pub PhantomData); -#[derive(Clone,Deserialize,Eq,Hash,PartialEq,Serialize)] +impl Serialize for String5 +{ + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + self.0.serialize(serializer) + } +} + +impl<'de, X> Deserialize<'de> for String5 +{ + fn deserialize(deserializer: D) -> Result, D::Error> + where + D: Deserializer<'de>, + { + let v = String::deserialize(deserializer)?; + Ok(String5(v, PhantomData)) + } +} + +#[derive(Clone,Eq,Hash,PartialEq)] pub struct String6(pub String, pub PhantomData); +impl Serialize for String6 +{ + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + self.0.serialize(serializer) + } +} + +impl<'de, X> Deserialize<'de> for String6 +{ + fn deserialize(deserializer: D) -> Result, D::Error> + where + D: Deserializer<'de>, + { + let v = String::deserialize(deserializer)?; + Ok(String6(v, PhantomData)) + } +} + pub type IntPoint1 = Point; -#[derive(Clone,Deserialize,Eq,Hash,PartialEq,Serialize)] +#[derive(Clone,Eq,Hash,PartialEq)] pub struct IntPoint2(pub Point); -#[derive(Clone,Deserialize,Eq,Hash,PartialEq,Serialize)] +impl Serialize for IntPoint2 +{ + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + self.0.serialize(serializer) + } +} + +impl<'de> Deserialize<'de> for IntPoint2 +{ + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let v = Point::::deserialize(deserializer)?; + Ok(IntPoint2(v)) + } +} + +#[derive(Clone,Eq,Hash,PartialEq)] pub struct IntPoint3(pub Point); +impl Serialize for IntPoint3 +{ + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + self.0.serialize(serializer) + } +} + +impl<'de> Deserialize<'de> for IntPoint3 +{ + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let v = Point::::deserialize(deserializer)?; + Ok(IntPoint3(v)) + } +} + pub type Point1 = Point; -#[derive(Clone,Deserialize,Eq,Hash,PartialEq,Serialize)] +#[derive(Clone,Eq,Hash,PartialEq)] pub struct Point2(pub Point); +impl Serialize for Point2 + where Point: Serialize +{ + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + self.0.serialize(serializer) + } +} + +impl<'de, X> Deserialize<'de> for Point2 + where Point: Deserialize<'de> +{ + fn deserialize(deserializer: D) -> Result, D::Error> + where + D: Deserializer<'de>, + { + let v = Point::::deserialize(deserializer)?; + Ok(Point2(v)) + } +} + pub type IntPoint1A = IntPoint1; #[derive(Clone,Deserialize,Eq,Hash,PartialEq,Serialize)]