1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
use std::mem;

use error::Error;
use query::{Direction, Page, Query, Sort};
use value::{Key, Map, Path, Set, Value};

/// An implementation of the "builder pattern" that can be used to construct a
/// new query.
#[derive(Default)]
pub struct Builder {
    fields: Vec<(String, Vec<String>)>,
    filter: Vec<(String, Value)>,
    include: Vec<String>,
    page: Option<Page>,
    sort: Vec<(String, Direction)>,
}

impl Builder {
    /// Attempt to construct a new query from the previously supplied values.
    pub fn build(&mut self) -> Result<Query, Error> {
        Ok(Query {
            sort: {
                self.sort
                    .drain(..)
                    .map(|(field, direction)| {
                        let field = field.parse()?;
                        Ok(Sort::new(field, direction))
                    })
                    .collect::<Result<Set<Sort>, Error>>()?
            },
            filter: {
                self.filter
                    .drain(..)
                    .map(|(key, value)| Ok((key.parse()?, value)))
                    .collect::<Result<Map<Path, Value>, Error>>()?
            },
            fields: {
                self.fields
                    .drain(..)
                    .map(|(key, mut value)| {
                        let key = key.parse::<Key>()?;
                        let value = value
                            .drain(..)
                            .map(|item| item.parse())
                            .collect::<Result<Set, Error>>()?;

                        Ok((key, value))
                    })
                    .collect::<Result<Map<Key, Set>, Error>>()?
            },
            include: {
                self.include
                    .drain(..)
                    .map(|value| value.parse())
                    .collect::<Result<Set<Path>, Error>>()?
            },
            page: mem::replace(&mut self.page, None),
            _ext: (),
        })
    }

    pub fn fields<I, K, V>(&mut self, key: K, iter: I) -> &mut Self
    where
        I: IntoIterator<Item = V>,
        K: Into<String>,
        V: Into<String>,
    {
        let key = key.into();
        let value = iter.into_iter().map(|i| i.into()).collect();

        self.fields.push((key, value));
        self
    }

    pub fn filter<K, V>(&mut self, key: K, value: V) -> &mut Self
    where
        K: Into<String>,
        V: Into<Value>,
    {
        let key = key.into();
        let value = value.into();

        self.filter.push((key, value));
        self
    }

    pub fn include<V>(&mut self, value: V) -> &mut Self
    where
        V: Into<String>,
    {
        self.include.push(value.into());
        self
    }

    pub fn page(&mut self, number: u64, size: Option<u64>) -> &mut Self {
        self.page = Some(Page::new(number, size));
        self
    }

    pub fn sort<F>(&mut self, field: F, direction: Direction) -> &mut Self
    where
        F: Into<String>,
    {
        self.sort.push((field.into(), direction));
        self
    }
}