1use ast::FilterAst;
2use failure::Fail;
3use fnv::FnvBuildHasher;
4use indexmap::map::{Entry, IndexMap};
5use lex::{complete, expect, span, take_while, LexErrorKind, LexResult, LexWith};
6use serde::{Deserialize, Serialize, Serializer};
7use std::{
8 cmp::{max, min},
9 error::Error,
10 fmt::{self, Debug, Display, Formatter},
11 ptr,
12};
13use types::{GetType, Type};
14
15#[derive(PartialEq, Eq, Clone, Copy)]
16pub(crate) struct Field<'s> {
17 scheme: &'s Scheme,
18 index: usize,
19}
20
21impl<'s> Serialize for Field<'s> {
22 fn serialize<S: Serializer>(&self, ser: S) -> Result<S::Ok, S::Error> {
23 self.name().serialize(ser)
24 }
25}
26
27impl<'s> Debug for Field<'s> {
28 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
29 write!(f, "{}", self.name())
30 }
31}
32
33impl<'i, 's> LexWith<'i, &'s Scheme> for Field<'s> {
34 fn lex_with(mut input: &'i str, scheme: &'s Scheme) -> LexResult<'i, Self> {
35 let initial_input = input;
36
37 loop {
38 input = take_while(input, "identifier character", |c| {
39 c.is_ascii_alphanumeric() || c == '_'
40 })?
41 .1;
42
43 match expect(input, ".") {
44 Ok(rest) => input = rest,
45 Err(_) => break,
46 };
47 }
48
49 let name = span(initial_input, input);
50
51 let field = scheme
52 .get_field_index(name)
53 .map_err(|err| (LexErrorKind::UnknownField(err), name))?;
54
55 Ok((field, input))
56 }
57}
58
59impl<'s> Field<'s> {
60 pub fn name(&self) -> &'s str {
61 self.scheme.fields.get_index(self.index).unwrap().0
62 }
63
64 pub fn index(&self) -> usize {
65 self.index
66 }
67
68 pub fn scheme(&self) -> &'s Scheme {
69 self.scheme
70 }
71}
72
73impl<'s> GetType for Field<'s> {
74 fn get_type(&self) -> Type {
75 *self.scheme.fields.get_index(self.index).unwrap().1
76 }
77}
78
79#[derive(Debug, PartialEq, Fail)]
82#[fail(display = "unknown field")]
83pub struct UnknownFieldError;
84
85#[derive(Debug, PartialEq, Fail)]
87#[fail(display = "attempt to redefine field {}", _0)]
88pub struct FieldRedefinitionError(String);
89
90#[derive(Debug, PartialEq)]
94pub struct ParseError<'i> {
95 kind: LexErrorKind,
96 input: &'i str,
97 line_number: usize,
98 span_start: usize,
99 span_len: usize,
100}
101
102impl<'i> Error for ParseError<'i> {}
103
104impl<'i> ParseError<'i> {
105 pub(crate) fn new(mut input: &'i str, (kind, span): (LexErrorKind, &'i str)) -> Self {
106 let mut span_start = span.as_ptr() as usize - input.as_ptr() as usize;
107
108 let (line_number, line_start) = input[..span_start]
109 .match_indices('\n')
110 .map(|(pos, _)| pos + 1)
111 .scan(0, |line_number, line_start| {
112 *line_number += 1;
113 Some((*line_number, line_start))
114 })
115 .last()
116 .unwrap_or_default();
117
118 input = &input[line_start..];
119
120 span_start -= line_start;
121 let mut span_len = span.len();
122
123 if let Some(line_end) = input.find('\n') {
124 input = &input[..line_end];
125 span_len = min(span_len, line_end - span_start);
126 }
127
128 ParseError {
129 kind,
130 input,
131 line_number,
132 span_start,
133 span_len,
134 }
135 }
136}
137
138impl<'i> Display for ParseError<'i> {
139 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
140 writeln!(
141 f,
142 "Filter parsing error ({}:{}):",
143 self.line_number + 1,
144 self.span_start + 1
145 )?;
146
147 writeln!(f, "{}", self.input)?;
148
149 for _ in 0..self.span_start {
150 write!(f, " ")?;
151 }
152
153 for _ in 0..max(1, self.span_len) {
154 write!(f, "^")?;
155 }
156
157 writeln!(f, " {}", self.kind)?;
158
159 Ok(())
160 }
161}
162
163#[derive(Default, Deserialize)]
169#[serde(transparent)]
170pub struct Scheme {
171 fields: IndexMap<String, Type, FnvBuildHasher>,
172}
173
174impl PartialEq for Scheme {
175 fn eq(&self, other: &Self) -> bool {
176 ptr::eq(self, other)
177 }
178}
179
180impl Eq for Scheme {}
181
182impl<'s> Scheme {
183 pub fn new() -> Self {
185 Default::default()
186 }
187
188 pub fn with_capacity(n: usize) -> Self {
190 Scheme {
191 fields: IndexMap::with_capacity_and_hasher(n, FnvBuildHasher::default()),
192 }
193 }
194
195 pub fn add_field(&mut self, name: String, ty: Type) -> Result<(), FieldRedefinitionError> {
197 match self.fields.entry(name) {
198 Entry::Occupied(entry) => Err(FieldRedefinitionError(entry.key().to_string())),
199 Entry::Vacant(entry) => {
200 entry.insert(ty);
201 Ok(())
202 }
203 }
204 }
205
206 pub fn try_from_iter(
208 iter: impl IntoIterator<Item = (String, Type)>,
209 ) -> Result<Self, FieldRedefinitionError> {
210 let iter = iter.into_iter();
211 let (low, _) = iter.size_hint();
212 let mut scheme = Scheme::with_capacity(low);
213 for (name, value) in iter {
214 scheme.add_field(name, value)?;
215 }
216 Ok(scheme)
217 }
218
219 pub(crate) fn get_field_index(&'s self, name: &str) -> Result<Field<'s>, UnknownFieldError> {
220 match self.fields.get_full(name) {
221 Some((index, ..)) => Ok(Field {
222 scheme: self,
223 index,
224 }),
225 None => Err(UnknownFieldError),
226 }
227 }
228
229 pub(crate) fn get_field_count(&self) -> usize {
230 self.fields.len()
231 }
232
233 pub fn parse<'i>(&'s self, input: &'i str) -> Result<FilterAst<'s>, ParseError<'i>> {
235 complete(FilterAst::lex_with(input.trim(), self)).map_err(|err| ParseError::new(input, err))
236 }
237}
238
239#[macro_export]
242macro_rules! Scheme {
243 ($($ns:ident $(. $field:ident)*: $ty:ident),* $(,)*) => {
244 $crate::Scheme::try_from_iter(
245 [$(
246 (
247 concat!(stringify!($ns) $(, ".", stringify!($field))*),
248 $crate::Type::$ty
249 )
250 ),*]
251 .iter()
252 .map(|&(k, v)| (k.to_owned(), v)),
253 )
254 .unwrap_or_else(|err| panic!("{}", err))
256 };
257}
258
259#[test]
260fn test_parse_error() {
261 use indoc::indoc;
262
263 let scheme = &Scheme! { num: Int };
264
265 {
266 let err = scheme.parse("xyz").unwrap_err();
267 assert_eq!(
268 err,
269 ParseError {
270 kind: LexErrorKind::UnknownField(UnknownFieldError),
271 input: "xyz",
272 line_number: 0,
273 span_start: 0,
274 span_len: 3
275 }
276 );
277 assert_eq!(
278 err.to_string(),
279 indoc!(
280 r#"
281 Filter parsing error (1:1):
282 xyz
283 ^^^ unknown field
284 "#
285 )
286 );
287 }
288
289 {
290 let err = scheme.parse("xyz\n").unwrap_err();
291 assert_eq!(
292 err,
293 ParseError {
294 kind: LexErrorKind::UnknownField(UnknownFieldError),
295 input: "xyz",
296 line_number: 0,
297 span_start: 0,
298 span_len: 3
299 }
300 );
301 assert_eq!(
302 err.to_string(),
303 indoc!(
304 r#"
305 Filter parsing error (1:1):
306 xyz
307 ^^^ unknown field
308 "#
309 )
310 );
311 }
312
313 {
314 let err = scheme.parse("\n\n xyz").unwrap_err();
315 assert_eq!(
316 err,
317 ParseError {
318 kind: LexErrorKind::UnknownField(UnknownFieldError),
319 input: " xyz",
320 line_number: 2,
321 span_start: 4,
322 span_len: 3
323 }
324 );
325 assert_eq!(
326 err.to_string(),
327 indoc!(
328 r#"
329 Filter parsing error (3:5):
330 xyz
331 ^^^ unknown field
332 "#
333 )
334 );
335 }
336
337 {
338 let err = scheme
339 .parse(indoc!(
340 r#"
341 num == 10 or
342 num == true or
343 num == 20
344 "#
345 ))
346 .unwrap_err();
347 assert_eq!(
348 err,
349 ParseError {
350 kind: LexErrorKind::ExpectedName("digit"),
351 input: "num == true or",
352 line_number: 1,
353 span_start: 7,
354 span_len: 7
355 }
356 );
357 assert_eq!(
358 err.to_string(),
359 indoc!(
360 r#"
361 Filter parsing error (2:8):
362 num == true or
363 ^^^^^^^ expected digit
364 "#
365 )
366 );
367 }
368}
369
370#[test]
371fn test_field() {
372 let scheme = &Scheme! {
373 x: Bytes,
374 x.y.z0: Int,
375 is_TCP: Bool,
376 };
377
378 assert_ok!(
379 Field::lex_with("x;", scheme),
380 scheme.get_field_index("x").unwrap(),
381 ";"
382 );
383
384 assert_ok!(
385 Field::lex_with("x.y.z0-", scheme),
386 scheme.get_field_index("x.y.z0").unwrap(),
387 "-"
388 );
389
390 assert_ok!(
391 Field::lex_with("is_TCP", scheme),
392 scheme.get_field_index("is_TCP").unwrap(),
393 ""
394 );
395
396 assert_err!(
397 Field::lex_with("x..y", scheme),
398 LexErrorKind::ExpectedName("identifier character"),
399 ".y"
400 );
401
402 assert_err!(
403 Field::lex_with("x.#", scheme),
404 LexErrorKind::ExpectedName("identifier character"),
405 "#"
406 );
407
408 assert_err!(
409 Field::lex_with("x.y.z;", scheme),
410 LexErrorKind::UnknownField(UnknownFieldError),
411 "x.y.z"
412 );
413}
414
415#[test]
416#[should_panic(expected = "attempt to redefine field foo")]
417fn test_static_field_type_override() {
418 Scheme! { foo: Int, foo: Int };
419}
420
421#[test]
422fn test_field_type_override() {
423 let mut scheme = Scheme! { foo: Int };
424
425 assert_eq!(
426 scheme.add_field("foo".into(), Type::Bytes),
427 Err(FieldRedefinitionError("foo".into()))
428 )
429}