diff options
author | Matthias Beyer <matthias.beyer@atos.net> | 2021-06-25 16:46:06 +0200 |
---|---|---|
committer | Matthias Beyer <matthias.beyer@atos.net> | 2021-09-16 12:28:09 +0200 |
commit | 288b7860b2d216f5aefce252b3fe51928325ff33 (patch) | |
tree | e2c7ab105c5e1e46820b926b1a132b7d96657e4e /src/package | |
parent | 1d7dd070642bc826dca28bf22f70bd967775413b (diff) |
Add types for conditional dependencies
This patch adds the first implementation for conditional dependencies in the
dependency fields (that is the "build" and "runtime" keys in the package
defintion).
This is only the deserialization-interface, not the actual condition resolving
code.
Signed-off-by: Matthias Beyer <matthias.beyer@atos.net>
Diffstat (limited to 'src/package')
-rw-r--r-- | src/package/dependency/condition.rs | 120 | ||||
-rw-r--r-- | src/package/dependency/mod.rs | 2 |
2 files changed, 122 insertions, 0 deletions
diff --git a/src/package/dependency/condition.rs b/src/package/dependency/condition.rs new file mode 100644 index 0000000..df65a5c --- /dev/null +++ b/src/package/dependency/condition.rs @@ -0,0 +1,120 @@ +// +// Copyright (c) 2020-2021 science+computing ag and other contributors +// +// This program and the accompanying materials are made +// available under the terms of the Eclipse Public License 2.0 +// which is available at https://www.eclipse.org/legal/epl-2.0/ +// +// SPDX-License-Identifier: EPL-2.0 +// + +use std::collections::HashMap; + +use serde::Deserialize; + +use crate::util::EnvironmentVariableName; + +/// The Condition type +/// +/// This type represents a condition whether a dependency should be included in the package tree or +/// not. +/// +/// Right now, we are supporting condition by environment (set or equal) or whether a specific +/// build image is used. +/// All these settings are optional, of course. +/// +#[derive(Deserialize, Clone, Debug)] +pub struct Condition { + #[serde(rename = "has_env", skip_serializing_if = "Option::is_none")] + has_env: Option<OneOrMore<EnvironmentVariableName>>, + + #[serde(rename = "env_eq", skip_serializing_if = "Option::is_none")] + env_eq: Option<HashMap<EnvironmentVariableName, String>>, + + #[serde(rename = "in_image", skip_serializing_if = "Option::is_none")] + in_image: Option<OneOrMore<String>>, +} + + +/// Helper type for supporting Vec<T> and T in value +/// position of Condition +#[cfg_attr(test, derive(Eq, PartialEq))] +#[derive(Deserialize, Clone, Debug)] +#[serde(untagged)] +pub enum OneOrMore<T: Sized> { + One(T), + More(Vec<T>), +} + +impl<T: Sized> Into<Vec<T>> for OneOrMore<T> { + fn into(self) -> Vec<T> { + match self { + OneOrMore::One(o) => vec![o], + OneOrMore::More(m) => m, + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_has_env_deserialization() { + let s = r#"has_env = "foo""#; + let c: Condition = toml::from_str(s).expect("Deserializing has_env"); + + assert_eq!(c.has_env.unwrap(), OneOrMore::<EnvironmentVariableName>::One(EnvironmentVariableName::from("foo"))); + assert!(c.env_eq.is_none()); + assert!(c.in_image.is_none()); + } + + #[test] + fn test_has_env_list_deserialization() { + let s = r#"has_env = ["foo", "bar"]"#; + let c: Condition = toml::from_str(s).expect("Deserializing has_env"); + + assert_eq!(c.has_env.unwrap(), { + OneOrMore::<EnvironmentVariableName>::More({ + vec![EnvironmentVariableName::from("foo"), EnvironmentVariableName::from("bar")] + }) + }); + assert!(c.env_eq.is_none()); + assert!(c.in_image.is_none()); + } + + #[test] + fn test_env_eq_deserialization() { + let s = r#"env_eq = { "foo" = "bar" }"#; + let c: Condition = toml::from_str(s).expect("Deserializing has_env"); + + assert!(c.has_env.is_none()); + assert_eq!(c.env_eq.unwrap(), { + let mut hm = HashMap::new(); + hm.insert(EnvironmentVariableName::from("foo"), String::from("bar")); + hm + }); + assert!(c.in_image.is_none()); + } + + #[test] + fn test_in_image_deserialization() { + let s = r#"in_image = "foo""#; + let c: Condition = toml::from_str(s).expect("Deserializing has_env"); + + assert!(c.has_env.is_none()); + assert!(c.env_eq.is_none()); + assert_eq!(c.in_image.unwrap(), OneOrMore::<String>::One(String::from("foo"))); + } + + #[test] + fn test_in_image_list_deserialization() { + let s = r#"in_image = ["foo"]"#; + let c: Condition = toml::from_str(s).expect("Deserializing has_env"); + + assert!(c.has_env.is_none()); + assert!(c.env_eq.is_none()); + assert_eq!(c.in_image.unwrap(), OneOrMore::<String>::More(vec![String::from("foo")])); + } + +} diff --git a/src/package/dependency/mod.rs b/src/package/dependency/mod.rs index 37cb82b..8195dd1 100644 --- a/src/package/dependency/mod.rs +++ b/src/package/dependency/mod.rs @@ -24,6 +24,8 @@ pub use build::*; mod runtime; pub use runtime::*; +mod condition; + pub trait StringEqual { fn str_equal(&self, s: &str) -> bool; } |