use std::{ collections::{hash_map, HashMap}, hash, rc::Rc, }; use enum_kinds::EnumKind; use serde::{Deserialize, Serialize}; #[derive(Debug, Serialize, PartialEq, Eq)] pub struct Platform { #[serde(skip)] pub short: String, pub gnu_triplet: String, pub karch: String, pub prefix: String, } #[derive(Debug, Serialize, PartialEq, Eq)] pub struct PlatformRelation { pub is_same: bool, pub sysroot: String, pub cross_compile: String, } #[derive(Clone, Debug, Serialize, PartialEq, Eq, EnumKind)] #[serde(untagged)] #[enum_kind(ArgType, derive(Deserialize), serde(rename_all = "snake_case"))] pub enum Arg { String(Rc), Platform(Rc), PlatformRelation(Rc), } impl From<&Arg> for Arg { fn from(value: &Arg) -> Self { value.clone() } } impl From for Arg { fn from(value: String) -> Self { Arg::String(Rc::new(value)) } } impl From for Arg { fn from(value: Platform) -> Self { Arg::Platform(Rc::new(value)) } } impl From for Arg { fn from(value: PlatformRelation) -> Self { Arg::PlatformRelation(Rc::new(value)) } } #[derive(Clone, Debug, Serialize, PartialEq, Eq, Default)] pub struct TaskArgs(HashMap); impl TaskArgs { pub fn contains_key(&self, key: &str) -> bool { self.0.contains_key(key) } pub fn get(&self, key: &str) -> Option<&Arg> { self.0.get(key) } pub fn set(&mut self, key: &str, value: Option) where T: Into, { if let Some(v) = value { self.0.insert(key.to_string(), v.into()); } else { self.0.remove(key); } } pub fn iter(&self) -> hash_map::Iter { self.into_iter() } } impl FromIterator<(String, Arg)> for TaskArgs { fn from_iter>(iter: T) -> Self { TaskArgs(HashMap::from_iter(iter)) } } impl<'a> IntoIterator for &'a TaskArgs { type Item = (&'a String, &'a Arg); type IntoIter = hash_map::Iter<'a, String, Arg>; fn into_iter(self) -> Self::IntoIter { self.0.iter() } } #[allow(clippy::derive_hash_xor_eq)] impl hash::Hash for TaskArgs { fn hash(&self, _state: &mut H) { // Don't do anything: Properly hashing the task args is likely to cost // much more performance than the hash collisions caused by TaskRefs // that only differ by the args } } pub fn arg>(key: &str, value: A) -> (String, Arg) { (key.to_string(), value.into()) } #[derive(Clone, Debug, Deserialize, Default, PartialEq, Eq)] pub struct ArgMapping(pub HashMap); #[allow(clippy::derive_hash_xor_eq)] impl hash::Hash for ArgMapping { fn hash(&self, _state: &mut H) {} }