From fa89e9cb319b353332c9e835944e7f86a6604c42 Mon Sep 17 00:00:00 2001 From: Nadrieril Date: Wed, 18 Mar 2020 21:37:14 +0000 Subject: Move Value, SimpleValue and SimpleType to serde --- serde_dhall/src/value.rs | 73 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 serde_dhall/src/value.rs (limited to 'serde_dhall/src/value.rs') diff --git a/serde_dhall/src/value.rs b/serde_dhall/src/value.rs new file mode 100644 index 0000000..a24f211 --- /dev/null +++ b/serde_dhall/src/value.rs @@ -0,0 +1,73 @@ +use dhall::semantics::Hir; +use dhall::syntax::Expr; +use dhall::{Normalized, Parsed}; + +use crate::simple::{SimpleType, SimpleValue}; +use crate::Error; + +/// A Dhall value. +#[derive(Debug, Clone)] +pub struct Value { + /// Invariant: in normal form + pub(crate) hir: Hir, + /// Cached conversions because they are annoying to construct from Hir. + /// At most one of them will be `Some`. + pub(crate) as_simple_val: Option, + pub(crate) as_simple_ty: Option, +} + +impl Value { + /// Parse a string into a Value, and optionally ensure that the value matches the provided type + /// annotation. + pub fn from_str_with_annot( + s: &str, + ty: Option<&Self>, + ) -> Result { + Self::from_str_with_annot_dhall_error(s, ty).map_err(Error::Dhall) + } + fn from_normalized(x: &Normalized) -> Self { + Value { + hir: x.to_hir(), + as_simple_val: SimpleValue::from_nir(x.as_nir()), + as_simple_ty: SimpleType::from_nir(x.as_nir()), + } + } + + fn from_str_with_annot_dhall_error( + s: &str, + ty: Option<&Self>, + ) -> Result { + let resolved = Parsed::parse_str(s)?.resolve()?; + let typed = match ty { + None => resolved.typecheck()?, + Some(ty) => resolved.typecheck_with(&ty.hir)?, + }; + Ok(Self::from_normalized(&typed.normalize())) + } + + /// Converts a Value into a SimpleValue. + pub fn to_simple_value(&self) -> Option { + self.as_simple_val.clone() + } + /// Converts a Value into a SimpleType. + pub fn to_simple_type(&self) -> Option { + self.as_simple_ty.clone() + } + + /// Converts a value back to the corresponding AST expression. + pub fn to_expr(&self) -> Expr { + self.hir.to_expr(Default::default()) + } +} + +impl Eq for Value {} +impl PartialEq for Value { + fn eq(&self, other: &Self) -> bool { + self.hir == other.hir + } +} +impl std::fmt::Display for Value { + fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> { + self.to_expr().fmt(f) + } +} -- cgit v1.2.3