mod tera;
mod error;
pub use error::StringTemplateError;
use error::StringTemplateErrorImpl;
use std::fmt;
mod io;
use serde::{Deserialize, Serialize};
use crate::Parameters;
#[derive(Clone, Debug, Serialize, Deserialize)]
#[serde(transparent)]
pub struct StringTemplate(StringTemplateImpl);
impl From<StringTemplateImpl> for StringTemplate {
fn from(template: StringTemplateImpl) -> Self {
Self(template)
}
}
impl StringTemplate {
pub fn format(&self, parameters: &Parameters) -> Result<String, error::StringTemplateError> {
self.0.format(parameters).map_err(|e| e.into())
}
pub fn static_string<K: Into<String>>(template: K) -> StringTemplate {
StringTemplateImpl::static_string(template.into()).into()
}
pub fn tera<K: Into<String>>(template: K) -> StringTemplate {
StringTemplateImpl::tera(template.into()).into()
}
pub fn from_file<K: AsRef<std::path::Path>>(path: K) -> Result<StringTemplate, std::io::Error> {
io::read_prompt_template_file(path)
}
pub fn combine(parts: Vec<StringTemplate>) -> StringTemplate {
let res: Vec<StringTemplateImpl> = parts.into_iter().map(|p| p.0).collect();
StringTemplateImpl::combine(res).into()
}
}
impl fmt::Display for StringTemplate {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", self.0)
}
}
#[derive(Clone, Debug, Serialize, Deserialize)]
enum StringTemplateImpl {
Static(String),
Tera(String),
Combined(Vec<StringTemplateImpl>),
}
impl StringTemplateImpl {
pub fn format(&self, parameters: &Parameters) -> Result<String, StringTemplateErrorImpl> {
match self {
Self::Static(template) => Ok(template.clone()),
Self::Tera(template) => tera::render(template, parameters).map_err(|e| e.into()),
Self::Combined(templates) => {
let mut result = String::new();
for template in templates {
let formatted = template.format(parameters)?;
result.push_str(&formatted);
}
Ok(result)
}
}
}
pub fn static_string(template: String) -> Self {
Self::Static(template)
}
pub fn tera(template: String) -> Self {
Self::Tera(template)
}
pub fn combine(templates: Vec<Self>) -> Self {
Self::Combined(templates)
}
}
impl fmt::Display for StringTemplateImpl {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Static(s) => write!(f, "{}", s),
Self::Tera(template) => write!(f, "{}", template),
Self::Combined(templates) => {
for template in templates {
write!(f, "{}", template)?;
}
Ok(())
}
}
}
}
impl From<&str> for StringTemplate {
fn from(template: &str) -> Self {
Self::tera(template.to_string())
}
}