difftreelog
feat(parser) tailstrict call, multiline
in: master
3 files changed
crates/jsonnet-parser/src/expr.rsdiffbeforeafterboth--- a/crates/jsonnet-parser/src/expr.rs
+++ b/crates/jsonnet-parser/src/expr.rs
@@ -196,7 +196,7 @@
/// error "I'm broken"
Error(LocExpr),
/// a(b, c)
- Apply(LocExpr, ArgsDesc),
+ Apply(LocExpr, ArgsDesc, bool),
///
Select(LocExpr, String),
/// a[b]
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;9pub use expr::*;10pub use expr::*;10pub use peg;11pub use peg;12use string_processing::deent;111312pub struct ParserSettings {14pub struct ParserSettings {13 pub loc_data: bool,15 pub loc_data: bool,78 pub rule assertion(s: &ParserSettings) -> expr::AssertStmt80 pub rule assertion(s: &ParserSettings) -> expr::AssertStmt79 = keyword("assert") _ cond:expr(s) msg:(_ ":" _ e:expr(s) {e})? { expr::AssertStmt(cond, msg) }81 = keyword("assert") _ cond:expr(s) msg:(_ ":" _ e:expr(s) {e})? { expr::AssertStmt(cond, msg) }8280 pub rule string() -> String83 pub rule whole_line() -> String81 = v:("\"" str:$(("\\\"" / !['"'][_])*) "\"" {str.to_owned()}84 = str:$((!['\n'][_])* "\n") {str.to_owned()}85 pub rule string() -> String86 = "\"" str:$(("\\\"" / !['"'][_])*) "\"" {str.to_owned()}82 / "'" str:$((!['\''][_])*) "'" {str.to_owned()}) {v.replace("\\n", "\n")}87 / "'" str:$((!['\''][_])*) "'" {str.to_owned()}88 // 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)}90 / "|||" "\n" str:$((" "*<2, 2> whole_line())+) " "*<1, 1> "|||" {deent(str)}91 / "|||" "\n" str:$((" "*<3, 3> whole_line())+) " "*<2, 2> "|||" {deent(str)}92 / "|||" "\n" str:$((" "*<4, 4> whole_line())+) " "*<3, 3> "|||" {deent(str)}93 / "|||" "\n" str:$((" "*<5, 5> whole_line())+) " "*<4, 4> "|||" {deent(str)}94 / "|||" "\n" str:$((" "*<6, 6> whole_line())+) " "*<5, 5> "|||" {deent(str)}95 / "|||" "\n" str:$((" "*<7, 7> whole_line())+) " "*<6, 6> "|||" {deent(str)}96 / "|||" "\n" str:$((" "*<8, 8> whole_line())+) " "*<7, 7> "|||" {deent(str)}97 / "|||" "\n" str:$((" "*<9, 9> whole_line())+) " "*<8, 8> "|||" {deent(str)}98 / "|||" "\n" str:$((" "*<10, 10> whole_line())+) " "*<9, 9> "|||" {deent(str)}99 / "|||" "\n" str:$((" "*<11, 11> whole_line())+) " "*<10, 10> "|||" {deent(str)}100 / "|||" "\n" str:$((" "*<12, 12> whole_line())+) " "*<11, 10> "|||" {deent(str)}10183 pub rule field_name(s: &ParserSettings) -> expr::FieldName102 pub rule field_name(s: &ParserSettings) -> expr::FieldName84 = name:id() {expr::FieldName::Fixed(name)}103 = name:id() {expr::FieldName::Fixed(name)}201 el!(Expr::Var("std".to_owned())),220 el!(Expr::Var("std".to_owned())),202 el!(Expr::Str("equals".to_owned()))221 el!(Expr::Str("equals".to_owned()))203 )), ArgsDesc(vec![Arg(None, a), Arg(None, b)])222 )),223 ArgsDesc(vec![Arg(None, a), Arg(None, b)]),224 true204 ))}225 ))}205 a:(@) _ "!=" _ b:@ {loc_expr_todo!(Expr::UnaryOp(UnaryOpType::Not, el!(Expr::Apply(226 a:(@) _ "!=" _ b:@ {loc_expr_todo!(Expr::UnaryOp(UnaryOpType::Not, el!(Expr::Apply(206 el!(Expr::Index(227 el!(Expr::Index(207 el!(Expr::Var("std".to_owned())),228 el!(Expr::Var("std".to_owned())),208 el!(Expr::Str("equals".to_owned()))229 el!(Expr::Str("equals".to_owned()))209 )), ArgsDesc(vec![Arg(None, a), Arg(None, b)])230 )),231 ArgsDesc(vec![Arg(None, a), Arg(None, b)]),232 true210 ))))}233 ))))}211 --234 --212 a:(@) _ "<" _ b:@ {loc_expr_todo!(Expr::BinaryOp(a, BinaryOpType::Lt, b))}235 a:(@) _ "<" _ b:@ {loc_expr_todo!(Expr::BinaryOp(a, BinaryOpType::Lt, b))}226 el!(Expr::Index(249 el!(Expr::Index(227 el!(Expr::Var("std".to_owned())),250 el!(Expr::Var("std".to_owned())),228 el!(Expr::Str("mod".to_owned()))251 el!(Expr::Str("mod".to_owned()))229 )), ArgsDesc(vec![Arg(None, a), Arg(None, b)])252 )), ArgsDesc(vec![Arg(None, a), Arg(None, b)]),253 true230 ))}254 ))}231 --255 --232 "-" _ b:@ {loc_expr_todo!(Expr::UnaryOp(UnaryOpType::Minus, b))}256 "-" _ b:@ {loc_expr_todo!(Expr::UnaryOp(UnaryOpType::Minus, b))}236 a:(@) _ "[" _ s:slice_desc(s) _ "]" {loc_expr_todo!(Expr::Slice(a, s))}260 a:(@) _ "[" _ s:slice_desc(s) _ "]" {loc_expr_todo!(Expr::Slice(a, s))}237 a:(@) _ "." _ s:id() {loc_expr_todo!(Expr::Index(a, el!(Expr::Str(s))))}261 a:(@) _ "." _ s:id() {loc_expr_todo!(Expr::Index(a, el!(Expr::Str(s))))}238 a:(@) _ "[" _ s:expr(s) _ "]" {loc_expr_todo!(Expr::Index(a, s))}262 a:(@) _ "[" _ s:expr(s) _ "]" {loc_expr_todo!(Expr::Index(a, s))}239 a:(@) _ "(" _ args:args(s) _ ")" (_ keyword("tailstrict"))? {loc_expr_todo!(Expr::Apply(a, args))}263 a:(@) _ "(" _ args:args(s) _ ")" ts:(_ keyword("tailstrict"))? {loc_expr_todo!(Expr::Apply(a, args, ts.is_some()))}240 a:(@) _ "{" _ body:objinside(s) _ "}" {loc_expr_todo!(Expr::ObjExtend(a, body))}264 a:(@) _ "{" _ body:objinside(s) _ "}" {loc_expr_todo!(Expr::ObjExtend(a, body))}241 --265 --242 e:expr_basic(s) {e}266 e:expr_basic(s) {e}302 }326 }303 }327 }328329 #[test]330 fn multiline_string() {331 assert_eq!(332 parse!("|||\n Hello world!\n a\n|||"),333 el!(Expr::Str(" Hello world!\na\n".to_owned())),334 )335 }304336305 #[test]337 #[test]306 fn empty_object() {338 fn empty_object() {389 el!(Var("std".to_owned())),421 el!(Var("std".to_owned())),390 el!(Str("deepJoin".to_owned()))422 el!(Str("deepJoin".to_owned()))391 )),423 )),392 ArgsDesc(vec![Arg(None, el!(Var("x".to_owned())))])424 ArgsDesc(vec![Arg(None, el!(Var("x".to_owned())))]),425 false,393 )),426 )),394 vec![CompSpec::ForSpec(ForSpecData(427 vec![CompSpec::ForSpec(ForSpecData(395 "x".to_owned(),428 "x".to_owned(),crates/jsonnet-parser/src/string_processing.rsdiffbeforeafterboth--- /dev/null
+++ b/crates/jsonnet-parser/src/string_processing.rs
@@ -0,0 +1,29 @@
+/// 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");
+ }
+}