summaryrefslogtreecommitdiffstats
path: root/src/package/dependency/condition.rs
diff options
context:
space:
mode:
authorMatthias Beyer <matthias.beyer@atos.net>2021-06-25 16:46:06 +0200
committerMatthias Beyer <matthias.beyer@atos.net>2021-09-16 12:28:09 +0200
commit288b7860b2d216f5aefce252b3fe51928325ff33 (patch)
treee2c7ab105c5e1e46820b926b1a132b7d96657e4e /src/package/dependency/condition.rs
parent1d7dd070642bc826dca28bf22f70bd967775413b (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/dependency/condition.rs')
-rw-r--r--src/package/dependency/condition.rs120
1 files changed, 120 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")]));
+ }
+
+}