From 45be2ff1f5bb3d6e0faa098402adf985b3d5e7ca Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Sat, 4 May 2019 12:38:36 +0200 Subject: Rename dhall_core to dhall_syntax --- dhall_syntax/src/text.rs | 116 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 dhall_syntax/src/text.rs (limited to 'dhall_syntax/src/text.rs') diff --git a/dhall_syntax/src/text.rs b/dhall_syntax/src/text.rs new file mode 100644 index 0000000..83643d9 --- /dev/null +++ b/dhall_syntax/src/text.rs @@ -0,0 +1,116 @@ +use std::iter::FromIterator; + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct InterpolatedText { + head: String, + tail: Vec<(SubExpr, String)>, +} + +impl From<(String, Vec<(SubExpr, String)>)> + for InterpolatedText +{ + fn from(x: (String, Vec<(SubExpr, String)>)) -> Self { + InterpolatedText { + head: x.0, + tail: x.1, + } + } +} + +impl From for InterpolatedText { + fn from(s: String) -> Self { + InterpolatedText { + head: s, + tail: vec![], + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum InterpolatedTextContents { + Text(String), + Expr(SubExpr), +} + +impl InterpolatedTextContents { + pub fn is_empty(&self) -> bool { + use InterpolatedTextContents::{Expr, Text}; + match self { + Expr(_) => false, + Text(s) => s.is_empty(), + } + } +} + +impl InterpolatedText { + pub fn traverse_ref<'a, SubExpr2, E, F>( + &'a self, + mut f: F, + ) -> Result, E> + where + F: FnMut(&'a SubExpr) -> Result, + { + Ok(InterpolatedText { + head: self.head.clone(), + tail: self + .tail + .iter() + .map(|(e, s)| Ok((f(e)?, s.clone()))) + .collect::>()?, + }) + } + + pub fn iter<'a>( + &'a self, + ) -> impl Iterator> + 'a + where + SubExpr: Clone, + { + use std::iter::once; + use InterpolatedTextContents::{Expr, Text}; + once(Text(self.head.clone())) + .chain(self.tail.iter().flat_map(|(e, s)| { + once(Expr(SubExpr::clone(e))).chain(once(Text(s.clone()))) + })) + .filter(|c| !c.is_empty()) + } + + pub fn into_iter( + self, + ) -> impl Iterator> { + use std::iter::once; + use InterpolatedTextContents::{Expr, Text}; + once(Text(self.head)) + .chain( + self.tail + .into_iter() + .flat_map(|(e, s)| once(Expr(e)).chain(once(Text(s)))), + ) + .filter(|c| !c.is_empty()) + } +} + +impl FromIterator> + for InterpolatedText +{ + fn from_iter(iter: T) -> Self + where + T: IntoIterator>, + { + let mut res = InterpolatedText { + head: String::new(), + tail: Vec::new(), + }; + let mut crnt_str = &mut res.head; + for x in iter.into_iter() { + match x { + InterpolatedTextContents::Text(s) => crnt_str.push_str(&s), + InterpolatedTextContents::Expr(e) => { + res.tail.push((e, String::new())); + crnt_str = &mut res.tail.last_mut().unwrap().1; + } + } + } + res + } +} -- cgit v1.2.3