summaryrefslogtreecommitdiff
path: root/dhall/src/traits.rs
blob: 4925457688a7bf3deb4f4d0f2dd6339c4d58bb5b (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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
use crate::expr::*;
use dhall_core::*;
use dhall_generator::*;
use std::borrow::Cow;

#[derive(Debug, Clone)]
pub enum ConversionError {}

pub trait StaticType {
    fn get_static_type() -> Type;
}

/// Trait for rust types that can be represented in dhall in
/// a single way, independent of the value. A typical example is `Option<bool>`,
/// represented by the dhall expression `Optional Bool`. A typical counterexample
/// is `HashMap<Text, bool>` because dhall cannot represent records with a
/// variable number of fields.
pub trait SimpleStaticType {
    fn get_simple_static_type() -> SimpleType;
}

fn mktype(x: SubExpr<X, X>) -> SimpleType {
    SimpleType(x)
}

impl<T: SimpleStaticType> StaticType for T {
    fn get_static_type() -> Type {
        crate::expr::Normalized(
            T::get_simple_static_type().into(),
            Type::const_type(),
        )
        .into_type()
    }
}

impl StaticType for SimpleType {
    fn get_static_type() -> Type {
        Type::const_type()
    }
}

impl SimpleStaticType for bool {
    fn get_simple_static_type() -> SimpleType {
        mktype(dhall_expr!(Bool))
    }
}

impl SimpleStaticType for Natural {
    fn get_simple_static_type() -> SimpleType {
        mktype(dhall_expr!(Natural))
    }
}

impl SimpleStaticType for Integer {
    fn get_simple_static_type() -> SimpleType {
        mktype(dhall_expr!(Integer))
    }
}

impl SimpleStaticType for String {
    fn get_simple_static_type() -> SimpleType {
        mktype(dhall_expr!(Text))
    }
}

impl<A: SimpleStaticType, B: SimpleStaticType> SimpleStaticType for (A, B) {
    fn get_simple_static_type() -> SimpleType {
        let ta: SubExpr<_, _> = A::get_simple_static_type().into();
        let tb: SubExpr<_, _> = B::get_simple_static_type().into();
        mktype(dhall_expr!({ _1: ta, _2: tb }))
    }
}

impl<T: SimpleStaticType> SimpleStaticType for Option<T> {
    fn get_simple_static_type() -> SimpleType {
        let t: SubExpr<_, _> = T::get_simple_static_type().into();
        mktype(dhall_expr!(Optional t))
    }
}

impl<T: SimpleStaticType> SimpleStaticType for Vec<T> {
    fn get_simple_static_type() -> SimpleType {
        let t: SubExpr<_, _> = T::get_simple_static_type().into();
        mktype(dhall_expr!(List t))
    }
}

impl<'a, T: SimpleStaticType> SimpleStaticType for &'a T {
    fn get_simple_static_type() -> SimpleType {
        T::get_simple_static_type()
    }
}

impl<T> SimpleStaticType for std::marker::PhantomData<T> {
    fn get_simple_static_type() -> SimpleType {
        mktype(dhall_expr!({}))
    }
}

impl<T: SimpleStaticType, E: SimpleStaticType> SimpleStaticType
    for std::result::Result<T, E>
{
    fn get_simple_static_type() -> SimpleType {
        let tt: SubExpr<_, _> = T::get_simple_static_type().into();
        let te: SubExpr<_, _> = E::get_simple_static_type().into();
        mktype(dhall_expr!(< Ok: tt | Err: te>))
    }
}