femstache 0.1.10

Embrace the feminine mustache to unlock your templating dreams! Or something, I don't know. :3
Documentation
//! # Femstache
//!
//! Femstache is a mustache-like templating library with its own extensions.
//!
//! ## Syntax
//!
//! Templates are composed of text interspersed with three kinds of control sequences:
//!
//!   - `{{ ... }}`: interpolation
//!   - `{% ... %}`: control
//!   - `{# ... #}`: metadata (only at the top of a document)
//!
//! There are a few kinds of control structures:
//!
//!   - `{% if COND %} ... {% end %}`
//!   - `{% for item in LIST %} ... {% end %}`
//!   - `{% for item in dict DICT %} ... {% end %}`
//!
//! There are also variable assignments, these are of the form `{% let VAR = EXPR %}`.
//!
//! Template inheritance is also supported, using `{# inherit "PATH_TO_PARENT" #}` and
//! `{% block BLOCKNAME %}{% end %}`.
//!
//! Expressions have the typical syntax of most programming languages, there are
//! a few binary operators:
//!
//!   - Equals: `x == y`
//!   - Not equals: `x != y`
//!   - String concat: `x ++ y`
//!   - Member access: `x.y`
//!   - Dict access: `x[y]`
//!   - Function calls: `x(y)`
//!
//! ## Types
//!
//! There are several available types:
//!
//!   - boolean values: `bool`
//!   - string values: `string` (these can be raw strings, which are not escaped)
//!   - optional values: `option T`
//!   - lists: `list T`
//!   - dicts: `dict T` (this is from strings to `T`)
//!   - structs: `struct(field1: ty1, field2: ty2, ...)`
//!   - functions: `fun A -> R`
//!
//! These types are truthy: (currently the typechecker doesn't allow non-`bool` conditions, though)
//!
//!   - `true`
//!   - non-empty string
//!   - non-empty dict
//!   - non-empty list
//!   - non-empty struct
//!   - non-empty option
//!   - function
//!
//! ## Typechecking
//!
//! Typechecking is handled using Hindley-Milner and supports extensible records.
//!
//! ## Example
//!
//! ```rust
//! use std::{collections::BTreeMap, path::PathBuf};
//! use femstache::{Femstache, TemplateSource, EscapeMode, Value};
//!
//! let mut files = BTreeMap::new();
//!
//! files.insert(PathBuf::from("hello.fem.html"), "{% for place in places %}hello {{ place }}! :3\n{% end %}".to_owned());
//!
//! let mut femstache = Femstache::new(TemplateSource::map(files), EscapeMode::Html);
//!
//! let mut inputs = BTreeMap::new();
//! inputs.insert("places".to_owned(), Value::List(vec![
//!     Value::string("world"),
//!     Value::string("mom"),
//!     Value::string("puniqt"),
//! ]));
//!
//! let output = femstache.render("hello.fem.html", &inputs).unwrap();
//!
//! assert_eq!(output, "hello world! :3\nhello mom! :3\nhello puniqt! :3\n");
//! ```

mod error;
mod femstache;
mod output;
mod renderer;

pub use femstache_eval::{EvalError, EvalResult, TemplateInput, ToValue, Value};
pub use femstache_loader::{LoaderError, TemplateSource};
pub use femstache_parser::{Offset, ParseError, ParseErrorKind, ParseResult, Span, Template};

pub use error::{FemstacheError, FemstacheResult};
pub use femstache::{Femstache, render};
pub use output::EscapeMode;

#[cfg(feature = "derive")]
pub use femstache_derive::TemplateInput;

#[cfg(test)]
mod tests;