use std::path::PathBuf;
use indexmap::IndexMap;
use serde::{Deserialize, Serialize};
use super::WorkflowSchema;
use super::diagnose::*;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct IssueIntakeSchema {
pub pull: IssuePullSchema,
#[serde(flatten)]
unknown_fields: serde_yaml::Mapping,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct IssuePullSchema {
pub command: String,
#[serde(default = "default_idle_sec")]
pub idle_sec: u64,
#[serde(flatten)]
unknown_fields: serde_yaml::Mapping,
}
fn default_idle_sec() -> u64 {
5
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct IssueHandlingSchema {
#[serde(default)]
pub hooks: IssueHooks,
pub stages: IndexMap<String, IssueStage>,
#[serde(flatten)]
unknown_fields: serde_yaml::Mapping,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct IssueHooks {
pub after_create: Option<String>,
#[serde(flatten)]
unknown_fields: serde_yaml::Mapping,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct IssueStage {
pub when: IssueStageMatch,
pub agent: String,
pub prompt_file: PathBuf,
#[serde(default)]
pub hooks: IssueStageHooks,
#[serde(flatten)]
unknown_fields: serde_yaml::Mapping,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct IssueStageMatch {
pub state: String,
#[serde(flatten)]
unknown_fields: serde_yaml::Mapping,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct IssueStageHooks {
pub before_run: Option<String>,
pub after_run: Option<String>,
#[serde(flatten)]
unknown_fields: serde_yaml::Mapping,
}
impl Diagnose for IssueIntakeSchema {
fn diagnose(&self, schema: &WorkflowSchema) -> Diagnostics {
let mut diagnostics = Diagnostics::new();
diagnose_fields!(diagnostics, self, schema, "pull" => pull);
diagnostics.warn_unknown_fields(&self.unknown_fields);
diagnostics
}
}
impl Diagnose for IssuePullSchema {
fn diagnose(&self, _: &WorkflowSchema) -> Diagnostics {
let mut diagnostics = Diagnostics::new();
diagnostics.error_if_empty_str("command", &self.command);
diagnostics.error_if_non_positive("idle_sec", self.idle_sec as usize);
diagnostics.warn_unknown_fields(&self.unknown_fields);
diagnostics
}
}
impl Diagnose for IssueHandlingSchema {
fn diagnose(&self, schema: &WorkflowSchema) -> Diagnostics {
let mut diagnostics = Diagnostics::new();
diagnostics.error_if_empty_map("stages", self.stages.is_empty());
if !self.stages.is_empty() {
self.stages.iter().for_each(|(stage_name, stage)| {
diagnostics.extends_with_pointer(&format!("stages.{stage_name}"), stage.diagnose(schema));
});
}
diagnose_fields!(diagnostics, self, schema, "hooks" => hooks);
diagnostics.warn_unknown_fields(&self.unknown_fields);
diagnostics
}
}
impl Diagnose for IssueStage {
fn diagnose(&self, schema: &WorkflowSchema) -> Diagnostics {
let mut diagnostics = Diagnostics::new();
diagnose_fields!(
diagnostics,
self,
schema,
"when" => when,
"hooks" => hooks,
);
diagnostics.error_if_empty_str("agent", &self.agent);
if !self.agent.trim().is_empty() && !schema.agents.contains_key(&self.agent) {
diagnostics.push(Diagnostic::error(
"agent",
DiagnosticCode::UnknownAgent(self.agent.clone()),
));
}
diagnostics.error_if_empty_path("prompt_file", &self.prompt_file);
diagnostics.warn_unknown_fields(&self.unknown_fields);
diagnostics
}
}
impl Diagnose for IssueHooks {
fn diagnose(&self, _: &WorkflowSchema) -> Diagnostics {
let mut diagnostics = Diagnostics::new();
diagnostics.warn_unknown_fields(&self.unknown_fields);
diagnostics
}
}
impl Diagnose for IssueStageMatch {
fn diagnose(&self, _: &WorkflowSchema) -> Diagnostics {
let mut diagnostics = Diagnostics::new();
diagnostics.error_if_empty_str("state", &self.state);
diagnostics.warn_unknown_fields(&self.unknown_fields);
diagnostics
}
}
impl Diagnose for IssueStageHooks {
fn diagnose(&self, _: &WorkflowSchema) -> Diagnostics {
let mut diagnostics = Diagnostics::new();
diagnostics.warn_unknown_fields(&self.unknown_fields);
diagnostics
}
}