use std::sync::Arc;
use std::sync::OnceLock;
use super::ILazyContextVariable;
use crate::expression::{TemplateObject, TemplateValue};
use crate::util::Utf16String;
pub struct LazyContextVariable<T, F>
where
F: Fn() -> T,
{
value: OnceLock<T>,
load_value: F,
}
impl<T, F> LazyContextVariable<T, F>
where
F: Fn() -> T,
{
#[must_use]
pub const fn new(load_value: F) -> Self {
Self {
value: OnceLock::new(),
load_value,
}
}
pub fn get_value(&self) -> &T {
self.value.get_or_init(|| (self.load_value)())
}
}
impl<T, F> ILazyContextVariable<T> for LazyContextVariable<T, F>
where
F: Fn() -> T,
{
fn get_value(&self) -> &T {
Self::get_value(self)
}
}
impl<F> TemplateObject for LazyContextVariable<Option<Arc<TemplateValue>>, F>
where
F: Fn() -> Option<Arc<TemplateValue>> + Send + Sync + 'static,
{
fn class_name(&self) -> &str {
"org.thymeleaf.context.LazyContextVariable"
}
fn to_utf16_string(&self) -> Utf16String {
self.get_value()
.as_deref()
.and_then(TemplateValue::to_utf16_string)
.unwrap_or_else(|| Utf16String::from_rust_str("null"))
}
fn as_any(&self) -> &dyn std::any::Any {
self
}
fn resolve_lazy_context_variable(&self) -> Option<Option<Arc<TemplateValue>>> {
Some(self.get_value().clone())
}
}