thymeleaf 0.1.0-beta.0

A framework-neutral Thymeleaf-compatible dynamic template engine for Rust
Documentation
use std::io;
use std::sync::Arc;

use crate::IEngineConfiguration;
use crate::TemplateMode;
use crate::engine::TemplateData;
use crate::util::TemplateWriter;

use super::{IModelVisitor, ITemplateEvent};

/// 模板模型的事件序列合同。
///
/// 对应 Java: `org.thymeleaf.model.IModel`。
pub trait IModel: Send + Sync {
    /// 若模型是完整 TemplateModel,返回其模板解析数据。
    ///
    /// Java Fragment 始终持有 TemplateModel;该 capability 保留 Fragment 插入时
    /// 切换模板解析上下文的动态类型语义。
    fn get_template_data(&self) -> Option<&TemplateData> {
        None
    }
    /// 返回完整 TemplateModel 的共享模板解析数据身份。
    fn get_template_data_arc(&self) -> Option<Arc<TemplateData>> {
        None
    }
    /// 返回创建模型时使用的同一引擎配置。
    fn get_configuration(&self) -> &dyn IEngineConfiguration;
    /// 返回模型的模板模式。
    fn get_template_mode(&self) -> TemplateMode;
    /// 返回事件数量。
    fn size(&self) -> usize;
    /// 返回指定位置的事件。
    fn get(&self, pos: usize) -> Arc<dyn ITemplateEvent>;
    /// 在末尾添加事件;`None` 对应 Java null 并保持不变。
    fn add(&mut self, event: Option<Arc<dyn ITemplateEvent>>) -> Result<(), IModelError>;
    /// 在指定位置插入事件。
    fn insert(
        &mut self,
        pos: usize,
        event: Option<Arc<dyn ITemplateEvent>>,
    ) -> Result<(), IModelError>;
    /// 替换指定位置的事件。
    fn replace(
        &mut self,
        pos: usize,
        event: Option<Arc<dyn ITemplateEvent>>,
    ) -> Result<(), IModelError>;
    /// 追加另一个模型的事件。
    fn add_model(&mut self, model: Option<&dyn IModel>) -> Result<(), IModelError>;
    /// 在指定位置插入另一个模型。
    fn insert_model(&mut self, pos: usize, model: Option<&dyn IModel>) -> Result<(), IModelError>;
    /// 删除指定位置的事件。
    fn remove(&mut self, pos: usize) -> Result<(), IModelError>;
    /// 清空事件序列。
    fn reset(&mut self) -> Result<(), IModelError>;
    /// 创建可变模型副本;事件保持同一不可变对象身份。
    fn clone_model(&self) -> Box<dyn IModel>;
    /// 依次把事件分派给 Visitor。
    fn accept(&self, visitor: &mut dyn IModelVisitor);
    /// 依次写出所有事件。
    fn write(&self, writer: &mut dyn TemplateWriter) -> io::Result<()>;
}

/// 模型变更或索引访问错误。
#[derive(Clone, Debug, Eq, thiserror::Error, PartialEq)]
/// 对应 Java 语义:`IModel` 的 Rust 侧类型 `IModelError`。
pub enum IModelError {
    /// 不可变 TemplateModel 被要求修改。
    #[error(
        "Modifications are not allowed on immutable model objects. This model object is an immutable \
         implementation of the org.thymeleaf.model.IModel interface, and no modifications are allowed in \
         order to keep cache consistency and improve performance. To modify model events, convert first your \
         immutable model object to a mutable one by means of the org.thymeleaf.model.IModel#cloneModel() method"
    )]
    ImmutableModel,
    /// 事件索引越界。
    #[error("Model event index out of bounds: {0}")]
    IndexOutOfBounds(usize),
    /// TemplateStart/TemplateEnd 只能由解析器放入完整 TemplateModel。
    #[error(
        "Cannot insert event of type TemplateStart/TemplateEnd. These events can only be added \
         to models internally during template parsing."
    )]
    TemplateBoundaryInsertion,
    /// 两个模型来自不同引擎配置。
    #[error(
        "Cannot add model of class org.thymeleaf.engine.Model to the current template, as it was created using a different Template Engine Configuration."
    )]
    DifferentConfiguration,
    /// 两个模型使用不同模板模式。
    #[error(
        "Cannot add model of class org.thymeleaf.engine.Model to the current template, as it was created using a different Template Mode: {model_mode} instead of the current {current_mode}"
    )]
    DifferentTemplateMode {
        /// 被插入模型的模板模式。
        model_mode: TemplateMode,
        /// 当前模型的模板模式。
        current_mode: TemplateMode,
    },
    /// 自定义事件不是 Thymeleaf 支持的事件子接口。
    #[error("Cannot handle template event type")]
    UnsupportedEvent,
}