jtable/
lib.rs

1extern crate serde;
2use serde::ser::{Serialize, Serializer, SerializeStruct};
3
4use std::borrow::Cow;
5
6#[cfg(test)]
7#[cfg_attr(test, macro_use)]
8extern crate serde_json;
9
10#[cfg(test)]
11extern crate serde_derive;
12
13pub enum JTableResponse<'e, T> {
14    Ok(Action<T>),
15    Err(Cow<'e, str>)
16}
17
18pub enum Action<T> {
19    List(Vec<T>),
20    Create(T),
21    Update,
22    Delete
23}
24
25impl<T> Action<T> where T: Serialize {
26    fn ser<S: SerializeStruct>(&self, s: &mut S) -> Result<(), S::Error> {
27        use Action::*;
28        match self {
29            Update | Delete => {},
30            Create(r) => s.serialize_field("Record", r)?,
31            List(l) => s.serialize_field("Records", l)?
32        }
33        Ok(())
34    }
35}
36
37impl<'e, T> serde::Serialize for JTableResponse<'e, T> where T: Serialize {
38    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
39    where S: Serializer {
40        let mut ser_struct = serializer.serialize_struct("response", 2)?;
41        match self {
42            JTableResponse::Ok(value) => {
43                ser_struct.serialize_field("Result", "OK")?;
44                value.ser(&mut ser_struct)?;
45            },
46            JTableResponse::Err(msg) => {
47                ser_struct.serialize_field("Result", "ERROR")?;
48                ser_struct.serialize_field("Message", msg)?;
49            }
50        }
51        ser_struct.end()
52    }
53}
54
55
56#[cfg(test)]
57mod tests {
58    use super::*;
59    use serde_derive::{Deserialize, Serialize};
60    #[test]
61    fn serialize_list() {
62        #[derive(Deserialize, Serialize)]
63        struct Project {
64            name: String,
65            version: u32,
66            contributors: Vec<String>,
67        }
68
69        assert_eq!(
70            serde_json::to_value(
71                JTableResponse::Ok(
72                    Action::List(vec![
73                        Project {
74                            name: "Rust".to_string(),
75                            version: 2018,
76                            contributors: vec!["brson".to_string()]
77                        }
78                    ])
79                )
80            ).unwrap(),
81            json!({
82                "Result": "OK",
83                "Records": [{
84                    "name": "Rust",
85                    "version": 2018,
86                    "contributors": ["brson"]
87                }]
88            })
89        );
90
91        assert_eq!(
92            serde_json::to_value(
93                JTableResponse::Err::<Project>("Requested entry violates constraints".into())
94            ).unwrap(),
95            json!({"Result": "ERROR", "Message": "Requested entry violates constraints"})
96        );
97
98        assert_eq!(
99            serde_json::to_value(
100                JTableResponse::Ok(
101                    Action::Create(Some(Project{name: "jtable".to_string(), version: 1, contributors: vec![]}))
102                )
103            ).unwrap(),
104            json!({"Result": "OK", "Record": {"name": "jtable", "version": 1, "contributors": []}})
105        );
106    }
107}