diff options
Diffstat (limited to '')
-rw-r--r-- | dhall/tests/parser.rs | 2 | ||||
-rw-r--r-- | dhall_core/src/parser.rs | 44 | ||||
-rw-r--r-- | dhall_core/src/printer.rs | 20 | ||||
-rw-r--r-- | dhall_core/src/text.rs | 20 |
4 files changed, 48 insertions, 38 deletions
diff --git a/dhall/tests/parser.rs b/dhall/tests/parser.rs index e73e78c..f983b8c 100644 --- a/dhall/tests/parser.rs +++ b/dhall/tests/parser.rs @@ -21,7 +21,7 @@ parser_success!(spec_parser_success_collectionImportType, "collectionImportType" parser_success!(spec_parser_success_double, "double"); parser_success!(spec_parser_success_doubleQuotedString, "doubleQuotedString"); parser_success!(spec_parser_success_environmentVariables, "environmentVariables"); -// parser_success!(spec_parser_success_escapedDoubleQuotedString, "escapedDoubleQuotedString"); +parser_success!(spec_parser_success_escapedDoubleQuotedString, "escapedDoubleQuotedString"); parser_success!(spec_parser_success_escapedSingleQuotedString, "escapedSingleQuotedString"); parser_success!(spec_parser_success_fields, "fields"); parser_success!(spec_parser_success_forall, "forall"); diff --git a/dhall_core/src/parser.rs b/dhall_core/src/parser.rs index 8908c78..9fd3213 100644 --- a/dhall_core/src/parser.rs +++ b/dhall_core/src/parser.rs @@ -13,7 +13,7 @@ use crate::*; // are here and hopefully you can figure out how they work. type ParsedText = InterpolatedText<X, Import>; -type ParsedTextContents<'a> = InterpolatedTextContents<'a, X, Import>; +type ParsedTextContents = InterpolatedTextContents<X, Import>; pub type ParseError = pest::error::Error<Rule>; @@ -270,7 +270,7 @@ make_parser! { } )); - rule!(double_quote_chunk<ParsedTextContents<'a>>; children!( + rule!(double_quote_chunk<ParsedTextContents>; children!( [interpolation(e)] => { InterpolatedTextContents::Expr(e) }, @@ -278,24 +278,28 @@ make_parser! { InterpolatedTextContents::Text(s) }, [double_quote_char(s)] => { - InterpolatedTextContents::Text(s) + InterpolatedTextContents::Text(s.to_owned()) }, )); - rule!(double_quote_escaped<&'a str>; - // TODO: parse all escapes + rule!(double_quote_escaped<String>; captured_str!(s) => { match s { - "\"" => "\"", - "$" => "$", - "\\" => "\\", - "/" => "/", - // "b" => "\b", - // "f" => "\f", - "n" => "\n", - "r" => "\r", - "t" => "\t", - // "uXXXX" - _ => unimplemented!(), + "\"" => "\"".to_owned(), + "$" => "$".to_owned(), + "\\" => "\\".to_owned(), + "/" => "/".to_owned(), + "b" => "\u{0008}".to_owned(), + "f" => "\u{000C}".to_owned(), + "n" => "\n".to_owned(), + "r" => "\r".to_owned(), + "t" => "\t".to_owned(), + _ => { + // "uXXXX" + use std::convert::TryFrom; + let c = u16::from_str_radix(&s[1..5], 16).unwrap(); + let c = char::try_from(c as u32).unwrap(); + std::iter::once(c).collect() + } } } ); @@ -323,22 +327,22 @@ make_parser! { [expression(e)] => e )); - rule!(single_quote_continue<Vec<ParsedTextContents<'a>>>; children!( + rule!(single_quote_continue<Vec<ParsedTextContents>>; children!( [interpolation(c), single_quote_continue(rest)] => { let mut rest = rest; rest.push(InterpolatedTextContents::Expr(c)); rest }, [escaped_quote_pair(c), single_quote_continue(rest)] => { let mut rest = rest; - rest.push(InterpolatedTextContents::Text(c)); rest + rest.push(InterpolatedTextContents::Text(c.to_owned())); rest }, [escaped_interpolation(c), single_quote_continue(rest)] => { let mut rest = rest; - rest.push(InterpolatedTextContents::Text(c)); rest + rest.push(InterpolatedTextContents::Text(c.to_owned())); rest }, [single_quote_char(c), single_quote_continue(rest)] => { let mut rest = rest; - rest.push(InterpolatedTextContents::Text(c)); rest + rest.push(InterpolatedTextContents::Text(c.to_owned())); rest }, [] => { vec![] diff --git a/dhall_core/src/printer.rs b/dhall_core/src/printer.rs index 508c1c8..5ecf5ce 100644 --- a/dhall_core/src/printer.rs +++ b/dhall_core/src/printer.rs @@ -206,13 +206,19 @@ impl<S, A: Display> Expr<S, A> { for x in a.iter() { match x { InterpolatedTextContents::Text(a) => { - // TODO Format all escapes properly - f.write_str( - &a.replace("\n", "\\n") - .replace("\t", "\\t") - .replace("\r", "\\r") - .replace("\"", "\\\""), - )?; + for c in a.chars() { + match c { + '\\' => f.write_str("\\\\"), + '"' => f.write_str("\\\""), + '$' => f.write_str("\\$"), + '\u{0008}' => f.write_str("\\b"), + '\u{000C}' => f.write_str("\\f"), + '\n' => f.write_str("\\n"), + '\r' => f.write_str("\\r"), + '\t' => f.write_str("\\t"), + c => write!(f, "{}", c), + }?; + } } InterpolatedTextContents::Expr(e) => { f.write_str("${ ")?; diff --git a/dhall_core/src/text.rs b/dhall_core/src/text.rs index eb0d39c..2a468d2 100644 --- a/dhall_core/src/text.rs +++ b/dhall_core/src/text.rs @@ -30,8 +30,8 @@ impl<N, E> From<String> for InterpolatedText<N, E> { } #[derive(Debug, Clone)] -pub enum InterpolatedTextContents<'a, Note, Embed> { - Text(&'a str), +pub enum InterpolatedTextContents<Note, Embed> { + Text(String), Expr(SubExpr<Note, Embed>), } @@ -46,35 +46,35 @@ impl<N, E> InterpolatedText<N, E> { } } - pub fn iter(&self) -> impl Iterator<Item = InterpolatedTextContents<N, E>> { + pub fn iter<'a>( + &'a self, + ) -> impl Iterator<Item = InterpolatedTextContents<N, E>> + 'a { use std::iter::once; - once(InterpolatedTextContents::Text(self.head.as_ref())).chain( + once(InterpolatedTextContents::Text(self.head.clone())).chain( self.tail.iter().flat_map(|(e, s)| { once(InterpolatedTextContents::Expr(Rc::clone(e))) - .chain(once(InterpolatedTextContents::Text(s))) + .chain(once(InterpolatedTextContents::Text(s.clone()))) }), ) } } -impl<'a, N: 'a, E: 'a> FromIterator<InterpolatedTextContents<'a, N, E>> +impl<'a, N: 'a, E: 'a> FromIterator<InterpolatedTextContents<N, E>> for InterpolatedText<N, E> { fn from_iter<T>(iter: T) -> Self where - T: IntoIterator<Item = InterpolatedTextContents<'a, N, E>>, + T: IntoIterator<Item = InterpolatedTextContents<N, E>>, { let mut res = InterpolatedText { head: "".to_owned(), tail: vec![], }; - // let mut empty_string = "".to_owned(); let mut crnt_str = &mut res.head; for x in iter.into_iter() { match x { - InterpolatedTextContents::Text(s) => crnt_str.push_str(s), + InterpolatedTextContents::Text(s) => crnt_str.push_str(&s), InterpolatedTextContents::Expr(e) => { - // crnt_str = &mut empty_string; res.tail.push((e.clone(), "".to_owned())); crnt_str = &mut res.tail.last_mut().unwrap().1; } |