1#![deny(missing_docs)]
2#![deny(warnings)]
3#![deny(missing_debug_implementations)]
4
5extern crate indexmap;
9extern crate serde;
10#[macro_use] extern crate serde_derive;
11extern crate serde_json;
12
13mod error;
14#[macro_use] mod codec;
15mod types;
16mod parts;
17pub mod aws;
18
19pub use error::{Error, ErrorKind};
20pub use types::*;
21pub use parts::*;
22
23pub mod json {
24 pub use serde_json::{Value, Number};
26}
27
28#[derive(Debug, Default, Serialize, Deserialize)]
30pub struct Template {
31 #[serde(rename = "Description", default, skip_serializing_if = "Option::is_none")]
32 description: Option<String>,
33 #[serde(rename = "Resources", default)]
34 resources: Resources,
35 #[serde(rename = "Outputs", default)]
36 outputs: Outputs
37}
38
39impl Template {
40 pub fn description(&self) -> &Option<String> {
42 &self.description
43 }
44
45 pub fn description_mut(&mut self) -> &mut Option<String> {
47 &mut self.description
48 }
49
50 pub fn resources(&self) -> &Resources {
52 &self.resources
53 }
54
55 pub fn resources_mut(&mut self) -> &mut Resources {
57 &mut self.resources
58 }
59
60 pub fn outputs(&self) -> &Outputs {
62 &self.outputs
63 }
64
65 pub fn outputs_mut(&mut self) -> &mut Outputs {
67 &mut self.outputs
68 }
69}
70
71impl Template {
72 pub fn from_json<T: AsRef<str>>(input: T) -> Result<Template, ::Error> {
74 serde_json::from_str(input.as_ref())
75 .map_err(|err| ::Error::new(::ErrorKind::Serialization, err))
76 }
77
78 pub fn to_json(&self) -> Result<String, ::Error> {
80 serde_json::to_string(self)
81 .map_err(|err| ::Error::new(::ErrorKind::Serialization, err))
82 }
83}
84
85pub trait Resource: Sized + private::Sealed {
87 const TYPE: &'static str;
89 type Properties: private::Properties<Self>;
91
92 fn properties(&self) -> &Self::Properties;
94 fn properties_mut(&mut self) -> &mut Self::Properties;
96}
97
98mod private {
99 pub trait Sealed {}
100
101 pub trait Properties<R>: Into<R> + ::serde::Serialize + ::serde::de::DeserializeOwned {}
102 impl<P, R> Properties<R> for P where P: Into<R> + ::serde::Serialize + ::serde::de::DeserializeOwned {}
103}
104
105#[cfg(test)]
106mod tests {
107 use serde_json::to_value;
108 use super::Template;
109
110 #[test]
111 fn deserialize_empty_template() {
112 let tpl = Template::from_json("{}").unwrap();
113 assert!(tpl.description().is_none())
114 }
115
116 #[test]
117 fn serialize_empty_template() {
118 let tpl = Template::default();
119 let val = to_value(&tpl).unwrap();
120 let obj = val.as_object().unwrap();
121 assert_eq!(2, obj.len());
122 assert_eq!(false, obj.contains_key("Description"));
123 assert_eq!(true, obj.contains_key("Resources"));
124 assert_eq!(true, obj.contains_key("Outputs"));
125 }
126}