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
extern crate serde;
#[macro_use]
extern crate serde_derive;
#[macro_use]
extern crate serde_json;

pub mod action;
pub mod entity;
pub mod field;
pub mod link;
pub mod property;

pub mod prelude {
    pub use super::action::Action;
    pub use super::entity::Entity;
    pub use super::field::Field;
    pub use super::link::Link;
    pub use super::property::Property;
}

#[cfg(test)]
mod test {
    use serde_json::to_value;

    use super::prelude::*;

    #[test]
    fn json_spec() {
        let siren = Entity::default()
            .class("order")
            .properties(vec![
                Property::new("itemCount", 3),
                Property::new("orderNumber", 42),
                Property::new("status", "pending"),
            ])
            .actions(vec![
                Action::new("add-item", "http://api.x.io/orders/42/items")
                    .method("POST")
                    .title("Add Item")
                    .tpye("application/x-www-form-urlencoded")
                    .fields(vec![
                        Field::new("orderNumber").tpye("hidden").value("42"),
                        Field::new("productCode").tpye("text"),
                        Field::new("quantity").tpye("number"),
                    ]),
            ])
            .entities(vec![
                Entity::new()
                    .rel(vec!["http://x.io/rels/order-items"])
                    .classes(vec!["items", "collection"])
                    .href("http://api.x.io/orders/42/items"),
                Entity::new()
                    .rel(vec!["http://x.io/rels/customer"])
                    .classes(vec!["info", "customer"])
                    .links(vec![
                        Link::new(vec!["self"], "http://api.x.io/customers/pj123"),
                    ])
                    .properties(vec![
                        Property::new("customerId", "pj123"),
                        Property::new("name", "Peter Joseph"),
                    ]),
            ])
            .links(vec![
                Link::new(vec!["self"], "http://api.x.io/orders/42"),
                Link::new(vec!["previous"], "http://api.x.io/orders/41"),
                Link::new(vec!["next"], "http://api.x.io/orders/43"),
            ]);

        assert_eq!(
            json!({
                "actions": [{
                    "fields": [
                        { "name": "orderNumber", "type": "hidden", "value": "42" },
                        { "name": "productCode", "type": "text" },
                        { "name": "quantity", "type": "number" }
                    ],
                    "href": "http://api.x.io/orders/42/items",
                    "method": "POST",
                    "name": "add-item",
                    "title": "Add Item",
                    "type": "application/x-www-form-urlencoded"
                }],
                "class": [ "order" ],
                "entities": [{
                    "class": [ "items", "collection" ],
                    "href": "http://api.x.io/orders/42/items",
                    "rel": [ "http://x.io/rels/order-items" ]
                }, {
                    "class": [ "info", "customer" ],
                    "links": [
                        { "href": "http://api.x.io/customers/pj123", "rel": [ "self" ] }
                    ],
                    "properties": {
                        "customerId": "pj123",
                        "name": "Peter Joseph"
                    },
                    "rel": [ "http://x.io/rels/customer" ]
                }],
                "links": [
                    { "href": "http://api.x.io/orders/42", "rel": [ "self" ] },
                    { "href": "http://api.x.io/orders/41", "rel": [ "previous" ] },
                    { "href": "http://api.x.io/orders/43", "rel": [ "next" ] }
                ],
                "properties": {
                    "itemCount": 3,
                    "orderNumber": 42,
                    "status": "pending"
                }
            }),
            to_value(&siren).unwrap(),
        );
    }
}