diff --git a/lib/oxrdf/src/literal.rs b/lib/oxrdf/src/literal.rs index 438fef9c..25e5043a 100644 --- a/lib/oxrdf/src/literal.rs +++ b/lib/oxrdf/src/literal.rs @@ -620,10 +620,41 @@ pub fn print_quoted_str(string: &str, f: &mut impl Write) -> fmt::Result { f.write_char('"')?; for c in string.chars() { match c { + '\0' => f.write_str("\\u0000"), + '\u{01}' => f.write_str("\\u0001"), + '\u{02}' => f.write_str("\\u0002"), + '\u{03}' => f.write_str("\\u0003"), + '\u{04}' => f.write_str("\\u0004"), + '\u{05}' => f.write_str("\\u0005"), + '\u{06}' => f.write_str("\\u0006"), + '\u{07}' => f.write_str("\\u0007"), + '\u{08}' => f.write_str("\\b"), + '\t' => f.write_str("\\t"), '\n' => f.write_str("\\n"), + '\u{0b}' => f.write_str("\\u000B"), + '\u{0c}' => f.write_str("\\f"), '\r' => f.write_str("\\r"), + '\u{0e}' => f.write_str("\\u000E"), + '\u{0f}' => f.write_str("\\u000F"), + '\u{10}' => f.write_str("\\u0010"), + '\u{11}' => f.write_str("\\u0011"), + '\u{12}' => f.write_str("\\u0012"), + '\u{13}' => f.write_str("\\u0013"), + '\u{14}' => f.write_str("\\u0014"), + '\u{15}' => f.write_str("\\u0015"), + '\u{16}' => f.write_str("\\u0016"), + '\u{17}' => f.write_str("\\u0017"), + '\u{18}' => f.write_str("\\u0018"), + '\u{19}' => f.write_str("\\u0019"), + '\u{1a}' => f.write_str("\\u001A"), + '\u{1b}' => f.write_str("\\u001B"), + '\u{1c}' => f.write_str("\\u001C"), + '\u{1d}' => f.write_str("\\u001D"), + '\u{1e}' => f.write_str("\\u001E"), + '\u{1f}' => f.write_str("\\u001F"), '"' => f.write_str("\\\""), '\\' => f.write_str("\\\\"), + '\u{7f}' => f.write_str("\\u007F"), c => f.write_char(c), }?; } @@ -633,6 +664,7 @@ pub fn print_quoted_str(string: &str, f: &mut impl Write) -> fmt::Result { #[cfg(test)] mod tests { use super::*; + use std::str::FromStr; #[test] fn test_simple_literal_equality() { @@ -663,4 +695,44 @@ mod tests { assert_eq!("NaN", Literal::from(f32::NAN).value()); assert_eq!("NaN", Literal::from(f64::NAN).value()); } + + #[test] + fn test_canoincal_escaping() { + assert_eq!( + Literal::from_str(r#""\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\u0008\u0009\u000a\u000b\u000c\u000d\u000e\u000f""#).unwrap().to_string(), + r###""\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000B\f\r\u000E\u000F""### + ); + assert_eq!( + Literal::from_str(r#""\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f""#).unwrap().to_string(), + r###""\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001A\u001B\u001C\u001D\u001E\u001F""### + ); + assert_eq!( + Literal::from_str(r#""\u0020\u0021\u0022\u0023\u0024\u0025\u0026\u0027\u0028\u0029\u002a\u002b\u002c\u002d\u002e\u002f""#).unwrap().to_string(), + r###"" !\"#$%&'()*+,-./""### + ); + assert_eq!( + Literal::from_str(r#""\u0030\u0031\u0032\u0033\u0034\u0035\u0036\u0037\u0038\u0039\u003a\u003b\u003c\u003d\u003e\u003f""#).unwrap().to_string(), + r###""0123456789:;<=>?""### + ); + assert_eq!( + Literal::from_str(r#""\u0040\u0041\u0042\u0043\u0044\u0045\u0046\u0047\u0048\u0049\u004a\u004b\u004c\u004d\u004e\u004f""#).unwrap().to_string(), + r###""@ABCDEFGHIJKLMNO""### + ); + assert_eq!( + Literal::from_str(r#""\u0050\u0051\u0052\u0053\u0054\u0055\u0056\u0057\u0058\u0059\u005a\u005b\u005c\u005d\u005e\u005f""#).unwrap().to_string(), + r###""PQRSTUVWXYZ[\\]^_""### + ); + assert_eq!( + Literal::from_str(r#""\u0060\u0061\u0062\u0063\u0064\u0065\u0066\u0067\u0068\u0069\u006a\u006b\u006c\u006d\u006e\u006f""#).unwrap().to_string(), + r###""`abcdefghijklmno""### + ); + assert_eq!( + Literal::from_str(r#""\u0070\u0071\u0072\u0073\u0074\u0075\u0076\u0077\u0078\u0079\u007a\u007b\u007c\u007d\u007e\u007f""#).unwrap().to_string(), + r###""pqrstuvwxyz{|}~\u007F""### + ); + assert_eq!( + Literal::from_str(r#""\u0080\u0081\u0082\u0083\u0084\u0085\u0086\u0087\u0088\u0089\u008a\u008b\u008c\u008d\u008e\u008f""#).unwrap().to_string(), + "\"\u{80}\u{81}\u{82}\u{83}\u{84}\u{85}\u{86}\u{87}\u{88}\u{89}\u{8a}\u{8b}\u{8c}\u{8d}\u{8e}\u{8f}\"" + ); + } }