credence_lib/render/
annotations.rs1use super::{
2 super::{configuration::*, resolve::*},
3 renderer::*,
4};
5
6use {
7 compris::{annotate::*, normal::*, parse::Parser, resolve::*, *},
8 kutil::std::{collections::*, immutable::*, string::*},
9};
10
11#[derive(Clone, Debug, Default, Resolve)]
17pub struct Annotations {
18 #[resolve]
20 pub created: Option<ResolveDateTime>,
21
22 #[resolve]
24 pub updated: Option<ResolveDateTime>,
25
26 #[resolve]
28 pub renderer: Option<Renderer>,
29
30 #[resolve]
32 pub template: Option<ByteString>,
33
34 #[resolve]
36 pub variables: FastHashMap<ByteString, Variant<WithAnnotations>>,
37
38 #[resolve]
40 pub headers: FastHashMap<ByteString, ByteString>,
41
42 #[resolve(other_keys)]
44 pub other: FastHashMap<ByteString, Variant<WithAnnotations>>,
45}
46
47impl Annotations {
48 pub fn renderer(&self, configuration: &RenderConfiguration) -> Renderer {
50 self.renderer.clone().unwrap_or(configuration.default_renderer)
51 }
52
53 pub fn template<'own>(&'own self, configuration: &'own RenderConfiguration) -> &'own str {
55 self.template.as_ref().unwrap_or(&configuration.default_template)
56 }
57
58 pub fn parse(identifier: &str, representation: &str, format: Format) -> Self {
60 match Parser::new(format).with_try_unsigned_integers(true).parse_string::<WithAnnotations>(representation) {
61 Ok(annotations) => match annotations.resolve() {
62 Ok(annotations) => {
63 return annotations;
64 }
65
66 Err(ResolveError::Missing) => {}
67
68 Err(error) => tracing::error!("{}: {}", identifier, error),
69 },
70
71 Err(error) => tracing::error!("{}: {}", identifier, error),
72 }
73
74 Self::default()
75 }
76
77 pub fn traverse_variable(&self, keys: &RefTraversal<'_, WithAnnotations>) -> Option<&Variant<WithAnnotations>> {
79 if !keys.is_empty() {
80 if let Variant::Text(first_key) = &keys[0]
81 && let Some(first_value) = self.variables.get(&first_key.inner)
82 {
83 let keys = keys[1..].iter().map(|variant| *variant);
84 return first_value.traverse(keys);
85 }
86 }
87
88 None
89 }
90}
91
92impl AnnotationsConfiguration {
93 pub fn split<'content>(&self, identifier: &str, content: &'content str) -> (Annotations, &'content str) {
95 let start_delimiter: &str = &self.start_delimiter;
96 if content.starts_with(start_delimiter) {
97 let end_delimiter: &str = &self.end_delimiter;
98 if let Some((properties, content)) =
99 content[start_delimiter.len()..].split_once_ignore_escaped(end_delimiter)
100 {
101 let annotations = properties.unescape(end_delimiter);
103 let mut annotations = annotations.as_str();
104
105 let format = {
106 match annotations.split_once('\n') {
108 Some((format, annotations_after_format)) => {
109 let format_result = format.parse();
110 annotations = annotations_after_format;
111 format_result.unwrap_or(self.default_format.inner.into())
112 }
113
114 None => self.default_format.inner.into(),
115 }
116 };
117
118 let annotations = Annotations::parse(identifier, annotations, format);
119 return (annotations, content);
120 }
121 }
122
123 (Default::default(), content)
124 }
125}