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}