template/context.rs
1#[cfg(feature = "std")]
2use serde::ser::Serialize;
3
4#[cfg(feature = "std")]
5use crate::value::to_value;
6use crate::{SerdeError, value::Value};
7
8/// A template rendering context.
9///
10/// Constructed via the [`context!`](crate::context) macro or through the
11/// [`IntoContext`] trait (implemented for all `Serialize` types when the
12/// `std` feature is enabled).
13pub struct Context(pub(crate) Value);
14
15impl From<Context> for Value {
16 fn from(ctx: Context) -> Value {
17 ctx.0
18 }
19}
20
21/// Trait for types that can be converted into a [`Context`] for template rendering.
22///
23/// Implemented for [`Context`] directly and, with the `std` feature, for all
24/// types that implement [`Serialize`](serde::Serialize).
25///
26/// The `std` blanket impl requires the result to be a map-like value
27/// (i.e. [`Value::Map`](crate::value::Value::Map)). Non-map values such as
28/// plain strings or numbers return an error.
29pub trait IntoContext {
30 fn into_context(self) -> Result<Context, SerdeError>;
31}
32
33impl IntoContext for Context {
34 /// Returns itself
35 fn into_context(self) -> Result<Context, SerdeError> {
36 Ok(self)
37 }
38}
39
40#[cfg(feature = "std")]
41impl<T: Serialize + ?Sized> IntoContext for &T {
42 fn into_context(self) -> Result<Context, SerdeError> {
43 let v = to_value(self)?;
44 match v {
45 Value::Map(_) => Ok(Context(v)),
46 _ => Err(SerdeError("context must be a map-like value".into())),
47 }
48 }
49}