Skip to main content

vector/template/
confined.rs

1use super::*;
2
3impl fmt::Debug for ConfinedTemplate {
4    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
5        f.debug_struct("ConfinedTemplate")
6            .field("inner", &self.inner)
7            .field("confinement", &self.checker.as_ref().map(|_| "<fn>"))
8            .finish()
9    }
10}
11
12impl fmt::Display for ConfinedTemplate {
13    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
14        self.inner.fmt(f)
15    }
16}
17
18impl ConfinedTemplate {
19    /// Set tz offset on the wrapped template.
20    pub const fn with_tz_offset(mut self, tz_offset: Option<FixedOffset>) -> Self {
21        self.inner.tz_offset = tz_offset;
22        self
23    }
24
25    /// Run the confinement check against a raw string without going through a normal render.
26    ///
27    /// Callers that bypass template rendering entirely (e.g. the elasticsearch sink's
28    /// `auto_routing` path) must call this to keep the confinement contract intact.
29    pub fn check_confinement(&self, rendered: &str) -> Result<(), TemplateRenderingError> {
30        if let Some(checker) = &self.checker {
31            checker
32                .confine(rendered)
33                .map_err(|e| TemplateRenderingError::Confined {
34                    rendered_preview: confined_preview(rendered),
35                    rendered_len: rendered.len(),
36                    message: e.to_string(),
37                })?;
38        }
39        Ok(())
40    }
41
42    /// Renders the given template with data from the event, returning raw bytes.
43    ///
44    /// If a confinement checker was attached via [`Template::confine`], it runs after
45    /// rendering and returns [`TemplateRenderingError::Confined`] on failure.
46    pub fn render<'a>(
47        &self,
48        event: impl Into<EventRef<'a>>,
49    ) -> Result<Bytes, TemplateRenderingError> {
50        self.render_string(event.into()).map(Into::into)
51    }
52
53    /// Renders the given template with data from the event.
54    ///
55    /// If a confinement checker was attached via [`Template::confine`], it runs after
56    /// rendering and returns [`TemplateRenderingError::Confined`] on failure.
57    pub fn render_string<'a>(
58        &self,
59        event: impl Into<EventRef<'a>>,
60    ) -> Result<String, TemplateRenderingError> {
61        let rendered = self.inner.render_string(event)?;
62        self.check_confinement(&rendered)?;
63        Ok(rendered)
64    }
65
66    /// Returns the fields used by this template for dynamic rendering.
67    ///
68    /// Delegates to [`UnconfinedTemplate::get_fields`].
69    pub fn get_fields(&self) -> Option<Vec<String>> {
70        self.inner.get_fields()
71    }
72}