actiondb/matcher/pattern/
deser.rs

1use super::Pattern;
2use super::testmessage::TestMessage;
3
4use serde;
5use uuid::Uuid;
6
7use std::collections::BTreeMap;
8
9impl serde::de::Deserialize for Pattern {
10    fn deserialize<D>(deserializer: &mut D) -> Result<Pattern, D::Error>
11        where D: serde::de::Deserializer
12    {
13        deserializer.deserialize_struct("Pattern", &[], PatternVisitor)
14    }
15}
16
17enum Field {
18    NAME,
19    UUID,
20    PATTERN,
21    VALUES,
22    TAGS,
23    TESTMESSAGES,
24}
25
26impl serde::Deserialize for Field {
27    fn deserialize<D>(deserializer: &mut D) -> Result<Field, D::Error>
28        where D: serde::de::Deserializer
29    {
30        struct FieldVisitor;
31
32        impl serde::de::Visitor for FieldVisitor {
33            type Value = Field;
34
35            fn visit_str<E>(&mut self, value: &str) -> Result<Field, E>
36                where E: serde::de::Error
37            {
38                match value {
39                    "name" => Ok(Field::NAME),
40                    "uuid" => Ok(Field::UUID),
41                    "pattern" => Ok(Field::PATTERN),
42                    "values" => Ok(Field::VALUES),
43                    "tags" => Ok(Field::TAGS),
44                    "test_messages" => Ok(Field::TESTMESSAGES),
45                    _ => Err(serde::de::Error::custom(format!("Unexpected field: {}", value))),
46                }
47            }
48        }
49
50        deserializer.deserialize(FieldVisitor)
51    }
52}
53
54
55struct PatternVisitor;
56
57impl PatternVisitor {
58    pub fn parse_uuid<V: serde::de::MapVisitor>(uuid: Option<String>) -> Result<Uuid, V::Error> {
59        let uuid = match uuid {
60            Some(uuid) => {
61                match Uuid::parse_str(&uuid) {
62                    Ok(value) => Some(value),
63                    Err(err) => {
64                        error!("Invalid field 'uuid': uuid={:?} error={}", &uuid, err);
65                        None
66                    }
67                }
68            }
69            None => {
70                None
71            }
72        };
73
74        match uuid {
75            Some(uuid) => Ok(uuid),
76            None => {
77                try!(Err(serde::de::Error::missing_field("uuid")))
78            }
79        }
80    }
81}
82
83impl serde::de::Visitor for PatternVisitor {
84    type Value = Pattern;
85
86    fn visit_map<V>(&mut self, mut visitor: V) -> Result<Pattern, V::Error>
87        where V: serde::de::MapVisitor
88    {
89        let mut name = None;
90        let mut uuid: Option<String> = None;
91        let mut pattern: Option<String> = None;
92        let mut values: Option<BTreeMap<String, String>> = None;
93        let mut tags: Option<Vec<String>> = None;
94        let mut test_messages: Option<Vec<TestMessage>> = None;
95
96        while let Some(field) = try!(visitor.visit_key()) {
97            match field {
98                Field::NAME => name = Some(try!(visitor.visit_value())),
99                Field::UUID => uuid = Some(try!(visitor.visit_value())),
100                Field::PATTERN => pattern = Some(try!(visitor.visit_value())),
101                Field::VALUES => values = Some(try!(visitor.visit_value())),
102                Field::TAGS => tags = Some(try!(visitor.visit_value())),
103                Field::TESTMESSAGES => test_messages = Some(try!(visitor.visit_value())),
104            }
105        }
106
107        let uuid = try!(PatternVisitor::parse_uuid::<V>(uuid));
108
109        let pattern = match pattern {
110            Some(pattern) => {
111                match ::grammar::parser::pattern(&pattern) {
112                    Ok(pattern) => pattern,
113                    Err(err) => {
114                        error!("Invalid field 'pattern': pattern={:?} name={:?} uuid={:?} \
115                                error={}",
116                               pattern,
117                               name,
118                               uuid,
119                               err);
120                        try!(Err(serde::de::Error::custom("Invalid field 'pattern'")))
121                    }
122                }
123            }
124            None => {
125                error!("Missing field 'pattern': name={:?} uuid={:?}", name, uuid);
126                try!(Err(serde::de::Error::missing_field("pattern")))
127            }
128        };
129
130        try!(visitor.end());
131
132        Ok(Pattern::new(name, uuid, pattern, test_messages, values, tags))
133    }
134}