difftreelog
fix correct string block parsing
in: master
2 files changed
crates/jsonnet-parser/src/lib.rsdiffbeforeafterboth6use peg::parser;6use peg::parser;7use std::{path::PathBuf, rc::Rc};7use std::{path::PathBuf, rc::Rc};8mod expr;8mod expr;9mod string_processing;10pub use expr::*;9pub use expr::*;11pub use peg;10pub use peg;12use string_processing::deent;131114pub struct ParserSettings {12pub struct ParserSettings {15 pub loc_data: bool,13 pub loc_data: bool,81 pub rule assertion(s: &ParserSettings) -> expr::AssertStmt79 pub rule assertion(s: &ParserSettings) -> expr::AssertStmt82 = keyword("assert") _ cond:expr(s) msg:(_ ":" _ e:expr(s) {e})? { expr::AssertStmt(cond, msg) }80 = keyword("assert") _ cond:expr(s) msg:(_ ":" _ e:expr(s) {e})? { expr::AssertStmt(cond, msg) }838184 pub rule whole_line() -> String82 pub rule whole_line() -> &'input str85 = str:$((!['\n'][_])* "\n") {str.to_owned()}83 = str:$((!['\n'][_])* "\n") {str}84 pub rule string_block() -> String85 = "|||" (!['\n']single_whitespace())* "\n"86 prefix:[' ']+ first_line:whole_line()87 lines:([' ']*<{prefix.len()}> s:whole_line() {s})*88 [' ']*<, {prefix.len() - 1}> "|||"89 {let mut l = first_line.to_owned(); l.extend(lines); l}86 pub rule string() -> String90 pub rule string() -> String87 = "\"" str:$(("\\\"" / "\\\\" / (!['"'][_]))*) "\"" {unescape::unescape(str).unwrap()}91 = "\"" str:$(("\\\"" / "\\\\" / (!['"'][_]))*) "\"" {unescape::unescape(str).unwrap()}88 / "'" str:$(("\\'" / "\\\\" / (!['\''][_]))*) "'" {unescape::unescape(str).unwrap()}92 / "'" str:$(("\\'" / "\\\\" / (!['\''][_]))*) "'" {unescape::unescape(str).unwrap()}89 / "@'" str:$(("''" / (!['\''][_]))*) "'" {str.replace("''", "'")}93 / "@'" str:$(("''" / (!['\''][_]))*) "'" {str.replace("''", "'")}90 / "@\"" str:$(("\"\"" / (!['"'][_]))*) "\"" {str.replace("\"\"", "\"")}94 / "@\"" str:$(("\"\"" / (!['"'][_]))*) "\"" {str.replace("\"\"", "\"")}91 // TODO: This is temporary workaround, i still dont know how to write this correctly btw.92 / "|||" (!['\n']single_whitespace())* "\n" str:$((" "*<1, 1> whole_line())+) " "*<0, 0> "|||" {deent(str)}95 / string_block()93 / "|||" (!['\n']single_whitespace())* "\n" str:$((" "*<2, 2> whole_line())+) " "*<1, 1> "|||" {deent(str)}94 / "|||" (!['\n']single_whitespace())* "\n" str:$((" "*<3, 3> whole_line())+) " "*<2, 2> "|||" {deent(str)}95 / "|||" (!['\n']single_whitespace())* "\n" str:$((" "*<4, 4> whole_line())+) " "*<3, 3> "|||" {deent(str)}96 / "|||" (!['\n']single_whitespace())* "\n" str:$((" "*<5, 5> whole_line())+) " "*<4, 4> "|||" {deent(str)}97 / "|||" (!['\n']single_whitespace())* "\n" str:$((" "*<6, 6> whole_line())+) " "*<5, 5> "|||" {deent(str)}98 / "|||" (!['\n']single_whitespace())* "\n" str:$((" "*<7, 7> whole_line())+) " "*<6, 6> "|||" {deent(str)}99 / "|||" (!['\n']single_whitespace())* "\n" str:$((" "*<8, 8> whole_line())+) " "*<7, 7> "|||" {deent(str)}100 / "|||" (!['\n']single_whitespace())* "\n" str:$((" "*<9, 9> whole_line())+) " "*<8, 8> "|||" {deent(str)}101 / "|||" (!['\n']single_whitespace())* "\n" str:$((" "*<10, 10> whole_line())+) " "*<9, 9> "|||" {deent(str)}102 / "|||" (!['\n']single_whitespace())* "\n" str:$((" "*<11, 11> whole_line())+) " "*<10, 10> "|||" {deent(str)}103 / "|||" (!['\n']single_whitespace())* "\n" str:$((" "*<12, 12> whole_line())+) " "*<11, 10> "|||" {deent(str)}10496105 pub rule field_name(s: &ParserSettings) -> expr::FieldName97 pub rule field_name(s: &ParserSettings) -> expr::FieldName106 = name:id() {expr::FieldName::Fixed(name)}98 = name:id() {expr::FieldName::Fixed(name)}342 #[test]334 #[test]343 fn multiline_string() {335 fn multiline_string() {344 assert_eq!(336 assert_eq!(345 parse!("|||\n Hello world!\n a\n|||"),337 parse!("|||\n Hello world!\n a\n|||"),346 el!(Expr::Str(" Hello world!\na\n".to_owned())),338 el!(Expr::Str("Hello world!\n a\n".to_owned())),347 )339 )348 }340 }349341crates/jsonnet-parser/src/string_processing.rsdiffbeforeafterboth--- a/crates/jsonnet-parser/src/string_processing.rs
+++ /dev/null
@@ -1,29 +0,0 @@
-/// Returns string with stripped line padding characters
-pub fn deent(input: &str) -> String {
- if input.is_empty() {
- return "".to_owned();
- }
- let min_ident = input
- .split('\n')
- .filter(|s| !s.is_empty())
- .map(|ss| ss.chars().take_while(|c| *c == ' ').count())
- .min()
- .unwrap();
- input
- .split('\n')
- .map(|s| s.chars().skip(min_ident).collect::<String>())
- .collect::<Vec<String>>()
- .join("\n")
-}
-
-#[cfg(test)]
-pub mod tests {
- use super::*;
- #[test]
- fn deent_tests() {
- assert_eq!(deent(" aaa"), "aaa");
- assert_eq!(deent(" aaa\n bbb"), " aaa\nbbb");
- assert_eq!(deent(" aaa\n bbb"), "aaa\n bbb");
- assert_eq!(deent(" aaa\n\n bbb"), "aaa\n\n bbb");
- }
-}