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 { id: ProcessorId::new(id), transform }
69 }
70}
71
72#[derive(Debug, Error, PartialEq, Eq)]
74pub enum ReferenceProcessingError {
75 #[error("unknown processor {0:?}")]
77 UnknownProcessor(ProcessorId),
78 #[error("processor {processor:?} failed: {message}")]
80 ProcessorFailed {
81 processor: ProcessorId,
83 message: String,
85 },
86}
87
88#[derive(Debug, Default)]
90pub struct ReferenceProcessorEnv {
91 artifacts: ArtifactSet,
92 processors: BTreeMap<ProcessorId, ReferenceProcessor>,
93 trace: Vec<ProcessingStep>,
94}
95
96impl ReferenceProcessorEnv {
97 #[must_use]
99 pub fn new(artifacts: ArtifactSet) -> Self {
100 Self { artifacts, processors: BTreeMap::default(), trace: Vec::default() }
101 }
102
103 pub fn register(&mut self, processor: ReferenceProcessor) -> Option<ReferenceProcessor> {
105 self.processors.insert(processor.id.clone(), processor)
106 }
107
108 #[must_use]
110 pub fn artifacts(&self) -> &ArtifactSet {
111 &self.artifacts
112 }
113
114 #[must_use]
116 pub fn trace(&self) -> &[ProcessingStep] {
117 &self.trace
118 }
119}
120
121impl ProcessingSorts for ReferenceProcessorEnv {
122 type Processor = ();
123 type Step = ProcessingStep;
124 type Program = ProcessingProgram;
125}
126
127impl ProcessingApplyAlg for ReferenceProcessorEnv {
128 type Error = ReferenceProcessingError;
129
130 fn apply_processing_step(&mut self, step: &ProcessingStep) -> Result<(), Self::Error> {
131 let processor = self
132 .processors
133 .get(&step.processor)
134 .ok_or_else(|| ReferenceProcessingError::UnknownProcessor(step.processor.clone()))?;
135 match &processor.transform {
136 ReferenceArtifactTransform::Identity => {}
137 ReferenceArtifactTransform::Move { artifact, path } => {
138 let item =
139 self.artifacts.get_mut(artifact).ok_or_else(|| ReferenceProcessingError::ProcessorFailed {
140 processor: step.processor.clone(),
141 message: format!("missing artifact {artifact}"),
142 })?;
143 item.metadata.insert(ARTIFACT_LOCATION, path.clone());
144 }
145 ReferenceArtifactTransform::Fail(message) => {
146 return Err(ReferenceProcessingError::ProcessorFailed {
147 processor: step.processor.clone(),
148 message: message.clone(),
149 });
150 }
151 }
152 self.trace.push(step.clone());
153 Ok(())
154 }
155}
156
157impl ProcessingProgramViewAlg for ReferenceProcessorEnv {
158 fn processing_steps<'a>(program: &'a Self::Program) -> impl Iterator<Item = &'a Self::Step>
159 where
160 Self::Step: 'a,
161 {
162 ProcessingSyntax::processing_steps(program)
163 }
164
165 fn processing_stage(step: &Self::Step) -> ProcessingStage {
166 ProcessingSyntax::processing_stage(step)
167 }
168}