actiondb/matcher/pattern/
deser.rs1use 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}