use super::Codec; use std::marker::PhantomData; use std::ops::Sub; #[derive(Clone, Debug)] pub enum FieldOperatorInstruction { Constant, None, Delta, Tail, Copy, } /// *Field encoding operator* in FAST terminology. pub trait FieldOperator { /// The type of the (de)serializable item. type Item: Codec; /// See section 6.3.1 of FAST 1.1 documentation. fn previous_value(&self) -> Option<&Self::Item>; /// Replace the previous value (or set it if unset) with a new one. fn replace(&mut self, new_value: Self::Item); /// Determine whether the specified value can be omitted from the final /// payload. This behavior is custom to every field operator. fn can_omit(&self, value: &Self::Item) -> bool; /// Unset previous state. fn reset(&mut self); } /// The constant operator specifies that the value of a field will always be the /// same, as initialized with `new`. #[derive(Debug)] pub struct Constant { value: T, } impl Constant { pub fn new(value: T) -> Self { Constant { value } } } impl FieldOperator for Constant where T: Codec, { type Item = T; fn previous_value(&self) -> Option<&T> { Some(&self.value) } fn can_omit(&self, _value: &T) -> bool { true } fn replace(&mut self, _new_value: T) {} fn reset(&mut self) {} } /// The delta operator specifies that a delta value is present in the stream. If /// the field has optional presence, the delta value can be NULL. In that case /// the value of the field is considered absent. Otherwise the field is obtained /// by combining the delta value with a base value. #[derive(Debug)] pub struct Delta { prev: Option, delta: U, } impl FieldOperator for Delta where U: PartialEq, T: Codec + Sub + std::marker::Copy, { type Item = T; fn previous_value(&self) -> Option<&T> { self.prev.as_ref() } fn can_omit(&self, value: &T) -> bool { if let Some(prev) = self.prev { *value - prev == self.delta } else { false } } fn replace(&mut self, new_value: T) { self.prev = Some(new_value) } fn reset(&mut self) { self.prev = Option::None } } #[derive(Debug)] pub struct Copy { prev: Option, } impl FieldOperator for Copy where T: Codec + PartialEq + std::marker::Copy, { type Item = T; fn previous_value(&self) -> Option<&T> { self.prev.as_ref() } fn can_omit(&self, value: &T) -> bool { if let Some(previous_value) = self.previous_value() { value == previous_value } else { false } } fn replace(&mut self, new_value: T) { self.prev = Some(new_value) } fn reset(&mut self) { self.prev = Option::None } } /// No field operator at all. #[derive(Debug)] pub struct None(PhantomData); impl Default for None { fn default() -> Self { None(PhantomData) } } impl FieldOperator for None where T: Codec, { type Item = T; fn previous_value(&self) -> Option<&T> { Option::None } fn can_omit(&self, _value: &T) -> bool { false } fn replace(&mut self, _new_value: T) {} fn reset(&mut self) {} }