diff --git a/flake-info/src/data/export.rs b/flake-info/src/data/export.rs index 22efebe..ee21b11 100644 --- a/flake-info/src/data/export.rs +++ b/flake-info/src/data/export.rs @@ -202,19 +202,11 @@ impl TryFrom for Derivation { .map(|l: &License| l.fullName.to_owned()) .collect(); - let platforms: HashSet = package - .meta - .platforms - .map_or(Default::default(), Flatten::flatten) - .into_iter() - .collect(); + let platforms: HashSet = + package.meta.platforms.unwrap_or_default().collect(); - let bad_platforms: HashSet = package - .meta - .bad_platforms - .map_or(Default::default(), Flatten::flatten) - .into_iter() - .collect(); + let bad_platforms: HashSet = + package.meta.bad_platforms.unwrap_or_default().collect(); let platforms: Vec = platforms.difference(&bad_platforms).cloned().collect(); diff --git a/flake-info/src/data/import.rs b/flake-info/src/data/import.rs index eef11b3..7a7de78 100644 --- a/flake-info/src/data/import.rs +++ b/flake-info/src/data/import.rs @@ -188,9 +188,9 @@ pub struct Meta { pub license: Option>>, pub maintainers: Option>, pub homepage: Option>, - pub platforms: Option>, + pub platforms: Option, #[serde(rename = "badPlatforms")] - pub bad_platforms: Option>, + pub bad_platforms: Option, pub position: Option, pub description: Option, #[serde(rename = "longDescription")] @@ -252,6 +252,36 @@ where } } +#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] +#[serde(untagged)] +pub enum Platform { + System(String), + Pattern {}, // TODO how should those be displayed? +} + +#[derive(Debug, Clone, PartialEq, Default, Serialize, Deserialize)] +pub struct Platforms(Flatten); + +impl Platforms { + // A bit of abstract nonsense: what we really want is + // into_iter : Platforms → ∃ (I : Iterator). I + // however Rust makes this annoying to write: we would either have to pick a + // concrete iterator type or use something like Box>. + // Instead, we can use the dual Church-encoded form of that existential type: + // ? : Platforms → ∀ B. (∀ (I : Iterator). I → B) → B + // ...which is exactly the type of collect! (think about what FromIterator means) + pub fn collect>(self) -> B { + self.0 + .flatten() + .into_iter() + .flat_map(|p| match p { + Platform::System(s) => Some(s), + _ => None, + }) + .collect() + } +} + /// Different representations of the licence attribute #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] #[serde(untagged)] @@ -388,7 +418,8 @@ mod tests { "powerpc64-linux", "powerpc64le-linux", "riscv32-linux", - "riscv64-linux" + "riscv64-linux", + {} ], "position": "/nix/store/97lxf2n6zip41j5flbv6b0928mxv9za8-nixpkgs-unstable-21.03pre268853.d9c6f13e13f/nixpkgs-unstable/pkgs/games/0verkill/default.nix:34", "unfree": false, diff --git a/flake-info/src/data/utility.rs b/flake-info/src/data/utility.rs index 782b1bd..0db3295 100644 --- a/flake-info/src/data/utility.rs +++ b/flake-info/src/data/utility.rs @@ -39,6 +39,12 @@ impl Flatten { } } +impl Default for Flatten { + fn default() -> Self { + Flatten::Deep(Vec::new()) + } +} + // TODO: use this or a to_ist function? /// Serialization helper that serializes single elements as a list with a single /// item