json_api/query/
builder.rs

1use std::mem;
2
3use error::Error;
4use query::{Direction, Page, Query, Sort};
5use value::{Key, Map, Path, Set, Value};
6
7/// An implementation of the "builder pattern" that can be used to construct a
8/// new query.
9#[derive(Default)]
10pub struct Builder {
11    fields: Vec<(String, Vec<String>)>,
12    filter: Vec<(String, Value)>,
13    include: Vec<String>,
14    page: Option<Page>,
15    sort: Vec<(String, Direction)>,
16}
17
18impl Builder {
19    /// Attempt to construct a new query from the previously supplied values.
20    pub fn build(&mut self) -> Result<Query, Error> {
21        Ok(Query {
22            sort: {
23                self.sort
24                    .drain(..)
25                    .map(|(field, direction)| {
26                        let field = field.parse()?;
27                        Ok(Sort::new(field, direction))
28                    })
29                    .collect::<Result<Set<Sort>, Error>>()?
30            },
31            filter: {
32                self.filter
33                    .drain(..)
34                    .map(|(key, value)| Ok((key.parse()?, value)))
35                    .collect::<Result<Map<Path, Value>, Error>>()?
36            },
37            fields: {
38                self.fields
39                    .drain(..)
40                    .map(|(key, mut value)| {
41                        let key = key.parse::<Key>()?;
42                        let value = value
43                            .drain(..)
44                            .map(|item| item.parse())
45                            .collect::<Result<Set, Error>>()?;
46
47                        Ok((key, value))
48                    })
49                    .collect::<Result<Map<Key, Set>, Error>>()?
50            },
51            include: {
52                self.include
53                    .drain(..)
54                    .map(|value| value.parse())
55                    .collect::<Result<Set<Path>, Error>>()?
56            },
57            page: mem::replace(&mut self.page, None),
58            _ext: (),
59        })
60    }
61
62    pub fn fields<I, K, V>(&mut self, key: K, iter: I) -> &mut Self
63    where
64        I: IntoIterator<Item = V>,
65        K: Into<String>,
66        V: Into<String>,
67    {
68        let key = key.into();
69        let value = iter.into_iter().map(|i| i.into()).collect();
70
71        self.fields.push((key, value));
72        self
73    }
74
75    pub fn filter<K, V>(&mut self, key: K, value: V) -> &mut Self
76    where
77        K: Into<String>,
78        V: Into<Value>,
79    {
80        let key = key.into();
81        let value = value.into();
82
83        self.filter.push((key, value));
84        self
85    }
86
87    pub fn include<V>(&mut self, value: V) -> &mut Self
88    where
89        V: Into<String>,
90    {
91        self.include.push(value.into());
92        self
93    }
94
95    pub fn page(&mut self, number: u64, size: Option<u64>) -> &mut Self {
96        self.page = Some(Page::new(number, size));
97        self
98    }
99
100    pub fn sort<F>(&mut self, field: F, direction: Direction) -> &mut Self
101    where
102        F: Into<String>,
103    {
104        self.sort.push((field.into(), direction));
105        self
106    }
107}