use std::fmt::{Display, Formatter};
use std::io;
use std::sync::Arc;
use crate::model::{IModelVisitor, ITemplateEvent, IText};
use crate::util::{CharSequenceValue, TemplateWriter, TextUtilsError, Utf16String};
use super::{AbstractTextualTemplateEvent, IEngineTemplateEvent, ITemplateHandler};
pub struct Text {
textual_event: AbstractTextualTemplateEvent,
}
impl Text {
#[must_use]
pub fn new(text: Option<Arc<dyn CharSequenceValue>>) -> Self {
Self {
textual_event: AbstractTextualTemplateEvent::new(text),
}
}
#[must_use]
pub fn with_location(
text: Option<Arc<dyn CharSequenceValue>>,
template_name: Option<Utf16String>,
line: i32,
col: i32,
) -> Self {
Self {
textual_event: AbstractTextualTemplateEvent::with_location(
text,
template_name,
line,
col,
),
}
}
pub fn is_whitespace(&self) -> Result<bool, TextUtilsError> {
self.textual_event.is_whitespace()
}
pub fn is_inlineable(&self) -> Result<bool, TextUtilsError> {
self.textual_event.is_inlineable()
}
}
impl CharSequenceValue for Text {
fn sequence_class_name(&self) -> &str {
"org.thymeleaf.engine.Text"
}
fn length(&self) -> Result<i32, TextUtilsError> {
self.textual_event.get_content_length()
}
fn char_at(&self, index: i32) -> Result<u16, TextUtilsError> {
self.textual_event.char_at_content(index)
}
fn as_utf16_string(&self) -> Option<&Utf16String> {
None
}
fn to_utf16_string(&self) -> Result<Utf16String, TextUtilsError> {
self.textual_event
.get_content_text()?
.ok_or(TextUtilsError::NullPointer)
}
fn sub_sequence(&self, start: i32, end: i32) -> Result<Utf16String, TextUtilsError> {
self.textual_event.content_sub_sequence(start, end)
}
}
impl IText for Text {
fn get_text(&self) -> Result<Option<Utf16String>, TextUtilsError> {
self.textual_event.get_content_text()
}
}
impl ITemplateEvent for Text {
fn has_location(&self) -> bool {
self.textual_event.as_template_event().has_location()
}
fn get_template_name(&self) -> Option<&Utf16String> {
self.textual_event.as_template_event().get_template_name()
}
fn get_line(&self) -> i32 {
self.textual_event.as_template_event().get_line()
}
fn get_col(&self) -> i32 {
self.textual_event.as_template_event().get_col()
}
fn accept(&self, visitor: &mut dyn IModelVisitor) {
visitor.visit_text(self);
}
fn be_handled(
self: Arc<Self>,
handler: &mut dyn ITemplateHandler,
) -> Result<(), Box<dyn crate::exceptions::TemplateEngineException>> {
handler.handle_text(self)
}
fn as_text(&self) -> Option<&dyn IText> {
Some(self)
}
fn into_text(self: Arc<Self>) -> Option<Arc<dyn IText>> {
Some(self)
}
fn write(&self, writer: &mut dyn TemplateWriter) -> io::Result<()> {
self.textual_event.write_content(writer)
}
}
impl IEngineTemplateEvent for Text {}
impl Display for Text {
fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result {
let text = self
.textual_event
.get_content_text()
.map_err(|_| std::fmt::Error)?
.ok_or(std::fmt::Error)?;
formatter.write_str(&text.to_string_lossy())
}
}