git.delta.rocks / jrsonnet / refs/commits / 8eff8514f067

difftreelog

feat(parser) tailstrict call, multiline

Лач2020-06-07parent: #fe18508.patch.diff
in: master

3 files changed

modifiedcrates/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]
modifiedcrates/jsonnet-parser/src/lib.rsdiffbeforeafterboth
6use 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;
1113
12pub 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::AssertStmt
79 = 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) }
82
80 pub rule string() -> String83 pub rule whole_line() -> String
81 = v:("\"" str:$(("\\\"" / !['"'][_])*) "\"" {str.to_owned()}84 = str:$((!['\n'][_])* "\n") {str.to_owned()}
85 pub rule string() -> String
86 = "\"" 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)}
101
83 pub rule field_name(s: &ParserSettings) -> expr::FieldName102 pub rule field_name(s: &ParserSettings) -> expr::FieldName
84 = 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 true
204 ))}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 true
210 ))))}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 true
230 ))}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 }
328
329 #[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 }
304336
305 #[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(),
addedcrates/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");
+	}
+}