redact_composer_core/render/
mod.rs1pub mod context;
3
4pub mod tree;
6
7use crate::error::RendererError;
8
9use std::fmt::Formatter;
10use std::iter::successors;
11use std::ops::Deref;
12use std::{any::TypeId, collections::HashMap, fmt::Debug, ops::Add};
13use Vec;
14
15use crate::{Element, Segment, SegmentRef};
16
17#[cfg(feature = "serde")]
18use serde::{Deserialize, Serialize};
19
20use crate::render::context::CompositionContext;
21
22pub type Result<T, E = RendererError> = std::result::Result<T, E>;
24
25pub trait Renderer {
33 type Element: Element;
35
36 fn render(
39 &self,
40 segment: SegmentRef<Self::Element>,
41 context: CompositionContext,
42 ) -> Result<Vec<Segment>>;
43}
44
45#[derive(Debug)]
47#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
48pub struct RenderSegment {
49 #[cfg_attr(feature = "serde", serde(flatten))]
51 pub segment: Segment,
52 pub seed: u64,
54 pub rendered: bool,
56 #[cfg_attr(feature = "serde", serde(skip_serializing_if = "Option::is_none"))]
58 pub error: Option<RendererError>,
59}
60
61#[allow(missing_debug_implementations)] pub struct AdhocRenderer<T: Element> {
82 #[allow(clippy::type_complexity)]
85 func: Box<dyn Fn(SegmentRef<T>, CompositionContext) -> Result<Vec<Segment>>>,
86}
87
88impl<T: Element> AdhocRenderer<T> {
89 pub fn new(
91 func: impl Fn(SegmentRef<T>, CompositionContext) -> Result<Vec<Segment>> + 'static,
92 ) -> AdhocRenderer<T> {
93 AdhocRenderer {
94 func: Box::new(func),
95 }
96 }
97}
98
99impl<T: Element> Renderer for AdhocRenderer<T> {
100 type Element = T;
101
102 fn render(
104 &self,
105 segment: SegmentRef<Self::Element>,
106 context: CompositionContext,
107 ) -> Result<Vec<Segment>> {
108 (self.func)(segment, context)
109 }
110}
111
112#[allow(missing_debug_implementations)] pub struct RendererGroup<T> {
117 pub renderers: Vec<Box<dyn Renderer<Element = T>>>,
119}
120
121impl<T> RendererGroup<T> {
122 pub fn new() -> RendererGroup<T> {
124 RendererGroup { renderers: vec![] }
125 }
126}
127
128impl<T> Default for RendererGroup<T> {
129 fn default() -> Self {
130 RendererGroup::new()
131 }
132}
133
134impl<T, R> Add<R> for RendererGroup<T>
135where
136 R: Renderer<Element = T> + 'static,
137{
138 type Output = Self;
139
140 fn add(mut self, rhs: R) -> Self::Output {
141 self.renderers.push(Box::new(rhs));
142
143 self
144 }
145}
146
147impl<T: Element> Renderer for RendererGroup<T> {
148 type Element = T;
149
150 fn render(
151 &self,
152 segment: SegmentRef<Self::Element>,
153 context: CompositionContext,
154 ) -> Result<Vec<Segment>> {
155 let mut result_children = vec![];
156
157 for renderer in &self.renderers {
158 result_children.append(&mut renderer.render(segment, context)?);
159 }
160
161 Ok(result_children)
162 }
163}
164
165trait ErasedRenderer {
166 fn render(&self, segment: &Segment, context: CompositionContext) -> Result<Vec<Segment>>;
167}
168
169impl<T: Renderer> ErasedRenderer for T {
170 fn render(&self, segment: &Segment, context: CompositionContext) -> Result<Vec<Segment>> {
171 self.render(segment.try_into()?, context)
172 }
173}
174
175#[allow(missing_debug_implementations)] #[derive(Default)]
180pub struct RenderEngine {
181 renderers: HashMap<TypeId, Box<dyn ErasedRenderer>>,
182}
183
184impl Debug for RenderEngine {
185 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
186 write!(f, "RenderEngine {{ /* TODO */ }}")
188 }
189}
190
191impl RenderEngine {
192 pub fn new() -> RenderEngine {
194 RenderEngine {
195 renderers: HashMap::new(),
196 }
197 }
198
199 pub fn add_renderer<R: Renderer + 'static>(&mut self, renderer: R) {
202 self.renderers
203 .insert(TypeId::of::<R::Element>(), Box::new(renderer));
204 }
205
206 fn renderer_for(&self, element: &dyn Element) -> Option<&dyn ErasedRenderer> {
208 self.renderers
209 .get(&element.as_any().type_id())
210 .map(Box::deref)
211 }
212
213 pub fn can_render(&self, element: &dyn Element) -> bool {
218 successors(Some(element), |&s| s.wrapped_element()).any(|s| self.can_render_specific(s))
219 }
220
221 pub fn can_render_specific(&self, element: &dyn Element) -> bool {
224 self.renderers.contains_key(&element.as_any().type_id())
225 }
226
227 pub fn render(
231 &self,
232 segment: &Segment,
233 context: CompositionContext,
234 ) -> Option<Result<Vec<Segment>>> {
235 let renderables = successors(Some(&*segment.element), |&s| s.wrapped_element())
236 .filter(|s| self.can_render_specific(*s))
237 .collect::<Vec<_>>();
238
239 if renderables.is_empty() {
240 None
241 } else {
242 let mut generated_segments = vec![];
243
244 for renderable in renderables {
245 if let Some(renderer) = self.renderer_for(renderable) {
246 let result = renderer.render(segment, context);
247
248 if let Ok(mut segments) = result {
249 generated_segments.append(&mut segments);
250 } else {
251 return Some(result);
252 }
253 }
254 }
255
256 Some(Ok(generated_segments))
257 }
258 }
259}
260
261impl<R, S> Add<R> for RenderEngine
262where
263 R: Renderer<Element = S> + 'static,
264 S: Element,
265{
266 type Output = Self;
267
268 fn add(mut self, rhs: R) -> Self::Output {
269 self.add_renderer(rhs);
270
271 self
272 }
273}
274
275impl Add<RenderEngine> for RenderEngine {
276 type Output = Self;
277
278 fn add(mut self, rhs: RenderEngine) -> Self::Output {
279 self.renderers.extend(rhs.renderers);
280
281 self
282 }
283}