use std::sync::{Arc, Weak};
use indexmap::IndexSet;
use crate::context::IExpressionContext;
use crate::messageresolver::{MessageResolutionError, MessageResolutionResult};
use crate::util::{Utf16String, ValidateError};
use super::TemplateValue;
pub struct Messages {
context: Weak<dyn IExpressionContext>,
}
impl Messages {
pub fn new(context: Option<Arc<dyn IExpressionContext>>) -> Result<Self, ValidateError> {
let context = context.ok_or_else(|| ValidateError::IllegalArgument {
message: Some("Context cannot be null".to_owned()),
})?;
if context.as_template_context().is_none() {
return Err(ValidateError::IllegalArgument {
message: Some("Context must implement ITemplateContext".to_owned()),
});
}
Ok(Self {
context: Arc::downgrade(&context),
})
}
pub fn msg(&self, message_key: &Utf16String) -> MessageResolutionResult<Option<Utf16String>> {
self.msg_with_params(message_key, &[])
}
pub fn msg_with_params(
&self,
message_key: &Utf16String,
message_parameters: &[Option<Arc<TemplateValue>>],
) -> MessageResolutionResult<Option<Utf16String>> {
self.get_message(message_key, message_parameters, true)
}
pub fn msg_or_null(
&self,
message_key: &Utf16String,
) -> MessageResolutionResult<Option<Utf16String>> {
self.msg_or_null_with_params(message_key, &[])
}
pub fn msg_or_null_with_params(
&self,
message_key: &Utf16String,
message_parameters: &[Option<Arc<TemplateValue>>],
) -> MessageResolutionResult<Option<Utf16String>> {
self.get_message(message_key, message_parameters, false)
}
pub fn array_msg(
&self,
message_keys: Option<&[Utf16String]>,
) -> MessageResolutionResult<Vec<Option<Utf16String>>> {
self.array_msg_with_params(message_keys, &[])
}
pub fn array_msg_with_params(
&self,
message_keys: Option<&[Utf16String]>,
message_parameters: &[Option<Arc<TemplateValue>>],
) -> MessageResolutionResult<Vec<Option<Utf16String>>> {
self.map_messages(message_keys, message_parameters, true)
}
pub fn array_msg_or_null(
&self,
message_keys: Option<&[Utf16String]>,
) -> MessageResolutionResult<Vec<Option<Utf16String>>> {
self.array_msg_or_null_with_params(message_keys, &[])
}
pub fn array_msg_or_null_with_params(
&self,
message_keys: Option<&[Utf16String]>,
message_parameters: &[Option<Arc<TemplateValue>>],
) -> MessageResolutionResult<Vec<Option<Utf16String>>> {
self.map_messages(message_keys, message_parameters, false)
}
pub fn list_msg(
&self,
message_keys: Option<&[Utf16String]>,
) -> MessageResolutionResult<Vec<Option<Utf16String>>> {
self.array_msg(message_keys)
}
pub fn list_msg_with_params(
&self,
message_keys: Option<&[Utf16String]>,
message_parameters: &[Option<Arc<TemplateValue>>],
) -> MessageResolutionResult<Vec<Option<Utf16String>>> {
self.array_msg_with_params(message_keys, message_parameters)
}
pub fn list_msg_or_null(
&self,
message_keys: Option<&[Utf16String]>,
) -> MessageResolutionResult<Vec<Option<Utf16String>>> {
self.array_msg_or_null(message_keys)
}
pub fn list_msg_or_null_with_params(
&self,
message_keys: Option<&[Utf16String]>,
message_parameters: &[Option<Arc<TemplateValue>>],
) -> MessageResolutionResult<Vec<Option<Utf16String>>> {
self.array_msg_or_null_with_params(message_keys, message_parameters)
}
pub fn set_msg(
&self,
message_keys: Option<&IndexSet<Utf16String>>,
) -> MessageResolutionResult<IndexSet<Option<Utf16String>>> {
self.set_msg_with_params(message_keys, &[])
}
pub fn set_msg_with_params(
&self,
message_keys: Option<&IndexSet<Utf16String>>,
message_parameters: &[Option<Arc<TemplateValue>>],
) -> MessageResolutionResult<IndexSet<Option<Utf16String>>> {
self.map_set(message_keys, message_parameters, true)
}
pub fn set_msg_or_null(
&self,
message_keys: Option<&IndexSet<Utf16String>>,
) -> MessageResolutionResult<IndexSet<Option<Utf16String>>> {
self.set_msg_or_null_with_params(message_keys, &[])
}
pub fn set_msg_or_null_with_params(
&self,
message_keys: Option<&IndexSet<Utf16String>>,
message_parameters: &[Option<Arc<TemplateValue>>],
) -> MessageResolutionResult<IndexSet<Option<Utf16String>>> {
self.map_set(message_keys, message_parameters, false)
}
fn map_messages(
&self,
message_keys: Option<&[Utf16String]>,
message_parameters: &[Option<Arc<TemplateValue>>],
use_absent_message_representation: bool,
) -> MessageResolutionResult<Vec<Option<Utf16String>>> {
let message_keys = message_keys
.ok_or_else(|| ValidateError::IllegalArgument {
message: Some("Message keys cannot be null".to_owned()),
})
.map_err(|error| Box::new(error) as MessageResolutionError)?;
message_keys
.iter()
.map(|key| self.get_message(key, message_parameters, use_absent_message_representation))
.collect()
}
fn map_set(
&self,
message_keys: Option<&IndexSet<Utf16String>>,
message_parameters: &[Option<Arc<TemplateValue>>],
use_absent_message_representation: bool,
) -> MessageResolutionResult<IndexSet<Option<Utf16String>>> {
let message_keys = message_keys
.ok_or_else(|| ValidateError::IllegalArgument {
message: Some("Message keys cannot be null".to_owned()),
})
.map_err(|error| Box::new(error) as MessageResolutionError)?;
message_keys
.iter()
.map(|key| self.get_message(key, message_parameters, use_absent_message_representation))
.collect()
}
fn get_message(
&self,
message_key: &Utf16String,
message_parameters: &[Option<Arc<TemplateValue>>],
use_absent_message_representation: bool,
) -> MessageResolutionResult<Option<Utf16String>> {
let context = self.context.upgrade().ok_or_else(|| {
Box::new(ValidateError::IllegalArgument {
message: Some("Expression context is no longer available".to_owned()),
}) as MessageResolutionError
})?;
context
.as_template_context()
.ok_or_else(|| {
Box::new(ValidateError::IllegalArgument {
message: Some("Context must implement ITemplateContext".to_owned()),
}) as MessageResolutionError
})?
.get_message(
None,
message_key,
Some(message_parameters),
use_absent_message_representation,
)
}
}