#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct File {
#[serde(deserialize_with = "check_version")]
version: String,
pub services: BTreeMap<String, Service>,
#[doc(hidden)]
#[serde(default, skip_serializing, skip_deserializing)]
pub _phantom: PhantomData<()>,
}
impl File {
pub fn read<R>(r: R) -> Result<Self, Error>
where R: io::Read
{
Ok(try!(serde_yaml::from_reader(r)))
}
pub fn write<W>(&self, w: &mut W) -> Result<(), Error>
where W: io::Write
{
Ok(try!(serde_yaml::to_writer(w, self)))
}
pub fn read_from_path<P>(path: P) -> Result<Self, Error>
where P: AsRef<Path>
{
Self::read(try!(fs::File::open(path)))
}
pub fn write_to_path<P>(&self, path: P) -> Result<(), Error>
where P: AsRef<Path>
{
self.write(&mut try!(fs::File::create(path)))
}
}
impl Default for File {
fn default() -> File {
File {
version: "2".to_owned(),
services: Default::default(),
_phantom: PhantomData,
}
}
}
impl FromStr for File {
type Err = serde_yaml::Error;
fn from_str(s: &str) -> Result<File, Self::Err> {
serde_yaml::from_str(&s)
}
}
#[test]
fn file_can_be_converted_from_and_to_yaml() {
let yaml = r#"---
"services":
"foo":
"build": "."
"version": "2"
"#;
assert_roundtrip!(File, yaml);
let file: File = serde_yaml::from_str(&yaml).unwrap();
let foo = file.services.get("foo").unwrap();
assert_eq!(foo.build.as_ref().unwrap().context, value(Context::new(".")));
}
#[test]
fn file_can_only_load_from_version_2() {
let yaml = r#"---
"services":
"foo":
"build": "."
"version": "3"
"#;
assert!(serde_yaml::from_str::<File>(&yaml).is_err());
}