bluejay_validator/executable/operation/
variable_values.rs1use bluejay_core::executable::{
2 OperationDefinition, VariableDefinition, VariableType, VariableTypeReference,
3};
4use bluejay_core::{AsIter, BuiltinScalarDefinition, Value, Variable};
5
6pub trait VariableValues {
7 type Key: AsRef<str>;
8 type Value: Value<true>;
9 type Iterator<'a>: Iterator<Item = (&'a Self::Key, &'a Self::Value)>
10 where
11 Self: 'a;
12
13 fn iter(&self) -> Self::Iterator<'_>;
14
15 fn get(&self, key: &str) -> Option<&Self::Value> {
16 self.iter().find(|(k, _)| k.as_ref() == key).map(|(_, v)| v)
17 }
18}
19
20pub trait OperationDefinitionValueEvaluationExt: OperationDefinition {
21 fn evaluate_bool<V: Variable, VV: VariableValues>(
22 &self,
23 variable: &V,
24 variable_values: &VV,
25 ) -> Option<bool>;
26
27 fn evaluate_int<V: Variable, VV: VariableValues>(
28 &self,
29 variable: &V,
30 variable_values: &VV,
31 ) -> Option<i32>;
32}
33
34impl<T: OperationDefinition> OperationDefinitionValueEvaluationExt for T {
35 fn evaluate_bool<V: Variable, VV: VariableValues>(
36 &self,
37 variable: &V,
38 variable_values: &VV,
39 ) -> Option<bool> {
40 let variable_definitions = self.as_ref().variable_definitions()?;
41 let variable_definition = variable_definitions.iter().find(|variable_definition| {
42 variable_definition.variable() == variable.name()
43 && matches!(
44 variable_definition.r#type().as_ref(),
45 VariableTypeReference::Named(type_name, _) if type_name == BuiltinScalarDefinition::Boolean.as_ref()
46 )
47 })?;
48
49 let value = variable_values
50 .iter()
51 .find(|(key, _)| key.as_ref() == variable.name())
52 .map(|(_, value)| value);
53
54 if let Some(value) = value {
55 value.as_ref().as_boolean().copied()
56 } else {
57 variable_definition
58 .default_value()
59 .and_then(|value| value.as_ref().as_boolean().copied())
60 }
61 }
62
63 fn evaluate_int<V: Variable, VV: VariableValues>(
64 &self,
65 variable: &V,
66 variable_values: &VV,
67 ) -> Option<i32> {
68 let variable_definitions = self.as_ref().variable_definitions()?;
69 let variable_definition = variable_definitions.iter().find(|variable_definition| {
70 variable_definition.variable() == variable.name()
71 && matches!(
72 variable_definition.r#type().as_ref(),
73 VariableTypeReference::Named(type_name, _) if type_name == BuiltinScalarDefinition::Int.as_ref()
74 )
75 })?;
76
77 let value = variable_values
78 .iter()
79 .find(|(key, _)| key.as_ref() == variable.name())
80 .map(|(_, value)| value);
81
82 if let Some(value) = value {
83 value.as_ref().as_integer().copied()
84 } else {
85 variable_definition
86 .default_value()
87 .and_then(|value| value.as_ref().as_integer().copied())
88 }
89 }
90}
91
92#[cfg(feature = "serde_json")]
93impl VariableValues for serde_json::Map<String, serde_json::Value> {
94 type Key = String;
95 type Value = serde_json::Value;
96 type Iterator<'a> = serde_json::map::Iter<'a>;
97
98 fn iter(&self) -> Self::Iterator<'_> {
99 self.iter()
100 }
101}