use super::SymbolTable;
use super::ids::{ActId, ArtifactId, MaterialId, OutputId, ParamId, RoleId, SectionId, StepId};
use crate::expression::ExprValue;
use crate::material::MaterialSource;
use crate::types::{ActionType, DutyType, Metadata, OutputType, ParameterType};
use rite_sdk::BackendConfig;
use std::collections::HashMap;
#[derive(Debug, Clone)]
pub struct Ceremony {
pub metadata: Metadata,
pub roles: SymbolTable<RoleId, Role>,
pub acts: SymbolTable<ActId, Act>,
pub sections: SymbolTable<SectionId, Section>,
pub parameters: SymbolTable<ParamId, Parameter>,
pub materials: SymbolTable<MaterialId, Material>,
pub prerequisites: Vec<String>,
pub outputs: SymbolTable<OutputId, Output>,
pub backends: HashMap<String, BackendConfig>,
pub execution_plan: Vec<Step>,
pub after: Vec<PostCeremonyDuty>,
}
#[derive(Debug, Clone)]
pub struct Role {
pub id: RoleId,
pub name: String,
pub role_type: String,
pub person: Option<String>,
}
#[derive(Debug, Clone)]
pub struct Act {
pub id: ActId,
pub name: Option<String>,
pub description: Option<String>,
}
#[derive(Debug, Clone)]
pub struct Section {
pub id: SectionId,
pub act: Option<ActId>,
pub name: Option<String>,
pub description: Option<String>,
pub default_role: Option<RoleId>,
}
#[derive(Debug, Clone)]
pub struct Step {
pub id: StepId,
pub step_label: String,
pub section: SectionId,
pub action: ActionType,
pub backend: Option<String>,
pub role: Option<RoleId>,
pub preconditions: Vec<String>,
pub with: ExprValue,
pub reads: Vec<ArtifactRef>,
pub reads_resolved: Option<StepInputs>,
pub creates: Option<ArtifactId>,
pub description: Option<ExprValue>,
pub silent: bool,
pub retry: RetryPolicy,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum RetryPolicy {
#[default]
Prompt,
Never,
MaxAttempts(u32),
}
#[derive(Debug, Clone)]
pub struct Parameter {
pub id: ParamId,
pub declared_type: ParameterType,
pub value: serde_json::Value,
pub description: Option<String>,
}
#[derive(Debug, Clone)]
pub enum MaterialKind {
Digital {
source: Option<MaterialSource>,
},
Physical {
identifier: Option<String>,
quantity: Option<u32>,
},
}
#[derive(Debug, Clone)]
pub struct Material {
pub id: MaterialId,
pub kind: MaterialKind,
pub title: Option<String>,
pub description: Option<String>,
}
impl Material {
pub fn display_name(&self) -> &str {
self.title.as_deref().unwrap_or(self.id.as_str())
}
pub fn is_digital(&self) -> bool {
matches!(self.kind, MaterialKind::Digital { .. })
}
pub fn is_physical(&self) -> bool {
matches!(self.kind, MaterialKind::Physical { .. })
}
}
#[derive(Debug, Clone)]
pub struct PostCeremonyDuty {
pub id: String,
pub kind: DutyType,
pub role: Option<RoleId>,
pub description: Option<String>,
pub items: Vec<String>,
pub recipient: Option<String>,
pub location: Option<String>,
}
#[derive(Debug, Clone)]
pub struct Output {
pub id: OutputId,
pub kind: OutputType,
pub description: Option<String>,
}
#[derive(Debug, Clone)]
pub enum ArtifactRef {
Material {
id: MaterialId,
property: Option<String>,
},
Produced {
id: ArtifactId,
property: Option<String>,
},
}
impl ArtifactRef {
pub fn display_name(&self) -> String {
match self {
ArtifactRef::Material { id, property: None } => id.to_string(),
ArtifactRef::Material {
id,
property: Some(p),
} => format!("{id}.{p}"),
ArtifactRef::Produced { id, property: None } => id.to_string(),
ArtifactRef::Produced {
id,
property: Some(p),
} => format!("{id}.{p}"),
}
}
pub fn artifact_id(&self) -> ArtifactId {
match self {
ArtifactRef::Material { id, .. } => ArtifactId::new(id.as_str()),
ArtifactRef::Produced { id, .. } => id.clone(),
}
}
pub fn property(&self) -> Option<&str> {
match self {
ArtifactRef::Material { property, .. } | ArtifactRef::Produced { property, .. } => {
property.as_deref()
}
}
}
}
#[derive(Debug, Clone)]
pub enum StepInputs {
Single(ArtifactRef),
Named(HashMap<String, ArtifactRef>),
}
impl StepInputs {
pub fn as_single(&self) -> Option<&ArtifactRef> {
match self {
StepInputs::Single(r) => Some(r),
StepInputs::Named(_) => None,
}
}
pub fn as_named(&self) -> Option<&HashMap<String, ArtifactRef>> {
match self {
StepInputs::Single(_) => None,
StepInputs::Named(m) => Some(m),
}
}
pub fn get(&self, key: &str) -> Option<&ArtifactRef> {
match self {
StepInputs::Single(_) => None,
StepInputs::Named(m) => m.get(key),
}
}
}