rsynko_memory/
processing.rs1use crate::ProcessingSyntax;
2use crate::{Artifact, ProcessingProgram, ProcessingStep, ProcessorId};
3use rsynko_media::*;
4use std::collections::BTreeMap;
5use thiserror::Error;
6
7#[derive(Clone, Debug, Default, PartialEq)]
9pub struct ArtifactSet(BTreeMap<String, Artifact>);
10
11impl ArtifactSet {
12 pub fn insert(&mut self, artifact: Artifact) -> Option<Artifact> {
14 self.0.insert(artifact.id.clone(), artifact)
15 }
16
17 #[must_use]
19 pub fn get(&self, id: &str) -> Option<&Artifact> {
20 self.0.get(id)
21 }
22
23 pub fn get_mut(&mut self, id: &str) -> Option<&mut Artifact> {
25 self.0.get_mut(id)
26 }
27
28 #[must_use]
30 pub fn len(&self) -> usize {
31 self.0.len()
32 }
33
34 #[must_use]
36 pub fn is_empty(&self) -> bool {
37 self.0.is_empty()
38 }
39}
40
41#[derive(Clone, Debug, PartialEq, Eq)]
43pub enum ReferenceArtifactTransform {
44 Identity,
46 Move {
48 artifact: String,
50 path: String,
52 },
53 Fail(String),
55}
56
57#[derive(Clone, Debug, PartialEq, Eq)]
59pub struct ReferenceProcessor {
60 id: ProcessorId,
61 transform: ReferenceArtifactTransform,
62}
63
64impl ReferenceProcessor {
65 #[must_use]
67 pub fn new(id: impl Into<String>, transform: ReferenceArtifactTransform) -> Self {
68 Self {
69 id: ProcessorId::new(id),
70 transform,
71 }
72 }
73}
74
75#[derive(Debug, Error, PartialEq, Eq)]
77pub enum ReferenceProcessingError {
78 #[error("unknown processor {0:?}")]
80 UnknownProcessor(ProcessorId),
81 #[error("processor {processor:?} failed: {message}")]
83 ProcessorFailed {
84 processor: ProcessorId,
86 message: String,
88 },
89}
90
91#[derive(Debug, Default)]
93pub struct ReferenceProcessorEnv {
94 artifacts: ArtifactSet,
95 processors: BTreeMap<ProcessorId, ReferenceProcessor>,
96 trace: Vec<ProcessingStep>,
97}
98
99impl ReferenceProcessorEnv {
100 #[must_use]
102 pub fn new(artifacts: ArtifactSet) -> Self {
103 Self {
104 artifacts,
105 processors: BTreeMap::default(),
106 trace: Vec::default(),
107 }
108 }
109
110 pub fn register(&mut self, processor: ReferenceProcessor) -> Option<ReferenceProcessor> {
112 self.processors.insert(processor.id.clone(), processor)
113 }
114
115 #[must_use]
117 pub fn artifacts(&self) -> &ArtifactSet {
118 &self.artifacts
119 }
120
121 #[must_use]
123 pub fn trace(&self) -> &[ProcessingStep] {
124 &self.trace
125 }
126}
127
128impl ProcessingSorts for ReferenceProcessorEnv {
129 type Processor = ();
130 type Step = ProcessingStep;
131 type Program = ProcessingProgram;
132}
133
134impl ProcessingApplyAlg for ReferenceProcessorEnv {
135 type Error = ReferenceProcessingError;
136
137 fn apply_processing_step(&mut self, step: &ProcessingStep) -> Result<(), Self::Error> {
138 let processor = self
139 .processors
140 .get(&step.processor)
141 .ok_or_else(|| ReferenceProcessingError::UnknownProcessor(step.processor.clone()))?;
142 match &processor.transform {
143 ReferenceArtifactTransform::Identity => {}
144 ReferenceArtifactTransform::Move { artifact, path } => {
145 let item = self.artifacts.get_mut(artifact).ok_or_else(|| {
146 ReferenceProcessingError::ProcessorFailed {
147 processor: step.processor.clone(),
148 message: format!("missing artifact {artifact}"),
149 }
150 })?;
151 item.metadata.insert(ARTIFACT_LOCATION, path.clone());
152 }
153 ReferenceArtifactTransform::Fail(message) => {
154 return Err(ReferenceProcessingError::ProcessorFailed {
155 processor: step.processor.clone(),
156 message: message.clone(),
157 });
158 }
159 }
160 self.trace.push(step.clone());
161 Ok(())
162 }
163}
164
165impl ProcessingProgramViewAlg for ReferenceProcessorEnv {
166 fn processing_steps<'a>(program: &'a Self::Program) -> impl Iterator<Item = &'a Self::Step>
167 where
168 Self::Step: 'a,
169 {
170 ProcessingSyntax::processing_steps(program)
171 }
172
173 fn processing_stage(step: &Self::Step) -> ProcessingStage {
174 ProcessingSyntax::processing_stage(step)
175 }
176}