From de742fbcd6ca9ab017fcf6c89a1c64da299cd7bf Mon Sep 17 00:00:00 2001 From: Hendrik Sollich Date: Wed, 24 Jul 2019 16:36:15 +0200 Subject: [PATCH] Fix emitting hexlike strings without quotes The emitter omitted quotes for strings that start with `0x` those would subsequently be parsed as strings again. This should fix #133. --- saphyr/src/emitter.rs | 1 + saphyr/tests/test_round_trip.rs | 54 +++++++++++++++++++++++++++++---- 2 files changed, 49 insertions(+), 6 deletions(-) diff --git a/saphyr/src/emitter.rs b/saphyr/src/emitter.rs index 09e9f87..872d1c8 100644 --- a/saphyr/src/emitter.rs +++ b/saphyr/src/emitter.rs @@ -336,6 +336,7 @@ fn need_quotes(string: &str) -> bool { ] .contains(&string) || string.starts_with('.') + || string.starts_with("0x") || string.parse::().is_ok() || string.parse::().is_ok() } diff --git a/saphyr/tests/test_round_trip.rs b/saphyr/tests/test_round_trip.rs index bfa9602..dc5e85e 100644 --- a/saphyr/tests/test_round_trip.rs +++ b/saphyr/tests/test_round_trip.rs @@ -2,22 +2,64 @@ extern crate yaml_rust; use yaml_rust::{Yaml, YamlEmitter, YamlLoader}; -fn test_round_trip(original: &Yaml) { - let mut out = String::new(); - YamlEmitter::new(&mut out).dump(original).unwrap(); - let documents = YamlLoader::load_from_str(&out).unwrap(); +fn roundtrip(original: &Yaml) { + let mut emitted = String::new(); + YamlEmitter::new(&mut emitted).dump(original).unwrap(); + + let documents = YamlLoader::load_from_str(&emitted).unwrap(); + println!("emitted {}", emitted); + assert_eq!(documents.len(), 1); assert_eq!(documents[0], *original); } +fn double_roundtrip(original: &str) { + let parsed = YamlLoader::load_from_str(&original).unwrap(); + + let mut serialized = String::new(); + YamlEmitter::new(&mut serialized).dump(&parsed[0]).unwrap(); + + let reparsed = YamlLoader::load_from_str(&serialized).unwrap(); + + assert_eq!(parsed, reparsed); +} + #[test] fn test_escape_character() { let y = Yaml::String("\x1b".to_owned()); - test_round_trip(&y); + roundtrip(&y); } #[test] fn test_colon_in_string() { let y = Yaml::String("x: %".to_owned()); - test_round_trip(&y); + roundtrip(&y); +} + +#[test] +fn test_numberlike_strings() { + let docs = [ + r#"x: "1234""#, r#"x: "01234""#, r#""1234""#, + r#""01234""#, r#"" 01234""#, r#""0x1234""#, + r#"" 0x1234""#, + ]; + + for doc in &docs { + roundtrip(&Yaml::String(doc.to_string())); + double_roundtrip(&doc); + } +} + +/// Example from https://github.com/chyh1990/yaml-rust/issues/133 +#[test] +fn test_issue133() { + + let doc = YamlLoader::load_from_str("\"0x123\"").unwrap().pop().unwrap(); + assert_eq!(doc, Yaml::String("0x123".to_string())); + + let mut out_str = String::new(); + YamlEmitter::new(&mut out_str).dump(&doc).unwrap(); + let doc2 = YamlLoader::load_from_str(&out_str).unwrap().pop().unwrap(); + assert_eq!(doc, doc2); // This failed because the type has changed to a number now + }