use crate::cel::time::parse_timestamp;
use crate::cel::{Key, Value};
use crate::expanded::Inputs;
use crate::host::Time;
use crate::md::Md;
use crate::settings::Settings;
use indexmap::IndexMap;
use serde_json::{Map, Value as Json};
use std::rc::Rc;
#[derive(Clone)]
pub struct RenderContext {
pub now: i128,
pub tz: String,
pub time: Rc<dyn Time>,
pub inputs: Map<String, Json>,
}
#[must_use]
pub fn parse_time(text: &str) -> Option<i128> {
parse_timestamp(text)
}
const DEFAULT_LANG: &str = "en";
const DEFAULT_VERSION: &str = "1";
impl RenderContext {
pub(crate) fn functions(&self, settings: &Settings) -> Md<'_> {
Md::new(
self.now,
settings.lang.as_deref().unwrap_or(DEFAULT_LANG),
self.tz(settings),
&*self.time,
)
}
pub(crate) fn md(&self, settings: &Settings) -> MdValue {
MdValue(IndexMap::from([
(
key("doc"),
Value::from_json(&Json::Object(settings.doc.clone())),
),
(
key("version"),
Value::string(settings.version.as_deref().unwrap_or(DEFAULT_VERSION)),
),
(
key("lang"),
Value::string(settings.lang.as_deref().unwrap_or(DEFAULT_LANG)),
),
(key("tz"), Value::string(self.tz(settings))),
]))
}
fn tz<'s>(&'s self, settings: &'s Settings) -> &'s str {
settings.tz.as_deref().unwrap_or(&self.tz)
}
}
pub(crate) struct MdValue(IndexMap<Key, Value>);
impl MdValue {
pub(crate) fn data(mut self, data: Value) -> Self {
self.0.insert(key("data"), data);
self
}
pub(crate) fn input(mut self, inputs: &Inputs) -> Self {
self.0.insert(key("input"), inputs.value());
self
}
}
impl From<MdValue> for Value {
fn from(md: MdValue) -> Self {
Self::Map(Rc::new(md.0))
}
}
pub(crate) fn key(name: &str) -> Key {
Key::String(Rc::from(name))
}