diff --git a/workspace/gh-workflow/src/workflow.rs b/workspace/gh-workflow/src/workflow.rs index ed5e7af..fa30929 100644 --- a/workspace/gh-workflow/src/workflow.rs +++ b/workspace/gh-workflow/src/workflow.rs @@ -5,7 +5,7 @@ use std::fmt::Display; use derive_setters::Setters; use indexmap::IndexMap; use serde::{Deserialize, Serialize}; -use serde_json::Value; +use serde_json::{Map, Value}; use crate::error::Result; use crate::generate::Generate; @@ -128,6 +128,10 @@ pub enum ActivityType { Deleted, } +#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, Default)] +#[serde(transparent)] +pub struct RunsOn(Value); + #[derive(Debug, Setters, Serialize, Deserialize, Clone, PartialEq, Eq, Default)] #[serde(rename_all = "kebab-case")] #[setters(strip_option)] @@ -140,7 +144,7 @@ pub struct Job { pub name: Option, #[serde(skip_serializing_if = "Option::is_none")] #[setters(skip)] - pub runs_on: Option, + pub runs_on: Option, #[serde(skip_serializing_if = "Option::is_none")] pub strategy: Option, #[serde(skip_serializing_if = "Option::is_none")] @@ -178,7 +182,7 @@ impl Job { pub fn new(name: T) -> Self { Self { name: Some(name.to_string()), - runs_on: Some(Value::from("ubuntu-latest")), + runs_on: Some(RunsOn(Value::from("ubuntu-latest"))), ..Default::default() } } @@ -187,7 +191,7 @@ impl Job { step.apply(self) } - pub fn runs_on>(self, a: T) -> Self { + pub fn runs_on(self, a: T) -> Self { a.apply(self) } @@ -196,7 +200,42 @@ impl Job { } } -impl> SetRunner for T { +pub trait AddRunsOn { + fn apply(self, job: Job) -> Job; +} + +impl From<&str> for RunsOn { + fn from(value: &str) -> Self { + RunsOn(Value::String(value.to_string())) + } +} + +impl From> for RunsOn { + fn from(value: Vec<&str>) -> Self { + RunsOn(Value::Array( + value + .into_iter() + .map(|v| v.to_string()) + .map(Value::String) + .collect(), + )) + } +} + +impl> AddRunsOn for Vec<(&str, V)> { + fn apply(self, mut job: Job) -> Job { + let val = self.into_iter().map(|(a, b)| (a.to_string(), b.into())); + let mut map = Map::new(); + for (k, v) in val { + map.insert(k.to_string(), v.0); + } + + job.runs_on = Some(RunsOn(Value::Object(map))); + job + } +} + +impl> AddRunsOn for V { fn apply(self, mut job: Job) -> Job { job.runs_on = Some(self.into()); job