Rename library to nomo

Signed-off-by: Marcel Müller <neikos@neikos.email>
This commit is contained in:
Marcel Müller 2026-03-07 10:07:47 +01:00
parent d691fb9198
commit d2e0405033
28 changed files with 92 additions and 92 deletions

28
Cargo.lock generated
View file

@ -228,6 +228,20 @@ version = "2.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79"
[[package]]
name = "nomo"
version = "0.1.0"
dependencies = [
"annotate-snippets",
"displaydoc",
"insta",
"nomo",
"serde",
"serde_json",
"thiserror",
"winnow",
]
[[package]] [[package]]
name = "once_cell" name = "once_cell"
version = "1.21.3" version = "1.21.3"
@ -386,20 +400,6 @@ dependencies = [
"windows-sys 0.61.2", "windows-sys 0.61.2",
] ]
[[package]]
name = "temple"
version = "0.1.0"
dependencies = [
"annotate-snippets",
"displaydoc",
"insta",
"serde",
"serde_json",
"temple",
"thiserror",
"winnow",
]
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "2.0.18" version = "2.0.18"

View file

@ -1,5 +1,5 @@
[package] [package]
name = "temple" name = "nomo"
version = "0.1.0" version = "0.1.0"
edition = "2024" edition = "2024"
@ -14,7 +14,7 @@ winnow = { version = "0.7.14", features = ["unstable-recover"] }
[dev-dependencies] [dev-dependencies]
annotate-snippets = { version = "0.12.13", features = ["testing-colors"] } annotate-snippets = { version = "0.12.13", features = ["testing-colors"] }
insta = { version = "1.46.3", features = ["glob"] } insta = { version = "1.46.3", features = ["glob"] }
temple = { path = ".", features = ["serialize"] } nomo = { path = ".", features = ["serialize"] }
[profile.dev.package] [profile.dev.package]
insta.opt-level = 3 insta.opt-level = 3

View file

@ -1,5 +1,5 @@
use crate::ast::TemplateAstExpr; use crate::ast::TemplateAstExpr;
use crate::input::TempleInput; use crate::input::NomoInput;
pub struct EmitMachine { pub struct EmitMachine {
current_index: usize, current_index: usize,
@ -25,10 +25,10 @@ pub struct VariableSlot {
#[derive(Debug)] #[derive(Debug)]
pub enum Instruction { pub enum Instruction {
AppendContent { AppendContent {
content: TempleInput, content: NomoInput,
}, },
LoadFromContextToSlot { LoadFromContextToSlot {
name: TempleInput, name: NomoInput,
slot: VariableSlot, slot: VariableSlot,
}, },
EmitFromSlot { EmitFromSlot {

View file

@ -5,12 +5,12 @@ use thiserror::Error;
use crate::Context; use crate::Context;
use crate::emit::Instruction; use crate::emit::Instruction;
use crate::input::TempleInput; use crate::input::NomoInput;
#[derive(Debug, Error, Display)] #[derive(Debug, Error, Display)]
pub enum EvaluationError { pub enum EvaluationError {
/// An unknown variable was encountered: .0 /// An unknown variable was encountered: .0
UnknownVariable(TempleInput), UnknownVariable(NomoInput),
/// An explicit abort was requested /// An explicit abort was requested
ExplicitAbort, ExplicitAbort,
} }

View file

@ -9,14 +9,14 @@ use winnow::stream::Stream;
use winnow::stream::StreamIsPartial; use winnow::stream::StreamIsPartial;
#[derive(Clone, PartialEq, Eq)] #[derive(Clone, PartialEq, Eq)]
pub struct TempleInput { pub struct NomoInput {
backing: Arc<str>, backing: Arc<str>,
range: Range<usize>, range: Range<usize>,
} }
impl TempleInput { impl NomoInput {
pub fn from_parts(backing: Arc<str>, range: Range<usize>) -> TempleInput { pub fn from_parts(backing: Arc<str>, range: Range<usize>) -> NomoInput {
TempleInput { backing, range } NomoInput { backing, range }
} }
pub fn into_parts(self) -> (Arc<str>, Range<usize>) { pub fn into_parts(self) -> (Arc<str>, Range<usize>) {
@ -24,43 +24,43 @@ impl TempleInput {
} }
} }
impl std::fmt::Debug for TempleInput { impl std::fmt::Debug for NomoInput {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "\"{}\"", self.as_str()) write!(f, "\"{}\"", self.as_str())
} }
} }
impl From<String> for TempleInput { impl From<String> for NomoInput {
fn from(value: String) -> Self { fn from(value: String) -> Self {
let range = 0..value.len(); let range = 0..value.len();
let backing = Arc::from(value); let backing = Arc::from(value);
TempleInput { backing, range } NomoInput { backing, range }
} }
} }
impl From<&str> for TempleInput { impl From<&str> for NomoInput {
fn from(value: &str) -> Self { fn from(value: &str) -> Self {
let backing = Arc::from(value.to_string()); let backing = Arc::from(value.to_string());
let range = 0..value.len(); let range = 0..value.len();
TempleInput { backing, range } NomoInput { backing, range }
} }
} }
impl FindSlice<&str> for TempleInput { impl FindSlice<&str> for NomoInput {
fn find_slice(&self, substr: &str) -> Option<core::ops::Range<usize>> { fn find_slice(&self, substr: &str) -> Option<core::ops::Range<usize>> {
self.as_str().find_slice(substr) self.as_str().find_slice(substr)
} }
} }
impl Compare<&str> for TempleInput { impl Compare<&str> for NomoInput {
fn compare(&self, t: &str) -> winnow::stream::CompareResult { fn compare(&self, t: &str) -> winnow::stream::CompareResult {
self.as_str().compare(t) self.as_str().compare(t)
} }
} }
impl Deref for TempleInput { impl Deref for NomoInput {
type Target = str; type Target = str;
fn deref(&self) -> &Self::Target { fn deref(&self) -> &Self::Target {
@ -68,24 +68,24 @@ impl Deref for TempleInput {
} }
} }
impl TempleInput { impl NomoInput {
pub fn as_str(&self) -> &str { pub fn as_str(&self) -> &str {
self.deref() self.deref()
} }
} }
impl Offset for TempleInput { impl Offset for NomoInput {
fn offset_from(&self, start: &Self) -> usize { fn offset_from(&self, start: &Self) -> usize {
self.as_str().offset_from(&start.as_str()) self.as_str().offset_from(&start.as_str())
} }
} }
pub struct TempleInputIter { pub struct NomoInputIter {
idx: usize, idx: usize,
input: TempleInput, input: NomoInput,
} }
impl Iterator for TempleInputIter { impl Iterator for NomoInputIter {
type Item = (usize, char); type Item = (usize, char);
fn next(&mut self) -> Option<Self::Item> { fn next(&mut self) -> Option<Self::Item> {
@ -95,7 +95,7 @@ impl Iterator for TempleInputIter {
} }
} }
impl StreamIsPartial for TempleInput { impl StreamIsPartial for NomoInput {
type PartialState = (); type PartialState = ();
fn complete(&mut self) -> Self::PartialState { fn complete(&mut self) -> Self::PartialState {
@ -109,17 +109,17 @@ impl StreamIsPartial for TempleInput {
} }
} }
impl Stream for TempleInput { impl Stream for NomoInput {
type Token = char; type Token = char;
type Slice = TempleInput; type Slice = NomoInput;
type IterOffsets = TempleInputIter; type IterOffsets = NomoInputIter;
type Checkpoint = TempleInput; type Checkpoint = NomoInput;
fn iter_offsets(&self) -> Self::IterOffsets { fn iter_offsets(&self) -> Self::IterOffsets {
TempleInputIter { NomoInputIter {
idx: 0, idx: 0,
input: self.clone(), input: self.clone(),
} }
@ -187,11 +187,11 @@ impl Stream for TempleInput {
mod tests { mod tests {
use winnow::stream::Stream; use winnow::stream::Stream;
use crate::input::TempleInput; use crate::input::NomoInput;
#[test] #[test]
fn check_stream_impl() { fn check_stream_impl() {
let mut stream = TempleInput::from("checking"); let mut stream = NomoInput::from("checking");
let checkpoint = stream.checkpoint(); let checkpoint = stream.checkpoint();

View file

@ -6,7 +6,7 @@ use serde::Serialize;
use thiserror::Error; use thiserror::Error;
use crate::emit::Instruction; use crate::emit::Instruction;
use crate::input::TempleInput; use crate::input::NomoInput;
pub mod ast; pub mod ast;
pub mod emit; pub mod emit;
@ -15,7 +15,7 @@ pub mod input;
pub mod parser; pub mod parser;
#[derive(Debug, Error, Display)] #[derive(Debug, Error, Display)]
pub enum TempleError { pub enum NomoError {
/// Could not parse the given template /// Could not parse the given template
ParseError { ParseError {
#[from] #[from]
@ -37,19 +37,19 @@ pub enum TempleError {
UnknownTemplate(String), UnknownTemplate(String),
} }
pub struct Temple { pub struct Nomo {
templates: HashMap<String, Template>, templates: HashMap<String, Template>,
} }
impl Default for Temple { impl Default for Nomo {
fn default() -> Self { fn default() -> Self {
Self::new() Self::new()
} }
} }
impl Temple { impl Nomo {
pub fn new() -> Temple { pub fn new() -> Nomo {
Temple { Nomo {
templates: HashMap::new(), templates: HashMap::new(),
} }
} }
@ -57,8 +57,8 @@ impl Temple {
pub fn add_template( pub fn add_template(
&mut self, &mut self,
name: impl Into<String>, name: impl Into<String>,
value: impl Into<TempleInput>, value: impl Into<NomoInput>,
) -> Result<(), TempleError> { ) -> Result<(), NomoError> {
let source = value.into(); let source = value.into();
let parse = parser::parse(source.clone())?; let parse = parser::parse(source.clone())?;
let ast = ast::parse(parse.tokens())?; let ast = ast::parse(parse.tokens())?;
@ -76,11 +76,11 @@ impl Temple {
Ok(()) Ok(())
} }
pub fn render(&self, name: &str, ctx: &Context) -> Result<String, TempleError> { pub fn render(&self, name: &str, ctx: &Context) -> Result<String, NomoError> {
let template = self let template = self
.templates .templates
.get(name) .get(name)
.ok_or_else(|| TempleError::UnknownTemplate(name.to_string()))?; .ok_or_else(|| NomoError::UnknownTemplate(name.to_string()))?;
let res = eval::execute(&template.instructions, ctx)?; let res = eval::execute(&template.instructions, ctx)?;
@ -89,7 +89,7 @@ impl Temple {
} }
struct Template { struct Template {
source: TempleInput, source: NomoInput,
instructions: Vec<Instruction>, instructions: Vec<Instruction>,
} }
@ -186,11 +186,11 @@ where
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::Context; use crate::Context;
use crate::Temple; use crate::Nomo;
#[test] #[test]
fn check_simple_template() { fn check_simple_template() {
let mut temp = Temple::new(); let mut temp = Nomo::new();
temp.add_template("base", "Hello {{= name }}").unwrap(); temp.add_template("base", "Hello {{= name }}").unwrap();

View file

@ -33,10 +33,10 @@ use winnow::token::take_until;
use winnow::token::take_while; use winnow::token::take_while;
use crate::SourceSpan; use crate::SourceSpan;
use crate::input::TempleInput; use crate::input::NomoInput;
use crate::resume_after_cut; use crate::resume_after_cut;
type Input<'input> = Recoverable<LocatingSlice<TempleInput>, ParseError>; type Input<'input> = Recoverable<LocatingSlice<NomoInput>, ParseError>;
type PResult<'input, T> = Result<T, ParseError>; type PResult<'input, T> = Result<T, ParseError>;
#[derive(Debug, Error)] #[derive(Debug, Error)]
@ -52,7 +52,7 @@ impl std::fmt::Display for ParseFailure {
} }
impl ParseFailure { impl ParseFailure {
fn from_errors(errors: Vec<ParseError>, input: TempleInput) -> ParseFailure { fn from_errors(errors: Vec<ParseError>, input: NomoInput) -> ParseFailure {
ParseFailure { ParseFailure {
input: Arc::from(input.to_string()), input: Arc::from(input.to_string()),
errors, errors,
@ -248,13 +248,13 @@ impl<const LEN: usize> winnow::stream::ContainsToken<&'_ TemplateToken> for [Tok
#[derive(Debug, Clone, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
pub struct TemplateToken { pub struct TemplateToken {
kind: TokenKind, kind: TokenKind,
source: TempleInput, source: NomoInput,
} }
macro_rules! impl_token_kind_builders { macro_rules! impl_token_kind_builders {
($($name:ident => $kind:expr),+ $(,)?) => { ($($name:ident => $kind:expr),+ $(,)?) => {
$( $(
fn $name(source: TempleInput) -> Self { fn $name(source: NomoInput) -> Self {
TemplateToken { TemplateToken {
kind: $kind, kind: $kind,
source, source,
@ -277,7 +277,7 @@ impl TemplateToken {
end => TokenKind::End, end => TokenKind::End,
} }
pub fn literal(literal: TokenLiteral, source: TempleInput) -> Self { pub fn literal(literal: TokenLiteral, source: NomoInput) -> Self {
TemplateToken { TemplateToken {
kind: TokenKind::Literal(literal), kind: TokenKind::Literal(literal),
source, source,
@ -288,12 +288,12 @@ impl TemplateToken {
self.kind self.kind
} }
pub fn source(&self) -> TempleInput { pub fn source(&self) -> NomoInput {
self.source.clone() self.source.clone()
} }
} }
pub fn parse(input: TempleInput) -> Result<ParsedTemplate, ParseFailure> { pub fn parse(input: NomoInput) -> Result<ParsedTemplate, ParseFailure> {
let (_remaining, val, errors) = let (_remaining, val, errors) =
parse_tokens.recoverable_parse(LocatingSlice::new(input.clone())); parse_tokens.recoverable_parse(LocatingSlice::new(input.clone()));
@ -335,7 +335,7 @@ fn parse_interpolate<'input>(input: &mut Input<'input>) -> PResult<'input, Vec<T
.resume_after(recover) .resume_after(recover)
.with_taken() .with_taken()
.map(|(val, taken)| { .map(|(val, taken)| {
val.unwrap_or_else(|| (vec![TemplateToken::invalid(taken)], TempleInput::from(""))) val.unwrap_or_else(|| (vec![TemplateToken::invalid(taken)], NomoInput::from("")))
}) })
.parse_next(input)?; .parse_next(input)?;
@ -419,7 +419,7 @@ fn parse_ident<'input>(input: &mut Input<'input>) -> PResult<'input, TemplateTok
.parse_next(input) .parse_next(input)
} }
fn ident<'input>(input: &mut Input<'input>) -> PResult<'input, TempleInput> { fn ident<'input>(input: &mut Input<'input>) -> PResult<'input, NomoInput> {
peek(not(parse_literal)) peek(not(parse_literal))
.context(ParseError::ctx().msg("Expected an ident, but found a literal instead")) .context(ParseError::ctx().msg("Expected an ident, but found a literal instead"))
.parse_next(input)?; .parse_next(input)?;

View file

@ -1,7 +1,7 @@
--- ---
source: tests/file_tests.rs source: tests/file_tests.rs
expression: parsed expression: parsed
input_file: tests/cases/identifiers.temple input_file: tests/cases/identifiers.nomo
--- ---
ParsedTemplate { ParsedTemplate {
tokens: [ tokens: [

View file

@ -1,7 +1,7 @@
--- ---
source: tests/file_tests.rs source: tests/file_tests.rs
expression: parsed expression: parsed
input_file: tests/cases/interpolation.temple input_file: tests/cases/interpolation.nomo
--- ---
ParsedTemplate { ParsedTemplate {
tokens: [ tokens: [

View file

@ -1,7 +1,7 @@
--- ---
source: tests/file_tests.rs source: tests/file_tests.rs
expression: parsed expression: parsed
input_file: tests/cases/multiple.temple input_file: tests/cases/multiple.nomo
--- ---
ParsedTemplate { ParsedTemplate {
tokens: [ tokens: [

View file

@ -1,7 +1,7 @@
--- ---
source: tests/file_tests.rs source: tests/file_tests.rs
expression: parsed expression: parsed
input_file: tests/cases/simple.temple input_file: tests/cases/simple.nomo
--- ---
ParsedTemplate { ParsedTemplate {
tokens: [ tokens: [

View file

@ -1,7 +1,7 @@
--- ---
source: tests/file_tests.rs source: tests/file_tests.rs
expression: ast expression: ast
input_file: tests/cases/identifiers.temple input_file: tests/cases/identifiers.nomo
--- ---
TemplateAst { TemplateAst {
root: [ root: [

View file

@ -1,7 +1,7 @@
--- ---
source: tests/file_tests.rs source: tests/file_tests.rs
expression: ast expression: ast
input_file: tests/cases/interpolation.temple input_file: tests/cases/interpolation.nomo
--- ---
TemplateAst { TemplateAst {
root: [ root: [

View file

@ -1,7 +1,7 @@
--- ---
source: tests/file_tests.rs source: tests/file_tests.rs
expression: ast expression: ast
input_file: tests/cases/multiple.temple input_file: tests/cases/multiple.nomo
--- ---
TemplateAst { TemplateAst {
root: [ root: [

View file

@ -1,7 +1,7 @@
--- ---
source: tests/file_tests.rs source: tests/file_tests.rs
expression: ast expression: ast
input_file: tests/cases/simple.temple input_file: tests/cases/simple.nomo
--- ---
TemplateAst { TemplateAst {
root: [ root: [

View file

@ -1,7 +1,7 @@
--- ---
source: tests/file_tests.rs source: tests/file_tests.rs
expression: emit expression: emit
input_file: tests/cases/identifiers.temple input_file: tests/cases/identifiers.nomo
--- ---
[ [
LoadFromContextToSlot { LoadFromContextToSlot {

View file

@ -1,7 +1,7 @@
--- ---
source: tests/file_tests.rs source: tests/file_tests.rs
expression: emit expression: emit
input_file: tests/cases/interpolation.temple input_file: tests/cases/interpolation.nomo
--- ---
[ [
AppendContent { AppendContent {

View file

@ -1,7 +1,7 @@
--- ---
source: tests/file_tests.rs source: tests/file_tests.rs
expression: emit expression: emit
input_file: tests/cases/multiple.temple input_file: tests/cases/multiple.nomo
--- ---
[ [
AppendContent { AppendContent {

View file

@ -1,7 +1,7 @@
--- ---
source: tests/file_tests.rs source: tests/file_tests.rs
expression: emit expression: emit
input_file: tests/cases/simple.temple input_file: tests/cases/simple.nomo
--- ---
[ [
AppendContent { AppendContent {

View file

@ -1,6 +1,6 @@
--- ---
source: tests/file_tests.rs source: tests/file_tests.rs
expression: output expression: output
input_file: tests/cases/identifiers.temple input_file: tests/cases/identifiers.nomo
--- ---
"Foo\nFoo\nFoo\nFoo\nFoo\nFoo" "Foo\nFoo\nFoo\nFoo\nFoo\nFoo"

View file

@ -1,6 +1,6 @@
--- ---
source: tests/file_tests.rs source: tests/file_tests.rs
expression: output expression: output
input_file: tests/cases/interpolation.temple input_file: tests/cases/interpolation.nomo
--- ---
"Hello! I'm Hemera" "Hello! I'm Hemera"

View file

@ -1,6 +1,6 @@
--- ---
source: tests/file_tests.rs source: tests/file_tests.rs
expression: output expression: output
input_file: tests/cases/multiple.temple input_file: tests/cases/multiple.nomo
--- ---
"Hi there! My name is Hemera Green" "Hi there! My name is Hemera Green"

View file

@ -1,6 +1,6 @@
--- ---
source: tests/file_tests.rs source: tests/file_tests.rs
expression: output expression: output
input_file: tests/cases/simple.temple input_file: tests/cases/simple.nomo
--- ---
"Hello World!" "Hello World!"

View file

@ -1,10 +1,10 @@
use std::collections::HashMap; use std::collections::HashMap;
use temple::Context; use nomo::Context;
#[test] #[test]
fn check_cases() { fn check_cases() {
insta::glob!("cases/*.temple", |path| { insta::glob!("cases/*.nomo", |path| {
let mut settings = insta::Settings::clone_current(); let mut settings = insta::Settings::clone_current();
settings.set_snapshot_path("cases"); settings.set_snapshot_path("cases");
settings.set_snapshot_suffix(path.file_stem().unwrap().display().to_string()); settings.set_snapshot_suffix(path.file_stem().unwrap().display().to_string());
@ -27,19 +27,19 @@ fn check_cases() {
context.insert(k, v); context.insert(k, v);
} }
let parsed = temple::parser::parse(input.into()).unwrap(); let parsed = nomo::parser::parse(input.into()).unwrap();
insta::assert_debug_snapshot!("1-parsed", parsed); insta::assert_debug_snapshot!("1-parsed", parsed);
let ast = temple::ast::parse(parsed.tokens()).unwrap(); let ast = nomo::ast::parse(parsed.tokens()).unwrap();
insta::assert_debug_snapshot!("2-ast", ast); insta::assert_debug_snapshot!("2-ast", ast);
let emit = temple::emit::emit_machine(ast); let emit = nomo::emit::emit_machine(ast);
insta::assert_debug_snapshot!("3-instructions", emit); insta::assert_debug_snapshot!("3-instructions", emit);
let output = temple::eval::execute(&emit, &context).unwrap(); let output = nomo::eval::execute(&emit, &context).unwrap();
insta::assert_debug_snapshot!("4-output", output); insta::assert_debug_snapshot!("4-output", output);
}); });