diff --git a/Cargo.toml b/Cargo.toml index 2298d5a..e0ffb13 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,8 +1,8 @@ [package] name = "uneval" -version = "0.2.2" +version = "0.2.3" authors = ["Cerber Ursi "] -edition = "2018" +edition = "2021" description = "Serde serializer to embed data as Rust code" license = "MIT" readme = "README.md" diff --git a/README.md b/README.md index 1606824..295b4b2 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,6 @@ or the similar construction using [`lazy_static`](http://crates.io/crates/lazy_s 3. Deserializer isn't implemented. This is intentional, since this crate isn't really intended for runtime usage. Well, in fact, the deserializer *is* implemented - it's just the Rust compiler itself. 4. This serializer is intended for use with derived implementation. It may return bogus results when used with customized `Serialize`. 5. It is impossible to serialize the struct with private fields outside from the module it is defined in. In fact, to be able to serialize this type at all, you'll have to distribute two copies of your crate, one of which would only export the definition with derived `Serialize` to be used by this crate during the build-time of the second copy. (Isn't this a bit too complex?) -6. It is impossible to use empty tuple structs (i.e. `Empty()`). From the Serde's point of view, they are indistinguishable from unit structs (i.e. `Unit`), but the same Rust syntax can't be used for both, and, since ordinary unit structs are much more common, it was decided to abandon the empty tuples. If you find any other case where this doesn't work, feel free to open an issue - we'll either fix the code or document the newly-found limitation. diff --git a/src/lib.rs b/src/lib.rs index deac393..a2b868c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -233,10 +233,6 @@ //! In fact, to be able to use this type with `uneval`, you'll have to distribute two copies of your crate, //! one of which would only export the definition with derived `Serialize` to be used by serializer //! during the build-time of the second copy. (Isn't this a bit too complex?) -//! 4. It is impossible to use empty tuple structs (i.e. `Empty()`). -//! From the Serde's point of view, they are indistinguishable from unit structs (i.e. `Unit`), -//! but the same Rust syntax can't be used for both, and, since ordinary unit structs are much -//! more common, it was decided to correctly handle them. //! //! [include]: https://doc.rust-lang.org/stable/std/macro.include.html diff --git a/src/ser.rs b/src/ser.rs index 0facc8e..d12be69 100644 --- a/src/ser.rs +++ b/src/ser.rs @@ -16,7 +16,7 @@ pub struct Uneval { } impl Uneval { - pub(crate) fn new(target: W) -> Self { + pub fn new(target: W) -> Self { Self { writer: target, inside: false, @@ -267,6 +267,7 @@ impl ser::SerializeSeq for &mut Uneval { fn end(self) -> SerResult { write!(self.writer, "].into_iter().collect()")?; + self.inside = true; Ok(()) } } @@ -283,6 +284,7 @@ impl ser::SerializeTuple for &mut Uneval { fn end(self) -> SerResult { write!(self.writer, ")) }}")?; + self.inside = true; Ok(()) } } @@ -299,6 +301,7 @@ impl ser::SerializeTupleStruct for &mut Uneval { fn end(self) -> SerResult { write!(self.writer, ")")?; + self.inside = true; Ok(()) } } @@ -315,6 +318,7 @@ impl ser::SerializeTupleVariant for &mut Uneval { fn end(self) -> SerResult { write!(self.writer, ")")?; + self.inside = true; Ok(()) } } @@ -344,6 +348,7 @@ impl ser::SerializeMap for &mut Uneval { fn end(self) -> SerResult { write!(self.writer, "].into_iter().collect()")?; + self.inside = true; Ok(()) } } @@ -368,6 +373,7 @@ impl ser::SerializeStruct for &mut Uneval { fn end(self) -> SerResult { self.comma()?; write!(self.writer, "}}")?; + self.inside = true; Ok(()) } } @@ -391,6 +397,7 @@ impl ser::SerializeStructVariant for &mut Uneval { fn end(self) -> SerResult { write!(self.writer, "}}")?; + self.inside = true; Ok(()) } } diff --git a/test_fixtures/data.toml b/test_fixtures/data.toml index 93de5aa..454f27b 100644 --- a/test_fixtures/data.toml +++ b/test_fixtures/data.toml @@ -93,6 +93,8 @@ pub enum Enum { Unit(Unit), Tuple(i32, String), Struct{ key: i32, value: String }, + EmptyTuple(), + EmptyStruct {}, } #[derive(PartialEq, Debug, Serialize)] @@ -102,10 +104,13 @@ value = """ { use definition::*; Container(vec![ - Enum::Empty, Enum::Unit(Unit), Enum::Tuple(1, "test".into()), Enum::Struct{ key: 1, value: "test".into() }, + Enum::EmptyTuple(), + Enum::EmptyStruct{}, + // this is intentionally last, to catch an error at previous step + Enum::Empty, ]) } """ @@ -128,4 +133,41 @@ pub struct ZeroSizeContainer(pub [u8; 0]); """ value = """ definition::ZeroSizeContainer([]) -""" \ No newline at end of file +""" + +[empty_fields_issue_3] +main_type = "Foo" +support_types = "UnitType,UnitStruct,UnitTuple" +definition = """ +use std::collections::HashMap; +#[derive(PartialEq, Debug, Serialize)] +pub struct UnitType; +#[derive(PartialEq, Debug, Serialize)] +pub struct UnitStruct {} +#[derive(PartialEq, Debug, Serialize)] +pub struct UnitTuple(); +#[derive(PartialEq, Debug, Serialize)] +pub struct Foo { + pub vec: Vec, + pub map: HashMap, + pub unit: (), + pub unit_type: UnitType, + pub unit_struct: UnitStruct, + pub unit_tuple: UnitTuple, + pub last: String +} +""" +value = """ +{ + use definition::*; + Foo { + vec: vec![], + map: std::collections::HashMap::new(), + unit: (), + unit_type: UnitType, + unit_struct: UnitStruct {}, + unit_tuple: UnitTuple(), + last: "".into() + } +} +"""