wirefilter/
execution_context.rs1use failure::Fail;
2use scheme::{Field, Scheme};
3use types::{GetType, LhsValue, Type};
4
5#[derive(Debug, PartialEq, Fail)]
8#[fail(
9 display = "the field should have {:?} type, but {:?} was provided",
10 field_type, value_type
11)]
12pub struct FieldValueTypeMismatchError {
13 pub field_type: Type,
15 pub value_type: Type,
17}
18
19pub struct ExecutionContext<'e> {
25 scheme: &'e Scheme,
26 values: Box<[Option<LhsValue<'e>>]>,
27}
28
29impl<'e> ExecutionContext<'e> {
30 pub fn new<'s: 'e>(scheme: &'s Scheme) -> Self {
34 ExecutionContext {
35 scheme,
36 values: vec![None; scheme.get_field_count()].into(),
37 }
38 }
39
40 pub fn scheme(&self) -> &'e Scheme {
42 self.scheme
43 }
44
45 pub(crate) fn get_field_value_unchecked(&self, field: Field<'e>) -> &LhsValue<'e> {
46 debug_assert!(self.scheme() == field.scheme());
50
51 self.values[field.index()].as_ref().unwrap_or_else(|| {
55 panic!(
56 "Field {} was registered but not given a value",
57 field.name()
58 );
59 })
60 }
61
62 pub fn set_field_value<'v: 'e, V: Into<LhsValue<'v>>>(
64 &mut self,
65 name: &str,
66 value: V,
67 ) -> Result<(), FieldValueTypeMismatchError> {
68 let field = self.scheme.get_field_index(name).unwrap();
69 let value = value.into();
70
71 let field_type = field.get_type();
72 let value_type = value.get_type();
73
74 if field_type == value_type {
75 self.values[field.index()] = Some(value);
76 Ok(())
77 } else {
78 Err(FieldValueTypeMismatchError {
79 field_type,
80 value_type,
81 })
82 }
83 }
84}
85
86#[test]
87fn test_field_value_type_mismatch() {
88 let scheme = Scheme! { foo: Int };
89
90 let mut ctx = ExecutionContext::new(&scheme);
91
92 assert_eq!(
93 ctx.set_field_value("foo", LhsValue::Bool(false)),
94 Err(FieldValueTypeMismatchError {
95 field_type: Type::Int,
96 value_type: Type::Bool
97 })
98 );
99}