Rendering spans
This commit is contained in:
48
src/renderer/errors.rs
Normal file
48
src/renderer/errors.rs
Normal file
@@ -0,0 +1,48 @@
|
||||
use std::error;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct RenderError {
|
||||
pub message: String,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct CompileError {
|
||||
pub message: String,
|
||||
}
|
||||
|
||||
impl fmt::Display for RenderError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "Error rendering: {}", self.message)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for RenderError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "Error rendering: {}", self.message)
|
||||
}
|
||||
}
|
||||
|
||||
impl error::Error for RenderError {
|
||||
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for CompileError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "Error rendering: {}", self.message)
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for CompileError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
write!(f, "Error rendering: {}", self.message)
|
||||
}
|
||||
}
|
||||
|
||||
impl error::Error for CompileError {
|
||||
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
|
||||
None
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
//! This module contains a renderer for a rust implementation of LinkedIn Dust
|
||||
|
||||
mod errors;
|
||||
mod renderer;
|
||||
|
||||
pub use renderer::compile_template;
|
||||
|
||||
@@ -1,41 +1,73 @@
|
||||
use crate::parser::template;
|
||||
use crate::parser::Template;
|
||||
use nom::IResult;
|
||||
use std::collections::BTreeMap;
|
||||
use crate::parser::TemplateElement;
|
||||
use crate::renderer::errors::CompileError;
|
||||
use crate::renderer::errors::RenderError;
|
||||
use std::collections::HashMap;
|
||||
use std::ops::Index;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct CompiledTemplate<'a> {
|
||||
template: Template<'a>,
|
||||
name: String,
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct DustRenderer<'a> {
|
||||
templates: BTreeMap<&'a String, &'a Template<'a>>,
|
||||
templates: HashMap<String, &'a Template<'a>>,
|
||||
}
|
||||
|
||||
pub fn compile_template<'a>(source: &'a str, name: String) -> CompiledTemplate<'a> {
|
||||
// TODO: Make this function return a result with a custom error type. Break the nom IResult chain
|
||||
pub fn compile_template<'a>(
|
||||
source: &'a str,
|
||||
name: String,
|
||||
) -> Result<CompiledTemplate<'a>, CompileError> {
|
||||
// TODO: Make this all consuming
|
||||
// TODO: This could use better error management
|
||||
let (_remaining, parsed_template) = template(source).expect("Failed to compile template");
|
||||
CompiledTemplate {
|
||||
Ok(CompiledTemplate {
|
||||
template: parsed_template,
|
||||
name: name,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
impl<'a> DustRenderer<'a> {
|
||||
pub fn new() -> DustRenderer<'a> {
|
||||
DustRenderer {
|
||||
templates: BTreeMap::new(),
|
||||
templates: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn load_source(&mut self, template: &'a CompiledTemplate) {
|
||||
self.templates.insert(&template.name, &template.template);
|
||||
self.templates
|
||||
.insert(template.name.clone(), &template.template);
|
||||
}
|
||||
|
||||
// pub fn render(&self, context) {
|
||||
pub fn render<C>(&self, name: &str, context: C) -> Result<String, RenderError>
|
||||
where
|
||||
C: Index<&'a str>,
|
||||
{
|
||||
let main_template = match self.templates.get(name) {
|
||||
Some(tmpl) => tmpl,
|
||||
None => {
|
||||
return Err(RenderError {
|
||||
message: format!("No template named {} in context", name),
|
||||
});
|
||||
}
|
||||
};
|
||||
self.render_template(main_template, context)
|
||||
}
|
||||
|
||||
// }
|
||||
fn render_template<C>(&self, template: &Template, context: C) -> Result<String, RenderError>
|
||||
where
|
||||
C: Index<&'a str>,
|
||||
{
|
||||
let mut output = String::new();
|
||||
for elem in &template.contents.elements {
|
||||
match elem {
|
||||
TemplateElement::TESpan(span) => output.push_str(span.contents),
|
||||
TemplateElement::TETag(dt) => (),
|
||||
}
|
||||
}
|
||||
Ok(output)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user