git.delta.rocks / jrsonnet / refs/commits / 17973b574124

difftreelog

feat(parser) correct strings support

Лач2020-06-08parent: #432b172.patch.diff
in: master

2 files changed

modifiedcrates/jsonnet-parser/Cargo.tomldiffbeforeafterboth
--- a/crates/jsonnet-parser/Cargo.toml
+++ b/crates/jsonnet-parser/Cargo.toml
@@ -14,6 +14,7 @@
 [dependencies]
 peg = "0.6.2"
 serde = { version = "1.0.111", features = ["derive", "rc"] }
+unescape = "0.1.0"
 
 [dev-dependencies]
 jsonnet-stdlib = { version = "0.1.0", path = "../jsonnet-stdlib" }
modifiedcrates/jsonnet-parser/src/lib.rsdiffbeforeafterboth
23 /// Standard C-like comments23 /// Standard C-like comments
24 rule comment()24 rule comment()
25 = "//" (!['\n'][_])* "\n"25 = "//" (!['\n'][_])* "\n"
26 / "/*" ((!("*/")[_][_])/("\\" "*/"))* "*/"26 / "/*" (!("*/")[_])* "*/"
27 / "#" (!['\n'][_])* "\n"27 / "#" (!['\n'][_])* "\n"
2828
29 rule _() = ([' ' | '\n' | '\t'] / comment())*29 rule single_whitespace() = quiet!{([' ' | '\r' | '\n' | '\t'] / comment())} / expected!("<whitespace>")
30 rule _() = single_whitespace()*
3031
31 /// For comma-delimited elements32 /// For comma-delimited elements
32 rule comma() = quiet!{_ "," _} / expected!("<comma>")33 rule comma() = quiet!{_ "," _} / expected!("<comma>")
83 pub rule whole_line() -> String84 pub rule whole_line() -> String
84 = str:$((!['\n'][_])* "\n") {str.to_owned()}85 = str:$((!['\n'][_])* "\n") {str.to_owned()}
85 pub rule string() -> String86 pub rule string() -> String
86 = "\"" str:$(("\\\"" / !['"'][_])*) "\"" {str.to_owned()}87 = "\"" str:$(("\\\"" / "\\\\" / (!['"'][_]))*) "\"" {unescape::unescape(str).unwrap()}
87 / "'" str:$((!['\''][_])*) "'" {str.to_owned()}88 / "'" str:$(("\\'" / "\\\\" / (!['\''][_]))*) "'" {unescape::unescape(str).unwrap()}
89 / "@'" str:$(("''" / (!['\''][_]))*) "'" {str.replace("''", "'")}
90 / "@\"" str:$(("\"\"" / (!['"'][_]))*) "\"" {str.replace("\"\"", "\"")}
88 // TODO: This is temporary workaround, i still dont know how to write this correctly btw.91 // TODO: This is temporary workaround, i still dont know how to write this correctly btw.
89 / "|||" "\n" str:$((" "*<1, 1> whole_line())+) " "*<0, 0> "|||" {deent(str)}92 / "|||" (!['\n']single_whitespace())+ "\n" str:$((" "*<1, 1> whole_line())+) " "*<0, 0> "|||" {deent(str)}
90 / "|||" "\n" str:$((" "*<2, 2> whole_line())+) " "*<1, 1> "|||" {deent(str)}93 / "|||" (!['\n']single_whitespace())+ "\n" str:$((" "*<2, 2> whole_line())+) " "*<1, 1> "|||" {deent(str)}
91 / "|||" "\n" str:$((" "*<3, 3> whole_line())+) " "*<2, 2> "|||" {deent(str)}94 / "|||" (!['\n']single_whitespace())+ "\n" str:$((" "*<3, 3> whole_line())+) " "*<2, 2> "|||" {deent(str)}
92 / "|||" "\n" str:$((" "*<4, 4> whole_line())+) " "*<3, 3> "|||" {deent(str)}95 / "|||" (!['\n']single_whitespace())+ "\n" str:$((" "*<4, 4> whole_line())+) " "*<3, 3> "|||" {deent(str)}
93 / "|||" "\n" str:$((" "*<5, 5> whole_line())+) " "*<4, 4> "|||" {deent(str)}96 / "|||" (!['\n']single_whitespace())+ "\n" str:$((" "*<5, 5> whole_line())+) " "*<4, 4> "|||" {deent(str)}
94 / "|||" "\n" str:$((" "*<6, 6> whole_line())+) " "*<5, 5> "|||" {deent(str)}97 / "|||" (!['\n']single_whitespace())+ "\n" str:$((" "*<6, 6> whole_line())+) " "*<5, 5> "|||" {deent(str)}
95 / "|||" "\n" str:$((" "*<7, 7> whole_line())+) " "*<6, 6> "|||" {deent(str)}98 / "|||" (!['\n']single_whitespace())+ "\n" str:$((" "*<7, 7> whole_line())+) " "*<6, 6> "|||" {deent(str)}
96 / "|||" "\n" str:$((" "*<8, 8> whole_line())+) " "*<7, 7> "|||" {deent(str)}99 / "|||" (!['\n']single_whitespace())+ "\n" str:$((" "*<8, 8> whole_line())+) " "*<7, 7> "|||" {deent(str)}
97 / "|||" "\n" str:$((" "*<9, 9> whole_line())+) " "*<8, 8> "|||" {deent(str)}100 / "|||" (!['\n']single_whitespace())+ "\n" str:$((" "*<9, 9> whole_line())+) " "*<8, 8> "|||" {deent(str)}
98 / "|||" "\n" str:$((" "*<10, 10> whole_line())+) " "*<9, 9> "|||" {deent(str)}101 / "|||" (!['\n']single_whitespace())+ "\n" str:$((" "*<10, 10> whole_line())+) " "*<9, 9> "|||" {deent(str)}
99 / "|||" "\n" str:$((" "*<11, 11> whole_line())+) " "*<10, 10> "|||" {deent(str)}102 / "|||" (!['\n']single_whitespace())+ "\n" str:$((" "*<11, 11> whole_line())+) " "*<10, 10> "|||" {deent(str)}
100 / "|||" "\n" str:$((" "*<12, 12> whole_line())+) " "*<11, 10> "|||" {deent(str)}103 / "|||" (!['\n']single_whitespace())+ "\n" str:$((" "*<12, 12> whole_line())+) " "*<11, 10> "|||" {deent(str)}
101104
102 pub rule field_name(s: &ParserSettings) -> expr::FieldName105 pub rule field_name(s: &ParserSettings) -> expr::FieldName
103 = name:id() {expr::FieldName::Fixed(name)}106 = name:id() {expr::FieldName::Fixed(name)}
334 )337 )
335 }338 }
339
340 #[test]
341 fn string_escaping() {
342 assert_eq!(
343 parse!(r#""Hello, \"world\"!""#),
344 el!(Expr::Str(r#"Hello, "world"!"#.to_owned())),
345 );
346 assert_eq!(
347 parse!(r#"'Hello \'world\'!'"#),
348 el!(Expr::Str("Hello 'world'!".to_owned())),
349 );
350 assert_eq!(parse!(r#"'\\\\'"#), el!(Expr::Str("\\\\".to_owned())),);
351 }
352
353 #[test]
354 fn string_unescaping() {
355 assert_eq!(
356 parse!(r#""Hello\nWorld""#),
357 el!(Expr::Str("Hello\nWorld".to_owned())),
358 );
359 }
360
361 #[test]
362 fn string_verbantim() {
363 assert_eq!(
364 parse!(r#"@"Hello\n""World""""#),
365 el!(Expr::Str("Hello\\n\"World\"".to_owned())),
366 );
367 }
336368
337 #[test]369 #[test]
338 fn empty_object() {370 fn empty_object() {