1mod bit_array;
2mod capture;
3mod custom;
4mod external;
5mod function;
6mod inspection;
7mod list;
8
9use ecow::EcoString;
10use num_bigint::BigInt;
11
12use crate::plan::ValueType;
13
14pub use self::bit_array::{BitArrayValue, BitArrayValueLengthError};
15pub(crate) use self::capture::{CaptureListValue, CaptureValue};
16pub use self::custom::{CustomFieldValue, CustomValue};
17pub use self::external::{ExternalValue, ExternalValueIdentity};
18pub use self::function::FunctionValue;
19pub(crate) use self::function::{
20 BitArrayFunctionValue, BoolFunctionValue, CustomFunctionValue, CustomFunctionValueTarget,
21 ExternalFunctionValue, FloatFunctionValue, FunctionFunctionValue, FunctionValueKind,
22 GenericFunctionValue, IntFunctionValue, ListFunctionValue, NeverFunctionValue,
23 NilFunctionValue, StringFunctionValue, TupleFunctionValue, UtfCodepointFunctionValue,
24};
25pub use self::inspection::ValueInspection;
26pub use self::list::{ListValue, ListValueItemTypeMismatch};
27
28#[derive(Debug, Clone, PartialEq)]
29pub enum Value {
30 Int(BigInt),
31 Float(f64),
32 String(EcoString),
33 BitArray(BitArrayValue),
34 UtfCodepoint(char),
35 Custom(CustomValue),
36 External(ExternalValue),
37 Bool(bool),
38 Nil,
39 Tuple(Vec<Value>),
40 List(ListValue),
41 Function(FunctionValue),
42}
43
44impl Value {
45 pub fn inspect(&self) -> ValueInspection<'_> {
46 ValueInspection::new(self)
47 }
48
49 pub fn value_type(&self) -> ValueType {
50 match self {
51 Self::Int(_) => ValueType::Int,
52 Self::Float(_) => ValueType::Float,
53 Self::String(_) => ValueType::String,
54 Self::BitArray(_) => ValueType::BitArray,
55 Self::UtfCodepoint(_) => ValueType::UtfCodepoint,
56 Self::Custom(value) => ValueType::Custom(value.type_().clone()),
57 Self::External(value) => ValueType::External(value.type_().clone()),
58 Self::Bool(_) => ValueType::Bool,
59 Self::Nil => ValueType::Nil,
60 Self::Tuple(values) => ValueType::Tuple(values.iter().map(Self::value_type).collect()),
61 Self::List(value) => ValueType::List(Box::new(value.item_type())),
62 Self::Function(value) => ValueType::Function(Box::new(value.type_())),
63 }
64 }
65}
66
67#[cfg(test)]
68mod tests {
69 use super::{BitArrayValue, CustomValue, ExternalValue, ListValue, Value, ValueType};
70 use crate::host::HostExternalStore;
71 use crate::plan::{CustomType, CustomTypeName, ExternalType, ExternalTypeName};
72
73 #[test]
74 fn value_type_preserves_tuple_element_families() {
75 fn source_hash(
76 context: &crate::host::HostExternalHashing<'_>,
77 value: &crate::host::HostStoredValue<num_bigint::BigInt>,
78 ) -> u64 {
79 context.stored_value_hash(value)
80 }
81
82 fn inspect(
83 context: &crate::host::HostExternalInspection<'_>,
84 value: &crate::host::HostStoredValue<num_bigint::BigInt>,
85 ) -> ecow::EcoString {
86 context.inspect_stored_value(value)
87 }
88
89 assert_eq!(Value::Float(1.0).value_type(), ValueType::Float);
90 assert_eq!(Value::String("one".into()).value_type(), ValueType::String);
91 assert_eq!(
92 Value::BitArray(BitArrayValue::from_bytes(vec![1])).value_type(),
93 ValueType::BitArray,
94 );
95 assert_eq!(
96 Value::UtfCodepoint('\u{10ffff}').value_type(),
97 ValueType::UtfCodepoint,
98 );
99 let custom_type = CustomType::new(
100 CustomTypeName::new("geam".into(), "main".into(), "Boxed".into()),
101 Vec::new(),
102 );
103 assert_eq!(
104 Value::Custom(CustomValue::from_evaluated(
105 custom_type.clone(),
106 "Boxed".into(),
107 0,
108 Vec::new(),
109 ))
110 .value_type(),
111 ValueType::Custom(custom_type),
112 );
113 let external_type = ExternalType::new(
114 ExternalTypeName::new("application".into(), "main".into(), "Resource".into()),
115 Vec::new(),
116 );
117 let store = HostExternalStore::default();
118 let source_equal =
119 |context: &crate::host::HostExternalEquality<'_>,
120 left: &crate::host::HostStoredValue<num_bigint::BigInt>,
121 right: &crate::host::HostStoredValue<num_bigint::BigInt>| {
122 context.stored_values_equal(left, right)
123 };
124 let first = store.insert(
125 crate::host::HostStoredValue::new(crate::runtime::StoredRuntimeValue::test_int(
126 7.into(),
127 )),
128 source_equal,
129 source_hash,
130 inspect,
131 );
132 let equal = store.insert(
133 crate::host::HostStoredValue::new(crate::runtime::StoredRuntimeValue::test_int(
134 7.into(),
135 )),
136 source_equal,
137 source_hash,
138 inspect,
139 );
140 let stored_equal =
141 |left: &crate::runtime::StoredRuntimeValue,
142 right: &crate::runtime::StoredRuntimeValue| left.value() == right.value();
143 let equality = crate::host::HostExternalEquality::new(&stored_equal);
144 assert!(first.source_equal(&equality, &equal));
145 let stored_hash = |_: &crate::runtime::StoredRuntimeValue| 7;
146 let stored_inspect = |_: &crate::runtime::StoredRuntimeValue| "Resource(7)".into();
147 assert_eq!(
148 first.source_hash(&crate::host::HostExternalHashing::new(&stored_hash)),
149 7,
150 );
151 assert_eq!(
152 first.inspection(&crate::host::HostExternalInspection::new(&stored_inspect)),
153 "Resource(7)",
154 );
155 assert_eq!(
156 Value::External(ExternalValue::from_evaluated(
157 external_type.clone(),
158 first,
159 "Resource(7)".into(),
160 ))
161 .value_type(),
162 ValueType::External(external_type),
163 );
164 assert_eq!(Value::Bool(true).value_type(), ValueType::Bool);
165 assert_eq!(Value::Nil.value_type(), ValueType::Nil);
166 assert_eq!(
167 Value::Tuple(vec![Value::Int(1.into()), Value::String("one".into())]).value_type(),
168 ValueType::Tuple(vec![ValueType::Int, ValueType::String]),
169 );
170 assert_eq!(
171 Value::List(ListValue::int(vec![1.into()])).value_type(),
172 ValueType::List(Box::new(ValueType::Int)),
173 );
174 let function = super::FunctionValue::new(
175 crate::plan::execution::function::RuntimeFunctionId::Core(
176 crate::plan::execution::function::CoreRuntimeFunctionId::Int(
177 crate::plan::execution::function::IntFunctionId(0),
178 ),
179 ),
180 Vec::new(),
181 crate::plan::FunctionType::new(Vec::new(), ValueType::Int),
182 );
183 assert_eq!(
184 Value::Function(function).value_type(),
185 ValueType::Function(Box::new(crate::plan::FunctionType::new(
186 Vec::new(),
187 ValueType::Int,
188 ))),
189 );
190 }
191}