moduforge_transform/
transform.rs1use std::{fmt, sync::Arc};
2
3use moduforge_model::{node_pool::NodePool, schema::Schema, tree::Tree};
4
5use super::step::{Step, StepResult};
6
7#[derive(Debug)]
9pub struct TransformError {
10    message: String,
11}
12impl fmt::Display for TransformError {
13    fn fmt(
14        &self,
15        f: &mut fmt::Formatter,
16    ) -> fmt::Result {
17        write!(f, "{}", self.message)
18    }
19}
20impl std::error::Error for TransformError {}
21
22impl TransformError {
23    pub fn new(message: String) -> Self {
24        TransformError { message }
25    }
26}
27#[derive(Debug, Clone)]
28pub struct Transform {
29    pub doc: Arc<NodePool>,
31    pub draft: Tree,
33    pub steps: im::Vector<Arc<dyn Step>>,
35    pub schema: Arc<Schema>,
37}
38impl Transform {
39    pub fn new(
40        doc: Arc<NodePool>,
41        schema: Arc<Schema>,
42    ) -> Transform {
43        Transform {
44            doc: doc.clone(),
45            draft: doc.get_inner().as_ref().clone(),
46            steps: im::Vector::new(),
47            schema,
48        }
49    }
50    pub fn step(
51        &mut self,
52        step: Arc<dyn Step>,
53    ) -> Result<(), TransformError> {
54        let result: StepResult =
55            step.apply(&mut self.draft, self.schema.clone())?;
56        match result.failed {
57            Some(message) => Err(TransformError::new(message)),
58            None => {
59                self.add_step(step);
60                Ok(())
61            },
62        }
63    }
64    pub fn doc_changed(&self) -> bool {
66        !self.steps.is_empty()
67    }
68    fn add_step(
70        &mut self,
71        step: Arc<dyn Step>,
72    ) {
73        self.steps.push_back(step);
74        self.doc = NodePool::new(Arc::new(self.draft.clone()));
75    }
76}