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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/// Unified query message macro
///
#[macro_export]
macro_rules! query {
    // call util
    (@$util:ident $($args:tt)*) => ( _query_impl!(@$util $($args)*) );

    // make query
    ($($tokens:tt)+) => ( _query_impl!(@query _query_actix, $($tokens)+) );
}

// native API output macros
#[macro_export]
#[doc(hidden)]
macro_rules! _query_actix {
    (@index $coll:expr, $($indexes:tt),+) => (
        $crate::SetIndexes(_query_impl!(@stringify $coll), _query_impl![@vec $($indexes),+])
    );
    (@find $type:tt, $coll:expr, $filter:expr, $order:expr) => (
        $crate::Find::<_, $type>(_query_impl!(@stringify $coll), $filter, $order)
    );
    (@insert $coll:expr, $doc:expr) => (
        $crate::Insert(_query_impl!(@stringify $coll), $doc)
    );
    (@update $coll:expr, $filter:expr, $modify:expr) => (
        $crate::Update(_query_impl!(@stringify $coll), $filter, $modify)
    );
    (@remove $coll:expr, $filter:expr) => (
        $crate::Remove(_query_impl!(@stringify $coll), $filter)
    );
}

#[cfg(test)]
mod test {
    use actor::*;
    use ledb::Value;

    #[test]
    fn find() {
        let find_query: FindMsg<Value> = query!(find in collection);
        assert_eq!(find_query, Find("collection", None, query!(@order)));

        assert_eq!(
            query!(find Value in collection),
            Find("collection", None, query!(@order))
        );

        assert_eq!(
            query!(find Value in collection order desc),
            Find("collection", None, query!(@order desc))
        );

        assert_eq!(
            query!(find Value in collection order by field),
            Find("collection", query!(@filter), query!(@order by field asc))
        );

        assert_eq!(
            query!(find Value in collection order by field desc),
            Find("collection", query!(@filter), query!(@order by field desc))
        );

        assert_eq!(
            query!(find Value in collection where field == "abc"),
            Find("collection", query!(@filter field == "abc"), query!(@order))
        );

        assert_eq!(
            query!(find Value in collection where field == "abc" order desc),
            Find(
                "collection",
                query!(@filter field == "abc"),
                query!(@order desc)
            )
        );

        assert_eq!(
            query!(find Value in collection where some.field == "abc" order by other.field desc),
            Find(
                "collection",
                query!(@filter some.field == "abc"),
                query!(@order by other.field <)
            )
        );
    }

    #[test]
    fn update() {
        assert_eq!(
            query!(update in collection modify field = 123),
            Update("collection", query!(@filter), query!(@modify field = 123))
        );

        assert_eq!(
            query!(update in collection modify field.with.sub.field = 123),
            Update(
                "collection",
                query!(@filter),
                query!(@modify field.with.sub.field = 123)
            )
        );

        assert_eq!(
            query!(update in collection modify field.with.sub.field = 123, other.field = "abc"),
            Update(
                "collection",
                query!(@filter),
                query!(@modify field.with.sub.field = 123, other.field = "abc")
            )
        );

        assert_eq!(
            query!(update in collection modify field = "def" where field == "abc"),
            Update(
                "collection",
                query!(@filter field == "abc"),
                query!(@modify field = "def")
            )
        );

        assert_eq!(
            query!(update in collection modify field = "def", other.field += 123, some.flag~ where field == "abc" && some.flag?),
            Update(
                "collection",
                query!(@filter field == "abc" && some.flag?),
                query!(@modify field = "def", other.field += 123, some.flag~)
            )
        );
    }
}