ito_domain/changes/
mutations.rs1use std::io;
4
5use thiserror::Error;
6
7pub type ChangeArtifactMutationServiceResult<T> = Result<T, ChangeArtifactMutationError>;
9
10#[derive(Debug, Clone, PartialEq, Eq)]
12pub enum ChangeArtifactKind {
13 Proposal,
15 Design,
17 Tasks,
19 SpecDelta {
21 capability: String,
23 },
24}
25
26impl ChangeArtifactKind {
27 pub fn label(&self) -> String {
29 match self {
30 ChangeArtifactKind::Proposal => "proposal".to_string(),
31 ChangeArtifactKind::Design => "design".to_string(),
32 ChangeArtifactKind::Tasks => "tasks".to_string(),
33 ChangeArtifactKind::SpecDelta { capability } => format!("spec:{capability}"),
34 }
35 }
36}
37
38#[derive(Debug, Clone, PartialEq, Eq)]
40pub struct ChangeArtifactRef {
41 pub change_id: String,
43 pub artifact: ChangeArtifactKind,
45}
46
47impl ChangeArtifactRef {
48 pub fn label(&self) -> String {
50 format!("{}:{}", self.change_id, self.artifact.label())
51 }
52}
53
54#[derive(Debug, Clone, PartialEq, Eq)]
56pub struct ChangeArtifactMutationResult {
57 pub target: ChangeArtifactRef,
59 pub existed: bool,
61 pub revision: Option<String>,
63}
64
65#[derive(Debug, Error)]
67pub enum ChangeArtifactMutationError {
68 #[error("I/O failure while {context}: {source}")]
70 Io {
71 context: String,
73 #[source]
75 source: io::Error,
76 },
77
78 #[error("{0}")]
80 Validation(String),
81
82 #[error("{0}")]
84 NotFound(String),
85
86 #[error("{0}")]
88 Other(String),
89}
90
91impl ChangeArtifactMutationError {
92 pub fn io(context: impl Into<String>, source: io::Error) -> Self {
94 Self::Io {
95 context: context.into(),
96 source,
97 }
98 }
99
100 pub fn validation(message: impl Into<String>) -> Self {
102 Self::Validation(message.into())
103 }
104
105 pub fn not_found(message: impl Into<String>) -> Self {
107 Self::NotFound(message.into())
108 }
109
110 pub fn other(message: impl Into<String>) -> Self {
112 Self::Other(message.into())
113 }
114}
115
116pub trait ChangeArtifactMutationService: Send + Sync {
118 fn load_artifact(
120 &self,
121 target: &ChangeArtifactRef,
122 ) -> ChangeArtifactMutationServiceResult<Option<String>>;
123
124 fn write_artifact(
126 &self,
127 target: &ChangeArtifactRef,
128 content: &str,
129 ) -> ChangeArtifactMutationServiceResult<ChangeArtifactMutationResult>;
130
131 fn patch_artifact(
133 &self,
134 target: &ChangeArtifactRef,
135 patch: &str,
136 ) -> ChangeArtifactMutationServiceResult<ChangeArtifactMutationResult>;
137}