summaryrefslogtreecommitdiff
path: root/serde_dhall/src/value.rs
blob: d4ded9039bd4deb326a63f3ed9a7764595ffc81b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
use dhall::semantics::{Hir, Nir};
use dhall::syntax::Expr;

use crate::simple::{Type as SimpleType, Value as SimpleValue};
use crate::{sealed::Sealed, Deserialize, Error};

/// An arbitrary 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<SimpleValue>,
    pub(crate) as_simple_ty: Option<SimpleType>,
}

impl Value {
    pub(crate) fn from_nir(x: &Nir) -> Self {
        Value {
            hir: x.to_hir_noenv(),
            as_simple_val: SimpleValue::from_nir(x),
            as_simple_ty: SimpleType::from_nir(x),
        }
    }

    /// Converts a Value into a SimpleValue.
    pub fn to_simple_value(&self) -> Option<SimpleValue> {
        self.as_simple_val.clone()
    }
    /// Converts a Value into a SimpleType.
    pub fn to_simple_type(&self) -> Option<SimpleType> {
        self.as_simple_ty.clone()
    }

    /// Converts a value back to the corresponding AST expression.
    pub(crate) 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)
    }
}

impl Sealed for Value {}

impl Deserialize for Value {
    fn from_dhall(v: &Value) -> Result<Self, Error> {
        Ok(v.clone())
    }
}