ephemeris_documents/
backend.rs1use std::fmt;
4
5use crate::annotation::Annotated;
6use crate::error::{DocumentError, MergeError};
7use crate::format::Format;
8use crate::header::{Applied, Existing, Header};
9use crate::merge::{Node, merge};
10use crate::ownership::Ownership;
11use crate::source::Source;
12
13pub(crate) trait Editable {
15 type Node: Node;
16
17 fn apply_header(&mut self, desired: &Self, existing: Existing) {
20 let header = Header::new(desired.header_text());
21 let (root, first) = self.leading();
22 let applied = header
23 .applied_to_parts(root, first, existing)
24 .map(Applied::into_owned);
25 if let Some(applied) = applied {
26 self.set_leading(applied);
27 }
28 }
29
30 fn header_text(&self) -> &str;
32
33 fn leading(&self) -> (&str, &str);
37
38 fn root(&self) -> &Self::Node;
40
41 fn root_mut(&mut self) -> &mut Self::Node;
43
44 fn set_leading(&mut self, applied: Applied<'_>);
46}
47
48pub(crate) type NodeOf<B> = <<B as Backend>::Document as Editable>::Node;
50
51pub(crate) trait Backend {
53 type Document: fmt::Display + Editable;
54
55 fn build(&self, desired: &Annotated) -> Result<Self::Document, DocumentError>;
60
61 fn descend<'n>(
67 &self,
68 node: &'n NodeOf<Self>,
69 key: &str,
70 _path: &[String],
71 ) -> Result<Option<&'n NodeOf<Self>>, DocumentError> {
72 Ok(node.child(key))
73 }
74
75 fn explain(&self, _current: &Self::Document, error: MergeError) -> DocumentError {
78 DocumentError::Merge(error)
79 }
80
81 fn finish(&self, current: &mut Self::Document, desired: &Self::Document, existing: Existing);
83
84 fn format(&self) -> Format;
86
87 fn parse(&self, source: &str) -> Result<Self::Document, DocumentError>;
92
93 fn read_string(&self, source: &str, path: &[String]) -> Result<Option<String>, DocumentError> {
100 let document = self.parse(source)?;
101 let mut node = document.root();
102 for (index, key) in path.iter().enumerate() {
103 match self.descend(node, key, path.get(..index).unwrap_or_default())? {
104 Some(child) => node = child,
105 None => return Ok(None),
106 }
107 }
108 self.string_leaf(node)?
109 .map(Some)
110 .ok_or_else(|| DocumentError::not_string(path))
111 }
112
113 fn reconcile(
122 &self,
123 desired: &Annotated,
124 source: &Source<'_>,
125 ownership: &Ownership,
126 ) -> Result<Vec<u8>, DocumentError> {
127 desired.validate(self.format())?;
128 let mut desired = self.build(desired)?;
129 let mut document = self.parse(source.text().unwrap_or_default())?;
130 merge(document.root_mut(), &*desired.root_mut(), ownership)
131 .map_err(|error| self.explain(&document, error))?;
132 self.finish(&mut document, &desired, Existing::under(ownership));
133 Ok(source.write(&document))
134 }
135
136 fn string_leaf(&self, node: &NodeOf<Self>) -> Result<Option<String>, DocumentError>;
142}