//! Adds [serde::Deserialze] support for [Sequence] use std::fmt; use serde::de::{self, Deserialize, Deserializer, Visitor}; use crate::{expr_parser::parse_tree, Sequence}; pub struct SequenceVisitor; impl<'de> Visitor<'de> for SequenceVisitor { type Value = Sequence; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { formatter.write_str("a string representing a (nested) comparison") } fn visit_str(self, value: &str) -> Result where E: de::Error, { parse_tree(value).map_err(|e| E::custom(format!("Unable to parse '{}': {:?}", value, e))) } fn visit_string(self, value: String) -> Result where E: de::Error, { parse_tree(&value).map_err(|e| E::custom(format!("Unable to parse '{}': {:?}", value, e))) } } impl<'de> Deserialize<'de> for Sequence { fn deserialize(deserializer: D) -> Result where D: Deserializer<'de>, { deserializer.deserialize_string(SequenceVisitor) } } #[cfg(test)] mod tests { use serde::Deserialize; use crate::{ compare::{Comparison, Logic, Operator}, sequence::{Entity, Sequence}, value::Value, }; #[test] fn test_deserialize() -> anyhow::Result<()> { use serde::de::{ value::{Error as ValueError, StrDeserializer}, IntoDeserializer, }; let input = "a > 1 && b < 2"; let deserializer: StrDeserializer = input.into_deserializer(); let seq = Sequence::deserialize(deserializer).expect("Unable to deserialize"); assert_eq!( seq.items[0], Entity::Comparison(Comparison::from(("a", Operator::Greater, Value::Numeric(1.0))), None), ); assert_eq!( seq.items[1], Entity::Comparison( Comparison::from(("b", Operator::Less, Value::Numeric(2.0))), Some(Logic::And) ), ); Ok(()) } }