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
|
use dhall::syntax::Builtin;
use crate::Value;
/// A Rust type that can be represented as a Dhall type.
///
/// A typical example is `Option<bool>`,
/// represented by the dhall expression `Optional Bool`.
///
/// This trait can and should be automatically derived.
///
/// The representation needs to be independent of the value.
/// For this reason, something like `HashMap<String, bool>` cannot implement
/// [StaticType] because each different value would
/// have a different Dhall record type.
pub trait StaticType {
fn static_type() -> Value;
}
macro_rules! derive_builtin {
($ty:ty, $builtin:ident) => {
impl StaticType for $ty {
fn static_type() -> Value {
Value::make_builtin_type(Builtin::$builtin)
}
}
};
}
derive_builtin!(bool, Bool);
derive_builtin!(usize, Natural);
derive_builtin!(u64, Natural);
derive_builtin!(u32, Natural);
derive_builtin!(isize, Integer);
derive_builtin!(i64, Integer);
derive_builtin!(i32, Integer);
derive_builtin!(f64, Double);
derive_builtin!(f32, Double);
derive_builtin!(String, Text);
impl<A, B> StaticType for (A, B)
where
A: StaticType,
B: StaticType,
{
fn static_type() -> Value {
Value::make_record_type(
vec![
("_1".to_owned(), A::static_type()),
("_2".to_owned(), B::static_type()),
]
.into_iter(),
)
}
}
impl<T, E> StaticType for std::result::Result<T, E>
where
T: StaticType,
E: StaticType,
{
fn static_type() -> Value {
Value::make_union_type(
vec![
("Ok".to_owned(), Some(T::static_type())),
("Err".to_owned(), Some(E::static_type())),
]
.into_iter(),
)
}
}
impl<T> StaticType for Option<T>
where
T: StaticType,
{
fn static_type() -> Value {
Value::make_optional_type(T::static_type())
}
}
impl<T> StaticType for Vec<T>
where
T: StaticType,
{
fn static_type() -> Value {
Value::make_list_type(T::static_type())
}
}
impl<'a, T> StaticType for &'a T
where
T: StaticType,
{
fn static_type() -> Value {
T::static_type()
}
}
|