diff options
-rw-r--r-- | src/tokens.rs | 19 | ||||
-rw-r--r-- | src/value.rs | 63 | ||||
-rw-r--r-- | test-suite/tests/invalid/string-bad-line-ending-escape.toml | 3 | ||||
-rw-r--r-- | test-suite/tests/serde.rs | 60 | ||||
-rw-r--r-- | test-suite/tests/valid/multiline-string.json | 8 | ||||
-rw-r--r-- | test-suite/tests/valid/multiline-string.toml | 11 |
6 files changed, 148 insertions, 16 deletions
diff --git a/src/tokens.rs b/src/tokens.rs index 15c3b41..382c1ec 100644 --- a/src/tokens.rs +++ b/src/tokens.rs @@ -364,7 +364,24 @@ impl<'a> Tokenizer<'a> { let len = if c == 'u' {4} else {8}; val.push(me.hex(start, i, len)?); } - Some((_, '\n')) if multi => { + Some((i, c @ ' ')) | + Some((i, c @ '\t')) | + Some((i, c @ '\n')) if multi => { + if c != '\n' { + while let Some((_, ch)) = me.chars.clone().next() { + match ch { + ' ' | '\t' => { + me.chars.next(); + continue + }, + '\n' => { + me.chars.next(); + break + }, + _ => return Err(Error::InvalidEscape(i, c)), + } + } + } while let Some((_, ch)) = me.chars.clone().next() { match ch { ' ' | '\t' | '\n' => { diff --git a/src/value.rs b/src/value.rs index 64f4555..2e42dc3 100644 --- a/src/value.rs +++ b/src/value.rs @@ -675,9 +675,9 @@ impl ser::Serializer for Serializer { type Error = ::ser::Error; type SerializeSeq = SerializeVec; - type SerializeTuple = ser::Impossible<Value, ::ser::Error>; - type SerializeTupleStruct = ser::Impossible<Value, ::ser::Error>; - type SerializeTupleVariant = ser::Impossible<Value, ::ser::Error>; + type SerializeTuple = SerializeVec; + type SerializeTupleStruct = SerializeVec; + type SerializeTupleVariant = SerializeVec; type SerializeMap = SerializeMap; type SerializeStruct = SerializeMap; type SerializeStructVariant = ser::Impossible<Value, ::ser::Error>; @@ -800,23 +800,23 @@ impl ser::Serializer for Serializer { }) } - fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, ::ser::Error> { - Err(::ser::Error::UnsupportedType) + fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, ::ser::Error> { + self.serialize_seq(Some(len)) } - fn serialize_tuple_struct(self, _name: &'static str, _len: usize) + fn serialize_tuple_struct(self, _name: &'static str, len: usize) -> Result<Self::SerializeTupleStruct, ::ser::Error> { - Err(::ser::Error::UnsupportedType) + self.serialize_seq(Some(len)) } fn serialize_tuple_variant(self, _name: &'static str, _variant_index: u32, _variant: &'static str, - _len: usize) + len: usize) -> Result<Self::SerializeTupleVariant, ::ser::Error> { - Err(::ser::Error::UnsupportedType) + self.serialize_seq(Some(len)) } fn serialize_map(self, _len: Option<usize>) @@ -869,6 +869,51 @@ impl ser::SerializeSeq for SerializeVec { } } +impl ser::SerializeTuple for SerializeVec { + type Ok = Value; + type Error = ::ser::Error; + + fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), ::ser::Error> + where T: ser::Serialize + { + ser::SerializeSeq::serialize_element(self, value) + } + + fn end(self) -> Result<Value, ::ser::Error> { + ser::SerializeSeq::end(self) + } +} + +impl ser::SerializeTupleStruct for SerializeVec { + type Ok = Value; + type Error = ::ser::Error; + + fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), ::ser::Error> + where T: ser::Serialize + { + ser::SerializeSeq::serialize_element(self, value) + } + + fn end(self) -> Result<Value, ::ser::Error> { + ser::SerializeSeq::end(self) + } +} + +impl ser::SerializeTupleVariant for SerializeVec { + type Ok = Value; + type Error = ::ser::Error; + + fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), ::ser::Error> + where T: ser::Serialize + { + ser::SerializeSeq::serialize_element(self, value) + } + + fn end(self) -> Result<Value, ::ser::Error> { + ser::SerializeSeq::end(self) + } +} + impl ser::SerializeMap for SerializeMap { type Ok = Value; type Error = ::ser::Error; diff --git a/test-suite/tests/invalid/string-bad-line-ending-escape.toml b/test-suite/tests/invalid/string-bad-line-ending-escape.toml new file mode 100644 index 0000000..32e2c48 --- /dev/null +++ b/test-suite/tests/invalid/string-bad-line-ending-escape.toml @@ -0,0 +1,3 @@ +invalid-escape = """\ + This string has a non whitespace-character after the line ending escape. \ a +""" diff --git a/test-suite/tests/serde.rs b/test-suite/tests/serde.rs index b97937f..c1b6d78 100644 --- a/test-suite/tests/serde.rs +++ b/test-suite/tests/serde.rs @@ -580,15 +580,63 @@ fn table_structs_empty() { #[test] fn fixed_size_array() { - #[derive(Serialize, PartialEq, Eq, Deserialize, Debug)] + #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] struct Entity { pos: [i32; 2] } - let text = "pos = [1, 2]\n"; - let value: Entity = toml::from_str(text).unwrap(); - let expected = Entity { pos: [1, 2] }; - assert_eq!(value, expected); - assert_eq!(toml::to_string(&value).unwrap(), text); + + equivalent! { + Entity { pos: [1, 2] }, + Table(map! { + pos: Array(vec![ + Integer(1), + Integer(2), + ]) + }), + } +} + +#[test] +fn homogeneous_tuple() { + #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] + struct Collection { + elems: (i64, i64, i64), + } + + equivalent! { + Collection { elems: (0, 1, 2) }, + Table(map! { + elems: Array(vec![ + Integer(0), + Integer(1), + Integer(2), + ]) + }), + } +} + +#[test] +fn homogeneous_tuple_struct() { + #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)] + struct Object(Vec<String>, Vec<String>, Vec<String>); + + equivalent! { + map! { + obj: Object(vec!["foo".to_string()], vec![], vec!["bar".to_string(), "baz".to_string()]) + }, + Table(map! { + obj: Array(vec![ + Array(vec![ + Value::String("foo".to_string()), + ]), + Array(vec![]), + Array(vec![ + Value::String("bar".to_string()), + Value::String("baz".to_string()), + ]), + ]) + }), + } } #[test] diff --git a/test-suite/tests/valid/multiline-string.json b/test-suite/tests/valid/multiline-string.json index 075bf50..3223bae 100644 --- a/test-suite/tests/valid/multiline-string.json +++ b/test-suite/tests/valid/multiline-string.json @@ -15,6 +15,10 @@ "type": "string", "value": "" }, + "multiline_empty_five": { + "type": "string", + "value": "" + }, "equivalent_one": { "type": "string", "value": "The quick brown fox jumps over the lazy dog." @@ -26,5 +30,9 @@ "equivalent_three": { "type": "string", "value": "The quick brown fox jumps over the lazy dog." + }, + "equivalent_four": { + "type": "string", + "value": "The quick brown fox jumps over the lazy dog." } } diff --git a/test-suite/tests/valid/multiline-string.toml b/test-suite/tests/valid/multiline-string.toml index 15b1143..2c4237f 100644 --- a/test-suite/tests/valid/multiline-string.toml +++ b/test-suite/tests/valid/multiline-string.toml @@ -7,6 +7,11 @@ multiline_empty_four = """\ \ \ """ +multiline_empty_five = """\ + \ + \ + \ + """ equivalent_one = "The quick brown fox jumps over the lazy dog." equivalent_two = """ @@ -21,3 +26,9 @@ equivalent_three = """\ fox jumps over \ the lazy dog.\ """ + +equivalent_four = """\ + The quick brown \ + fox jumps over \ + the lazy dog.\ + """ |