use std::time::Duration;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use crate::Manifest;
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
pub struct PackageContract {
#[serde(serialize_with = "crate::canonical::serialize_value")]
pub input_schema: Value,
#[serde(serialize_with = "crate::canonical::serialize_value")]
pub output_schema: Value,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub workers: Vec<WorkerContract>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub children: Vec<ChildContract>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub signals: Vec<SignalContract>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub additional_workflows: Vec<AdditionalWorkflowContract>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub unscoped_activities: Vec<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub workloop: Option<WorkloopContract>,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct WorkloopContract {
#[serde(default, skip_serializing_if = "Option::is_none")]
pub cadence_seconds: Option<u64>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub arms: Vec<String>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub carries: Vec<CarryContract>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub invariants: Vec<InvariantContract>,
pub retention_seconds: u64,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub detached: Vec<DetachedContract>,
#[serde(default, skip_serializing_if = "Vec::is_empty")]
pub reports: Vec<ReportContract>,
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub has_retire_body: bool,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct CarryContract {
pub name: String,
#[serde(serialize_with = "crate::canonical::serialize_value")]
pub schema: Value,
#[serde(serialize_with = "crate::canonical::serialize_value")]
pub default: Value,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(tag = "form", rename_all = "snake_case")]
pub enum ToleranceContract {
Windows {
count: u64,
},
UnconfirmedFor {
seconds: u64,
},
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct InvariantContract {
pub name: String,
pub record_type: String,
#[serde(serialize_with = "crate::canonical::serialize_value")]
pub schema: Value,
pub tolerances: Vec<ToleranceContract>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub confirms: Option<String>,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct DetachedContract {
pub name: String,
#[serde(serialize_with = "crate::canonical::serialize_value")]
pub input_schema: Value,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct ReportContract {
pub name: String,
#[serde(serialize_with = "crate::canonical::serialize_value")]
pub schema: Value,
}
impl PackageContract {
#[must_use]
pub fn from_manifest(manifest: &Manifest) -> Self {
Self {
input_schema: manifest.input_schema.clone(),
output_schema: manifest.output_schema.clone(),
workers: Vec::new(),
children: Vec::new(),
signals: Vec::new(),
additional_workflows: manifest
.additional_workflows
.iter()
.map(|entry| AdditionalWorkflowContract {
workflow_type: entry.workflow_type.clone(),
input_schema: entry.input_schema.clone(),
output_schema: entry.output_schema.clone(),
})
.collect(),
unscoped_activities: manifest
.activities
.iter()
.map(|activity| activity.activity_type.clone())
.collect(),
workloop: None,
}
}
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct WorkerContract {
pub task_queue: String,
pub actions: Vec<ActionContract>,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct ActivityDescriptor {
pub name: String,
#[serde(serialize_with = "crate::canonical::serialize_value")]
pub input_schema: Value,
#[serde(serialize_with = "crate::canonical::serialize_value")]
pub output_schema: Value,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct ActionContract {
pub name: String,
#[serde(serialize_with = "crate::canonical::serialize_value")]
pub input_schema: Value,
#[serde(serialize_with = "crate::canonical::serialize_value")]
pub output_schema: Value,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub node: Option<String>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub timeout: Option<Duration>,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub retry: Option<RetryContract>,
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub advisory: bool,
#[serde(default, skip_serializing_if = "std::ops::Not::not")]
pub agent: bool,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub body: Option<ActionBodyContract>,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(tag = "kind", rename_all = "snake_case")]
pub enum ActionBodyContract {
Run {
command: String,
},
Command {
capture: CommandBodyCapture,
command: Box<crate::declared_command::DeclaredCommandContract>,
},
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum CommandBodyCapture {
Text,
Json,
}
impl ActionContract {
#[must_use]
pub fn worker_owed(&self) -> bool {
self.body.is_none()
}
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(tag = "kind", rename_all = "snake_case")]
pub enum RetryContract {
Every {
count: u64,
every: Duration,
},
Backoff {
count: u64,
min: Duration,
max: Duration,
},
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct ChildContract {
pub name: String,
#[serde(serialize_with = "crate::canonical::serialize_value")]
pub input_schema: Value,
#[serde(serialize_with = "crate::canonical::serialize_value")]
pub output_schema: Value,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct SignalContract {
pub name: String,
#[serde(serialize_with = "crate::canonical::serialize_value")]
pub input_schema: Value,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct AdditionalWorkflowContract {
pub workflow_type: String,
#[serde(serialize_with = "crate::canonical::serialize_value")]
pub input_schema: Value,
#[serde(serialize_with = "crate::canonical::serialize_value")]
pub output_schema: Value,
}