use crate::Error;
use chrono::NaiveDate;
use serde::{Deserialize, Serialize};
use std::{
collections::HashMap,
fs::File,
io::{Read, Write},
path::Path,
};
#[derive(Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "kebab-case")]
pub struct Manifest {
pub date: NaiveDate,
#[serde(rename = "pkg")]
pub packages: HashMap<String, PackageTargets>,
#[serde(default)]
pub renames: HashMap<String, Rename>,
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct Rename {
pub to: String,
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct PackageTargets {
#[serde(rename = "target")]
pub targets: HashMap<String, PackageInfo>,
}
#[derive(Debug, Serialize, Deserialize, PartialEq)]
pub struct PackageInfo {
pub available: bool,
}
impl Manifest {
pub fn load_from_fs(path: impl AsRef<Path>) -> Result<Self, Error> {
let path = path.as_ref();
let mut f = File::open(path).map_err(|e| Error::Io(e, format!("opening {:?}", path)))?;
let mut data = String::new();
f.read_to_string(&mut data)
.map_err(|e| Error::Io(e, format!("reading {:?}", path)))?;
toml::from_str(&data).map_err(|e| Error::TomlDe(e, format!("{:?}", path)))
}
pub fn save_to_file(&self, path: impl AsRef<Path>) -> Result<(), Error> {
let path = path.as_ref();
let mut f = File::create(path).map_err(|e| Error::Io(e, format!("creating {:?}", path)))?;
let data = toml::to_vec(self)
.map_err(|e| Error::TomlSer(e, format!("serializing {}", self.date)))?;
f.write_all(&data)
.map_err(|e| Error::Io(e, format!("writing to {:?}", path)))?;
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn check() {
let data = r#"date = "2018-09-03"
[pkg.cargo.target.aarch64-unknown-linux-gnu]
available = true
[pkg.cargo.target.arm-unknown-linux-gnueabi]
available = true
[pkg.cargo.target.arm-unknown-linux-gnueabihf]
available = false
[pkg.rustfmt-preview.target.aarch64-unknown-linux-gnu]
available = true
[pkg.rustfmt-preview.target.x86_64-unknown-freebsd]
available = false
[pkg.rustfmt-preview.target.x86_64-unknown-linux-gnu]
available = true
[renames.rls]
to = "rls-preview"
[renames.rustfmt]
to = "rustfmt-preview"
"#;
let parsed_manifest: Manifest = toml::from_str(data).unwrap();
let reference_manifest = Manifest {
date: NaiveDate::from_ymd(2018, 9, 3),
packages: vec![
(
"cargo".to_string(),
PackageTargets {
targets: vec![
(
"aarch64-unknown-linux-gnu".to_string(),
PackageInfo { available: true },
),
(
"arm-unknown-linux-gnueabi".to_string(),
PackageInfo { available: true },
),
(
"arm-unknown-linux-gnueabihf".to_string(),
PackageInfo { available: false },
),
]
.into_iter()
.collect(),
},
),
(
"rustfmt-preview".to_string(),
PackageTargets {
targets: vec![
(
"aarch64-unknown-linux-gnu".to_string(),
PackageInfo { available: true },
),
(
"x86_64-unknown-freebsd".to_string(),
PackageInfo { available: false },
),
(
"x86_64-unknown-linux-gnu".to_string(),
PackageInfo { available: true },
),
]
.into_iter()
.collect(),
},
),
]
.into_iter()
.collect(),
renames: vec![
(
"rls".to_string(),
Rename {
to: "rls-preview".to_string(),
},
),
(
"rustfmt".to_string(),
Rename {
to: "rustfmt-preview".to_string(),
},
),
]
.into_iter()
.collect(),
};
assert_eq!(reference_manifest, parsed_manifest);
}
#[test]
fn check_wildcard() {
let data = r#"date = "2018-09-03"
[pkg.rust-src.target."*"]
available = true
url = "https://static.rust-lang.org/dist/2018-09-03/rust-src-nightly.tar.gz"
hash = "79f524d39ccd7fc28be473d1ec35e77ff18322488d455e046c7fe850f2a56b67"
xz_url = "https://static.rust-lang.org/dist/2018-09-03/rust-src-nightly.tar.xz"
xz_hash = "dbb913da0a207ae80c53bc6a42074b637920c2a80121420416579fed3e7f2499"
"#;
let parsed_manifest: Manifest = toml::from_str(data).unwrap();
let reference_manifest = Manifest {
date: NaiveDate::from_ymd(2018, 9, 3),
packages: vec![(
"rust-src".to_string(),
PackageTargets {
targets: vec![("*".to_string(), PackageInfo { available: true })]
.into_iter()
.collect(),
},
)]
.into_iter()
.collect(),
renames: vec![].into_iter().collect(),
};
assert_eq!(reference_manifest, parsed_manifest);
}
#[test]
fn check_validity() {
let data = r#"manifest-version = "2"
date = "2018-09-03"
[pkg.cargo]
version = "0.30.0-nightly (0ec7281b9 2018-08-20)"
[pkg.cargo.target.aarch64-unknown-linux-gnu]
available = true
url = "https://static.rust-lang.org/dist/2018-09-04/cargo-nightly-aarch64-unknown-linux-gnu.tar.gz"
hash = "15b6e8011af001afb8bc4ec0b951b2b7fcd139f5d83ce82fea7c711c259d217a"
xz_url = "https://static.rust-lang.org/dist/2018-09-04/cargo-nightly-aarch64-unknown-linux-gnu.tar.xz"
xz_hash = "23844e04a62c5fc74a2aebb8e084d6d066deae486f080e0f746eb34148e787f9"
[pkg.cargo.target.arm-unknown-linux-gnueabi]
available = true
url = "https://static.rust-lang.org/dist/2018-09-04/cargo-nightly-arm-unknown-linux-gnueabi.tar.gz"
hash = "bae7e0f9450b64a42e75db53c3f733ccacc1108393473c64cc13ef79900dbe71"
xz_url = "https://static.rust-lang.org/dist/2018-09-04/cargo-nightly-arm-unknown-linux-gnueabi.tar.xz"
xz_hash = "d9ccfec25501c9a9a247867b711d59886c2913367d16f6ba5887612abb8325d1"
[pkg.cargo.target.arm-unknown-linux-gnueabihf]
available = true
url = "https://static.rust-lang.org/dist/2018-09-04/cargo-nightly-arm-unknown-linux-gnueabihf.tar.gz"
hash = "62f6cbfa88e7301414a40d2bfcdc77809a3eace1dbbc8c47b839bdaa5756d326"
xz_url = "https://static.rust-lang.org/dist/2018-09-04/cargo-nightly-arm-unknown-linux-gnueabihf.tar.xz"
xz_hash = "ca0e68e7e9827ba6221a40bb17170e8dc6271a9f6991ee5030dcf6acb1a1d8c8"
[pkg.rustfmt-preview]
version = "0.99.2-nightly (5c9a2b6c1 2018-08-07)"
[pkg.rustfmt-preview.target.aarch64-unknown-linux-gnu]
available = true
url = "https://static.rust-lang.org/dist/2018-09-03/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.gz"
hash = "cbb44cfb0148ec10335f312a74459c2874b2c2e65c11940cb762f55b75a846e1"
xz_url = "https://static.rust-lang.org/dist/2018-09-03/rustfmt-nightly-aarch64-unknown-linux-gnu.tar.xz"
xz_hash = "04afbca685b921b5bbbce9bce728430f410d4ebc293407893795acc9054dec2a"
[pkg.rustfmt-preview.target.x86_64-unknown-freebsd]
available = true
url = "https://static.rust-lang.org/dist/2018-09-03/rustfmt-nightly-x86_64-unknown-freebsd.tar.gz"
hash = "76566ab4d9373b3fe54466984aadebc89f1ce91c79c3e8fd60d559744af5b40c"
xz_url = "https://static.rust-lang.org/dist/2018-09-03/rustfmt-nightly-x86_64-unknown-freebsd.tar.xz"
xz_hash = "6aa97c093f923399b5b00dbc489120b6f1a225eb1e54e2cb3135ec7674aa1d48"
[pkg.rustfmt-preview.target.x86_64-unknown-linux-gnu]
available = true
url = "https://static.rust-lang.org/dist/2018-09-03/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.gz"
hash = "74b5d5ff8434c15359eccd15dfc097a1d9c7a3ac44a21718b2998e8cccc347a9"
xz_url = "https://static.rust-lang.org/dist/2018-09-03/rustfmt-nightly-x86_64-unknown-linux-gnu.tar.xz"
xz_hash = "85c786cfd3f7531a26e004819651da00540e24f83f5d8de0e3ab991730b4cc0d"
"#;
let _manifest: Manifest = toml::from_str(data).unwrap();
}
}