diff options
author | Nadrieril | 2019-03-31 19:08:08 +0200 |
---|---|---|
committer | Nadrieril | 2019-03-31 19:08:08 +0200 |
commit | 7374d0524ccd53b256107667b213597c05720d2d (patch) | |
tree | 69dc0e324ffbe3ecf928c62f4e900000f11c5386 /dhall_core | |
parent | bfe3f7f75570540fa184a133653d16e86f22667a (diff) |
Move recursion out of Expr
Diffstat (limited to 'dhall_core')
-rw-r--r-- | dhall_core/src/core.rs | 76 | ||||
-rw-r--r-- | dhall_core/src/parser.rs | 172 | ||||
-rw-r--r-- | dhall_core/src/printer.rs | 8 | ||||
-rw-r--r-- | dhall_core/src/text.rs | 37 |
4 files changed, 141 insertions, 152 deletions
diff --git a/dhall_core/src/core.rs b/dhall_core/src/core.rs index b49515a..2d11068 100644 --- a/dhall_core/src/core.rs +++ b/dhall_core/src/core.rs @@ -173,43 +173,39 @@ pub type DhallExpr = ResolvedExpr; #[derive(Debug, PartialEq, Eq)] pub struct SubExpr<Note, Embed>(pub Rc<Expr<Note, Embed>>); +pub type Expr<Note, Embed> = ExprF<SubExpr<Note, Embed>, Note, Embed>; + /// Syntax tree for expressions +// Having the recursion out of the enum definition enables writing +// much more generic code and improves pattern-matching behind +// smart pointers. #[derive(Debug, Clone, PartialEq, Eq)] -pub enum Expr<Note, Embed> { +pub enum ExprF<SubExpr, Note, Embed> { /// `Const c ~ c` Const(Const), /// `Var (V x 0) ~ x`<br> /// `Var (V x n) ~ x@n` Var(V), /// `Lam x A b ~ λ(x : A) -> b` - Lam(Label, SubExpr<Note, Embed>, SubExpr<Note, Embed>), + Lam(Label, SubExpr, SubExpr), /// `Pi "_" A B ~ A -> B` /// `Pi x A B ~ ∀(x : A) -> B` - Pi(Label, SubExpr<Note, Embed>, SubExpr<Note, Embed>), + Pi(Label, SubExpr, SubExpr), /// `App f A ~ f A` - App(SubExpr<Note, Embed>, Vec<SubExpr<Note, Embed>>), + App(SubExpr, Vec<SubExpr>), /// `Let x Nothing r e ~ let x = r in e` /// `Let x (Just t) r e ~ let x : t = r in e` - Let( - Label, - Option<SubExpr<Note, Embed>>, - SubExpr<Note, Embed>, - SubExpr<Note, Embed>, - ), + Let(Label, Option<SubExpr>, SubExpr, SubExpr), /// `Annot x t ~ x : t` - Annot(SubExpr<Note, Embed>, SubExpr<Note, Embed>), + Annot(SubExpr, SubExpr), /// Built-in values Builtin(Builtin), // Binary operations - BinOp(BinOp, SubExpr<Note, Embed>, SubExpr<Note, Embed>), + BinOp(BinOp, SubExpr, SubExpr), /// `BoolLit b ~ b` BoolLit(bool), /// `BoolIf x y z ~ if x then y else z` - BoolIf( - SubExpr<Note, Embed>, - SubExpr<Note, Embed>, - SubExpr<Note, Embed>, - ), + BoolIf(SubExpr, SubExpr, SubExpr), /// `NaturalLit n ~ +n` NaturalLit(Natural), /// `IntegerLit n ~ n` @@ -217,39 +213,31 @@ pub enum Expr<Note, Embed> { /// `DoubleLit n ~ n` DoubleLit(Double), /// `TextLit t ~ t` - TextLit(InterpolatedText<Note, Embed>), + TextLit(InterpolatedText<SubExpr>), /// [] : List t` - EmptyListLit(SubExpr<Note, Embed>), + EmptyListLit(SubExpr), /// [x, y, z] - NEListLit(Vec<SubExpr<Note, Embed>>), + NEListLit(Vec<SubExpr>), /// None t - EmptyOptionalLit(SubExpr<Note, Embed>), + EmptyOptionalLit(SubExpr), /// Some e - NEOptionalLit(SubExpr<Note, Embed>), + NEOptionalLit(SubExpr), /// `Record [(k1, t1), (k2, t2)] ~ { k1 : t1, k2 : t1 }` - RecordType(BTreeMap<Label, SubExpr<Note, Embed>>), + RecordType(BTreeMap<Label, SubExpr>), /// `RecordLit [(k1, v1), (k2, v2)] ~ { k1 = v1, k2 = v2 }` - RecordLit(BTreeMap<Label, SubExpr<Note, Embed>>), + RecordLit(BTreeMap<Label, SubExpr>), /// `Union [(k1, t1), (k2, t2)] ~ < k1 : t1, k2 : t2 >` - UnionType(BTreeMap<Label, SubExpr<Note, Embed>>), + UnionType(BTreeMap<Label, SubExpr>), /// `UnionLit (k1, v1) [(k2, t2), (k3, t3)] ~ < k1 = t1, k2 : t2, k3 : t3 >` - UnionLit( - Label, - SubExpr<Note, Embed>, - BTreeMap<Label, SubExpr<Note, Embed>>, - ), + UnionLit(Label, SubExpr, BTreeMap<Label, SubExpr>), /// `Merge x y t ~ merge x y : t` - Merge( - SubExpr<Note, Embed>, - SubExpr<Note, Embed>, - Option<SubExpr<Note, Embed>>, - ), + Merge(SubExpr, SubExpr, Option<SubExpr>), /// e.x - Field(SubExpr<Note, Embed>, Label), + Field(SubExpr, Label), /// e.{ x, y, z } - Projection(SubExpr<Note, Embed>, Vec<Label>), + Projection(SubExpr, Vec<Label>), /// Annotation on the AST. Unused for now but could hold e.g. file location information - Note(Note, SubExpr<Note, Embed>), + Note(Note, SubExpr), /// Embeds an import or the result of resolving the import Embed(Embed), } @@ -305,7 +293,7 @@ impl<S, A> Expr<S, A> { impl<S: Clone, A: Clone> Expr<S, Expr<S, A>> { pub fn squash_embed(&self) -> Expr<S, A> { match self { - Expr::Embed(e) => e.clone(), + ExprF::Embed(e) => e.clone(), e => e.map_shallow( |e| e.squash_embed(), |x| x.clone(), @@ -369,7 +357,7 @@ where F4: Fn(&Label) -> Label, F5: FnOnce(&Label, &SubExpr<S, A>) -> SubExpr<T, B>, { - use crate::Expr::*; + use crate::ExprF::*; let map = ↦ let opt = |x: &Option<_>| x.as_ref().map(&map); let vec = |x: &Vec<_>| x.iter().map(&map).collect(); @@ -422,8 +410,8 @@ where F2: FnOnce(&Label, &SubExpr<S, A>) -> SubExpr<S, A>, { match e.as_ref() { - Expr::Embed(_) => SubExpr::clone(e), - Expr::Note(_, e) => { + ExprF::Embed(_) => SubExpr::clone(e), + ExprF::Note(_, e) => { map_subexpr_rc_binder(e, map_expr, map_under_binder) } _ => rc(map_subexpr( @@ -523,7 +511,7 @@ pub fn shift<S, A>( var: &V, in_expr: &SubExpr<S, A>, ) -> SubExpr<S, A> { - use crate::Expr::*; + use crate::ExprF::*; let V(x, n) = var; let under_binder = |y: &Label, e: &SubExpr<_, _>| { let n = if x == y { n + 1 } else { *n }; @@ -553,7 +541,7 @@ pub fn subst<S, A>( value: &SubExpr<S, A>, in_expr: &SubExpr<S, A>, ) -> SubExpr<S, A> { - use crate::Expr::*; + use crate::ExprF::*; let under_binder = |y: &Label, e: &SubExpr<_, _>| { let V(x, n) = var; let n = if x == y { n + 1 } else { *n }; diff --git a/dhall_core/src/parser.rs b/dhall_core/src/parser.rs index b7ac3f6..343a895 100644 --- a/dhall_core/src/parser.rs +++ b/dhall_core/src/parser.rs @@ -13,8 +13,10 @@ use crate::*; // their own crate because they are quite general and useful. For now they // are here and hopefully you can figure out how they work. -type ParsedText = InterpolatedText<X, Import>; -type ParsedTextContents = InterpolatedTextContents<X, Import>; +use crate::ExprF::*; + +type ParsedText = InterpolatedText<SubExpr<X, Import>>; +type ParsedTextContents = InterpolatedTextContents<SubExpr<X, Import>>; pub type ParseError = pest::error::Error<Rule>; @@ -26,9 +28,9 @@ enum Either<A, B> { Right(B), } -impl Builtin { +impl crate::Builtin { pub fn parse(s: &str) -> Option<Self> { - use self::Builtin::*; + use crate::Builtin::*; match s { "Bool" => Some(Bool), "Natural" => Some(Natural), @@ -267,7 +269,7 @@ make_parser! { )); rule!(unreserved_label<Label>; children!( [label(l)] => { - if Builtin::parse(&String::from(&l)).is_some() { + if crate::Builtin::parse(&String::from(&l)).is_some() { Err( format!("Builtin names are not allowed as bound variables") )? @@ -526,13 +528,13 @@ make_parser! { rule!(import<ParsedExpr> as expression; children!( [import_hashed(location_hashed)] => { - bx(Expr::Embed(Import { + bx(Embed(Import { mode: ImportMode::Code, location_hashed })) }, [import_hashed(location_hashed), Text(_)] => { - bx(Expr::Embed(Import { + bx(Embed(Import { mode: ImportMode::RawText, location_hashed })) @@ -541,13 +543,13 @@ make_parser! { rule!(lambda_expression<ParsedExpr> as expression; children!( [unreserved_label(l), expression(typ), expression(body)] => { - bx(Expr::Lam(l, typ, body)) + bx(Lam(l, typ, body)) } )); rule!(ifthenelse_expression<ParsedExpr> as expression; children!( [expression(cond), expression(left), expression(right)] => { - bx(Expr::BoolIf(cond, left, right)) + bx(BoolIf(cond, left, right)) } )); @@ -555,7 +557,7 @@ make_parser! { [let_binding(bindings).., expression(final_expr)] => { bindings.fold( final_expr, - |acc, x| bx(Expr::Let(x.0, x.1, x.2, acc)) + |acc, x| bx(Let(x.0, x.1, x.2, acc)) ) } )); @@ -569,21 +571,21 @@ make_parser! { rule!(forall_expression<ParsedExpr> as expression; children!( [unreserved_label(l), expression(typ), expression(body)] => { - bx(Expr::Pi(l, typ, body)) + bx(Pi(l, typ, body)) } )); rule!(arrow_expression<ParsedExpr> as expression; children!( [expression(typ), expression(body)] => { - bx(Expr::Pi("_".into(), typ, body)) + bx(Pi("_".into(), typ, body)) } )); rule!(merge_expression<ParsedExpr> as expression; children!( [expression(x), expression(y), expression(z)] => - bx(Expr::Merge(x, y, Some(z))), + bx(Merge(x, y, Some(z))), [expression(x), expression(y)] => - bx(Expr::Merge(x, y, None)), + bx(Merge(x, y, None)), )); rule!(List<()>; captured_str!(_) => ()); @@ -591,108 +593,108 @@ make_parser! { rule!(empty_collection<ParsedExpr> as expression; children!( [List(_), expression(t)] => { - bx(Expr::EmptyListLit(t)) + bx(EmptyListLit(t)) }, [Optional(_), expression(t)] => { - bx(Expr::EmptyOptionalLit(t)) + bx(EmptyOptionalLit(t)) }, )); rule!(non_empty_optional<ParsedExpr> as expression; children!( [expression(x), Optional(_), expression(t)] => { - rc(Expr::Annot(rc(Expr::NEOptionalLit(x)), t)) + rc(Annot(rc(NEOptionalLit(x)), t)) } )); rule!(import_alt_expression<ParsedExpr> as expression; children!( [expression(e)] => e, [expression(first), expression(rest)..] => { - let o = BinOp::ImportAlt; - rest.fold(first, |acc, e| bx(Expr::BinOp(o, acc, e))) + let o = crate::BinOp::ImportAlt; + rest.fold(first, |acc, e| bx(BinOp(o, acc, e))) }, )); rule!(or_expression<ParsedExpr> as expression; children!( [expression(e)] => e, [expression(first), expression(rest)..] => { - let o = BinOp::BoolOr; - rest.fold(first, |acc, e| bx(Expr::BinOp(o, acc, e))) + let o = crate::BinOp::BoolOr; + rest.fold(first, |acc, e| bx(BinOp(o, acc, e))) }, )); rule!(plus_expression<ParsedExpr> as expression; children!( [expression(e)] => e, [expression(first), expression(rest)..] => { - let o = BinOp::NaturalPlus; - rest.fold(first, |acc, e| bx(Expr::BinOp(o, acc, e))) + let o = crate::BinOp::NaturalPlus; + rest.fold(first, |acc, e| bx(BinOp(o, acc, e))) }, )); rule!(text_append_expression<ParsedExpr> as expression; children!( [expression(e)] => e, [expression(first), expression(rest)..] => { - let o = BinOp::TextAppend; - rest.fold(first, |acc, e| bx(Expr::BinOp(o, acc, e))) + let o = crate::BinOp::TextAppend; + rest.fold(first, |acc, e| bx(BinOp(o, acc, e))) }, )); rule!(list_append_expression<ParsedExpr> as expression; children!( [expression(e)] => e, [expression(first), expression(rest)..] => { - let o = BinOp::ListAppend; - rest.fold(first, |acc, e| bx(Expr::BinOp(o, acc, e))) + let o = crate::BinOp::ListAppend; + rest.fold(first, |acc, e| bx(BinOp(o, acc, e))) }, )); rule!(and_expression<ParsedExpr> as expression; children!( [expression(e)] => e, [expression(first), expression(rest)..] => { - let o = BinOp::BoolAnd; - rest.fold(first, |acc, e| bx(Expr::BinOp(o, acc, e))) + let o = crate::BinOp::BoolAnd; + rest.fold(first, |acc, e| bx(BinOp(o, acc, e))) }, )); rule!(combine_expression<ParsedExpr> as expression; children!( [expression(e)] => e, [expression(first), expression(rest)..] => { - let o = BinOp::Combine; - rest.fold(first, |acc, e| bx(Expr::BinOp(o, acc, e))) + let o = crate::BinOp::Combine; + rest.fold(first, |acc, e| bx(BinOp(o, acc, e))) }, )); rule!(prefer_expression<ParsedExpr> as expression; children!( [expression(e)] => e, [expression(first), expression(rest)..] => { - let o = BinOp::Prefer; - rest.fold(first, |acc, e| bx(Expr::BinOp(o, acc, e))) + let o = crate::BinOp::Prefer; + rest.fold(first, |acc, e| bx(BinOp(o, acc, e))) }, )); rule!(combine_types_expression<ParsedExpr> as expression; children!( [expression(e)] => e, [expression(first), expression(rest)..] => { - let o = BinOp::CombineTypes; - rest.fold(first, |acc, e| bx(Expr::BinOp(o, acc, e))) + let o = crate::BinOp::CombineTypes; + rest.fold(first, |acc, e| bx(BinOp(o, acc, e))) }, )); rule!(times_expression<ParsedExpr> as expression; children!( [expression(e)] => e, [expression(first), expression(rest)..] => { - let o = BinOp::NaturalTimes; - rest.fold(first, |acc, e| bx(Expr::BinOp(o, acc, e))) + let o = crate::BinOp::NaturalTimes; + rest.fold(first, |acc, e| bx(BinOp(o, acc, e))) }, )); rule!(equal_expression<ParsedExpr> as expression; children!( [expression(e)] => e, [expression(first), expression(rest)..] => { - let o = BinOp::BoolEQ; - rest.fold(first, |acc, e| bx(Expr::BinOp(o, acc, e))) + let o = crate::BinOp::BoolEQ; + rest.fold(first, |acc, e| bx(BinOp(o, acc, e))) }, )); rule!(not_equal_expression<ParsedExpr> as expression; children!( [expression(e)] => e, [expression(first), expression(rest)..] => { - let o = BinOp::BoolNE; - rest.fold(first, |acc, e| bx(Expr::BinOp(o, acc, e))) + let o = crate::BinOp::BoolNE; + rest.fold(first, |acc, e| bx(BinOp(o, acc, e))) }, )); rule!(annotated_expression<ParsedExpr> as expression; children!( [expression(e)] => e, [expression(e), expression(annot)] => { - bx(Expr::Annot(e, annot)) + bx(Annot(e, annot)) }, )); @@ -700,22 +702,22 @@ make_parser! { [expression(e)] => e, [expression(first), expression(second)] => { match first.as_ref() { - Expr::Builtin(Builtin::OptionalNone) => - bx(Expr::EmptyOptionalLit(second)), - Expr::Builtin(Builtin::OptionalSome) => - bx(Expr::NEOptionalLit(second)), - _ => bx(Expr::App(first, vec![second])), + Builtin(crate::Builtin::OptionalNone) => + bx(EmptyOptionalLit(second)), + Builtin(crate::Builtin::OptionalSome) => + bx(NEOptionalLit(second)), + _ => bx(App(first, vec![second])), } }, [expression(first), expression(second), expression(rest)..] => { match first.as_ref() { - Expr::Builtin(Builtin::OptionalNone) => - bx(Expr::App(bx(Expr::EmptyOptionalLit(second)), + Builtin(crate::Builtin::OptionalNone) => + bx(App(bx(EmptyOptionalLit(second)), rest.collect())), - Expr::Builtin(Builtin::OptionalSome) => - bx(Expr::App(bx(Expr::NEOptionalLit(second)), + Builtin(crate::Builtin::OptionalSome) => + bx(App(bx(NEOptionalLit(second)), rest.collect())), - _ => bx(Expr::App(first, + _ => bx(App(first, std::iter::once(second) .chain(rest) .collect())), @@ -727,8 +729,8 @@ make_parser! { [expression(e)] => e, [expression(first), selector(rest)..] => { rest.fold(first, |acc, e| match e { - Either::Left(l) => bx(Expr::Field(acc, l)), - Either::Right(ls) => bx(Expr::Projection(acc, ls)), + Either::Left(l) => bx(Field(acc, l)), + Either::Right(ls) => bx(Projection(acc, ls)), }) } )); @@ -743,66 +745,66 @@ make_parser! { )); rule!(literal_expression<ParsedExpr> as expression; children!( - [double_literal(n)] => bx(Expr::DoubleLit(n)), + [double_literal(n)] => bx(DoubleLit(n)), [minus_infinity_literal(n)] => - bx(Expr::DoubleLit(std::f64::NEG_INFINITY.into())), + bx(DoubleLit(std::f64::NEG_INFINITY.into())), [plus_infinity_literal(n)] => - bx(Expr::DoubleLit(std::f64::INFINITY.into())), - [NaN(n)] => bx(Expr::DoubleLit(std::f64::NAN.into())), - [natural_literal(n)] => bx(Expr::NaturalLit(n)), - [integer_literal(n)] => bx(Expr::IntegerLit(n)), - [double_quote_literal(s)] => bx(Expr::TextLit(s)), - [single_quote_literal(s)] => bx(Expr::TextLit(s)), + bx(DoubleLit(std::f64::INFINITY.into())), + [NaN(n)] => bx(DoubleLit(std::f64::NAN.into())), + [natural_literal(n)] => bx(NaturalLit(n)), + [integer_literal(n)] => bx(IntegerLit(n)), + [double_quote_literal(s)] => bx(TextLit(s)), + [single_quote_literal(s)] => bx(TextLit(s)), [expression(e)] => e, )); rule!(identifier<ParsedExpr> as expression; children!( [label(l), natural_literal(idx)] => { let name = String::from(&l); - match Builtin::parse(name.as_str()) { - Some(b) => bx(Expr::Builtin(b)), + match crate::Builtin::parse(name.as_str()) { + Some(b) => bx(Builtin(b)), None => match name.as_str() { - "True" => bx(Expr::BoolLit(true)), - "False" => bx(Expr::BoolLit(false)), - "Type" => bx(Expr::Const(Const::Type)), - "Kind" => bx(Expr::Const(Const::Kind)), - _ => bx(Expr::Var(V(l, idx))), + "True" => bx(BoolLit(true)), + "False" => bx(BoolLit(false)), + "Type" => bx(Const(crate::Const::Type)), + "Kind" => bx(Const(crate::Const::Kind)), + _ => bx(Var(V(l, idx))), } } }, [label(l)] => { let name = String::from(&l); - match Builtin::parse(name.as_str()) { - Some(b) => bx(Expr::Builtin(b)), + match crate::Builtin::parse(name.as_str()) { + Some(b) => bx(Builtin(b)), None => match name.as_str() { - "True" => bx(Expr::BoolLit(true)), - "False" => bx(Expr::BoolLit(false)), - "Type" => bx(Expr::Const(Const::Type)), - "Kind" => bx(Expr::Const(Const::Kind)), - _ => bx(Expr::Var(V(l, 0))), + "True" => bx(BoolLit(true)), + "False" => bx(BoolLit(false)), + "Type" => bx(Const(crate::Const::Type)), + "Kind" => bx(Const(crate::Const::Kind)), + _ => bx(Var(V(l, 0))), } } }, )); rule!(empty_record_literal<ParsedExpr> as expression; - captured_str!(_) => bx(Expr::RecordLit(BTreeMap::new())) + captured_str!(_) => bx(RecordLit(BTreeMap::new())) ); rule!(empty_record_type<ParsedExpr> as expression; - captured_str!(_) => bx(Expr::RecordType(BTreeMap::new())) + captured_str!(_) => bx(RecordType(BTreeMap::new())) ); rule!(non_empty_record_type_or_literal<ParsedExpr> as expression; children!( [label(first_label), non_empty_record_type(rest)] => { let (first_expr, mut map) = rest; map.insert(first_label, first_expr); - bx(Expr::RecordType(map)) + bx(RecordType(map)) }, [label(first_label), non_empty_record_literal(rest)] => { let (first_expr, mut map) = rest; map.insert(first_label, first_expr); - bx(Expr::RecordLit(map)) + bx(RecordLit(map)) }, )); @@ -830,13 +832,13 @@ make_parser! { rule!(union_type_or_literal<ParsedExpr> as expression; children!( [empty_union_type(_)] => { - bx(Expr::UnionType(BTreeMap::new())) + bx(UnionType(BTreeMap::new())) }, [non_empty_union_type_or_literal((Some((l, e)), entries))] => { - bx(Expr::UnionLit(l, e, entries)) + bx(UnionLit(l, e, entries)) }, [non_empty_union_type_or_literal((None, entries))] => { - bx(Expr::UnionType(entries)) + bx(UnionType(entries)) }, )); @@ -869,7 +871,7 @@ make_parser! { )); rule!(non_empty_list_literal<ParsedExpr> as expression; children!( - [expression(items)..] => bx(Expr::NEListLit(items.collect())) + [expression(items)..] => bx(NEListLit(items.collect())) )); rule!(final_expression<ParsedExpr> as expression; children!( @@ -885,7 +887,7 @@ pub fn parse_expr(s: &str) -> ParseResult<ParsedExpr> { ParsedValue::expression(e) => Ok(e), _ => unreachable!(), } - // Ok(bx(Expr::BoolLit(false))) + // Ok(bx(BoolLit(false))) } #[test] diff --git a/dhall_core/src/printer.rs b/dhall_core/src/printer.rs index b153d1b..b7d7506 100644 --- a/dhall_core/src/printer.rs +++ b/dhall_core/src/printer.rs @@ -35,7 +35,7 @@ impl<S, A: Display> Expr<S, A> { f: &mut fmt::Formatter, phase: PrintPhase, ) -> Result<(), fmt::Error> { - use crate::Expr::*; + use crate::ExprF::*; use PrintPhase::*; match self { _ if phase == Paren => { @@ -143,7 +143,7 @@ impl<S, A: Display> Expr<S, A> { write!(f, " : ")?; b.fmt(f)?; } - Expr::BinOp(op, a, b) => { + ExprF::BinOp(op, a, b) => { // Precedence is magically handled by the ordering of BinOps. if phase > PrintPhase::BinOp(*op) { return self.fmt_phase(f, Paren); @@ -152,7 +152,7 @@ impl<S, A: Display> Expr<S, A> { write!(f, " {} ", op)?; b.fmt_phase(f, PrintPhase::BinOp(*op))?; } - Expr::App(a, args) => { + ExprF::App(a, args) => { if phase > PrintPhase::App { return self.fmt_phase(f, Paren); } @@ -239,7 +239,7 @@ where f.write_str(close) } -impl<S, A: Display> Display for InterpolatedText<S, A> { +impl<SubExpr: Display + Clone> Display for InterpolatedText<SubExpr> { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { f.write_str("\"")?; for x in self.iter() { diff --git a/dhall_core/src/text.rs b/dhall_core/src/text.rs index eef0797..d915553 100644 --- a/dhall_core/src/text.rs +++ b/dhall_core/src/text.rs @@ -1,17 +1,16 @@ -use crate::*; use std::iter::FromIterator; use std::ops::Add; #[derive(Debug, Clone, PartialEq, Eq)] -pub struct InterpolatedText<Note, Embed> { +pub struct InterpolatedText<SubExpr> { head: String, - tail: Vec<(SubExpr<Note, Embed>, String)>, + tail: Vec<(SubExpr, String)>, } -impl<N, E> From<(String, Vec<(SubExpr<N, E>, String)>)> - for InterpolatedText<N, E> +impl<SubExpr> From<(String, Vec<(SubExpr, String)>)> + for InterpolatedText<SubExpr> { - fn from(x: (String, Vec<(SubExpr<N, E>, String)>)) -> Self { + fn from(x: (String, Vec<(SubExpr, String)>)) -> Self { InterpolatedText { head: x.0, tail: x.1, @@ -19,7 +18,7 @@ impl<N, E> From<(String, Vec<(SubExpr<N, E>, String)>)> } } -impl<N, E> From<String> for InterpolatedText<N, E> { +impl<SubExpr> From<String> for InterpolatedText<SubExpr> { fn from(s: String) -> Self { InterpolatedText { head: s, @@ -29,15 +28,15 @@ impl<N, E> From<String> for InterpolatedText<N, E> { } #[derive(Debug, Clone, PartialEq, Eq)] -pub enum InterpolatedTextContents<Note, Embed> { +pub enum InterpolatedTextContents<SubExpr> { Text(String), - Expr(SubExpr<Note, Embed>), + Expr(SubExpr), } -impl<N, E> InterpolatedText<N, E> { - pub fn map<N2, E2, F>(&self, mut f: F) -> InterpolatedText<N2, E2> +impl<SubExpr: Clone> InterpolatedText<SubExpr> { + pub fn map<SubExpr2, F>(&self, mut f: F) -> InterpolatedText<SubExpr2> where - F: FnMut(&SubExpr<N, E>) -> SubExpr<N2, E2>, + F: FnMut(&SubExpr) -> SubExpr2, { InterpolatedText { head: self.head.clone(), @@ -47,7 +46,7 @@ impl<N, E> InterpolatedText<N, E> { pub fn iter<'a>( &'a self, - ) -> impl Iterator<Item = InterpolatedTextContents<N, E>> + 'a { + ) -> impl Iterator<Item = InterpolatedTextContents<SubExpr>> + 'a { use std::iter::once; once(InterpolatedTextContents::Text(self.head.clone())).chain( self.tail.iter().flat_map(|(e, s)| { @@ -58,12 +57,12 @@ impl<N, E> InterpolatedText<N, E> { } } -impl<'a, N: 'a, E: 'a> FromIterator<InterpolatedTextContents<N, E>> - for InterpolatedText<N, E> +impl<'a, SubExpr: Clone + 'a> FromIterator<InterpolatedTextContents<SubExpr>> + for InterpolatedText<SubExpr> { fn from_iter<T>(iter: T) -> Self where - T: IntoIterator<Item = InterpolatedTextContents<N, E>>, + T: IntoIterator<Item = InterpolatedTextContents<SubExpr>>, { let mut res = InterpolatedText { head: "".to_owned(), @@ -83,9 +82,9 @@ impl<'a, N: 'a, E: 'a> FromIterator<InterpolatedTextContents<N, E>> } } -impl<N, E> Add for &InterpolatedText<N, E> { - type Output = InterpolatedText<N, E>; - fn add(self, rhs: &InterpolatedText<N, E>) -> Self::Output { +impl<SubExpr: Clone> Add for &InterpolatedText<SubExpr> { + type Output = InterpolatedText<SubExpr>; + fn add(self, rhs: &InterpolatedText<SubExpr>) -> Self::Output { self.iter().chain(rhs.iter()).collect() } } |