boxology_contract/
presence.rs1#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
3pub enum DecodeRole {
4 ProviderInput,
5 ConsumerOutput,
6}
7
8#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
10pub enum Field<T> {
11 Missing,
12 Null,
13 Value(T),
14}
15
16impl<T> Field<T> {
17 pub fn is_missing(&self) -> bool {
18 matches!(self, Self::Missing)
19 }
20
21 pub fn is_null(&self) -> bool {
22 matches!(self, Self::Null)
23 }
24
25 pub fn is_value(&self) -> bool {
26 matches!(self, Self::Value(_))
27 }
28
29 pub fn value(&self) -> Option<&T> {
31 match self {
32 Self::Value(value) => Some(value),
33 Self::Missing | Self::Null => None,
34 }
35 }
36
37 pub fn into_value(self) -> Option<T> {
39 match self {
40 Self::Value(value) => Some(value),
41 Self::Missing | Self::Null => None,
42 }
43 }
44
45 pub fn as_ref(&self) -> Field<&T> {
46 match self {
47 Self::Missing => Field::Missing,
48 Self::Null => Field::Null,
49 Self::Value(value) => Field::Value(value),
50 }
51 }
52}
53
54#[cfg(test)]
55mod tests {
56 use super::Field;
57
58 #[test]
59 fn field_queries_and_projections_preserve_all_states() {
60 let missing = Field::<u8>::Missing;
61 let null = Field::<u8>::Null;
62 let value = Field::Value(7);
63 assert!(missing.is_missing() && null.is_null() && value.is_value());
64 assert_eq!((missing.value(), missing.as_ref()), (None, Field::Missing));
65 assert_eq!((null.as_ref(), null.into_value()), (Field::Null, None));
66 assert_eq!(value.value(), Some(&7));
67 assert_eq!(value.as_ref(), Field::Value(&7));
68 assert_eq!(value.into_value(), Some(7));
69 }
70}