use std::sync::Arc;
use thiserror::Error;
use crate::context::IContext;
use crate::util::Utf16String;
use super::TemplateValue;
pub struct NativeContextPropertyAccessor;
impl NativeContextPropertyAccessor {
pub const RESTRICT_EXPRESSION_OBJECTS: &'static str = "%RESTRICT_EXPRESSION_OBJECTS%";
pub const REQUEST_PARAMETERS_RESTRICTED_VARIABLE_NAME: &'static str = "param";
pub const fn new() -> Self {
Self
}
pub fn get_property(
&self,
restrict_expression_objects: bool,
target: &dyn IContext,
name: Option<&Utf16String>,
) -> Result<Option<Arc<TemplateValue>>, NativeContextPropertyError> {
if restrict_expression_objects
&& name.is_some_and(|name| {
name == &Utf16String::from_rust_str(
Self::REQUEST_PARAMETERS_RESTRICTED_VARIABLE_NAME,
)
})
{
return Err(NativeContextPropertyError::RestrictedVariable {
name: Self::REQUEST_PARAMETERS_RESTRICTED_VARIABLE_NAME.to_owned(),
});
}
Ok(target.get_variable(name))
}
pub fn set_property(
&self,
_target: &dyn IContext,
_name: Option<&Utf16String>,
_value: Option<Arc<TemplateValue>>,
) -> Result<(), NativeContextPropertyError> {
Err(NativeContextPropertyError::ReadOnly)
}
}
impl Default for NativeContextPropertyAccessor {
fn default() -> Self {
Self::new()
}
}
#[derive(Debug, Error, Eq, PartialEq)]
pub enum NativeContextPropertyError {
#[error(
"Access to variable \"{name}\" is forbidden in this context. Note some restrictions apply to variable access."
)]
RestrictedVariable {
name: String,
},
#[error("Cannot set values into VariablesMap instances from OGNL Expressions")]
ReadOnly,
}