use std::borrow::Cow;
use std::fmt::{self, Display, Formatter};
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum Identifier<'a> {
Named(&'a str),
Indexed(usize),
}
impl Display for Identifier<'_> {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
match self {
Self::Named(name) => write!(f, "{name}"),
Self::Indexed(index) => write!(f, "{index}"),
}
}
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum Modifier {
Upper { all: bool },
Lower { all: bool },
Reverse { all: bool },
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum Param<'a> {
Simple {
identifier: Identifier<'a>,
modifier: Option<Modifier>,
},
WithDefault {
identifier: Identifier<'a>,
default: Vec<Node<'a>>,
treat_empty_as_unset: bool,
},
WithAlt {
identifier: Identifier<'a>,
alt: Vec<Node<'a>>,
treat_empty_as_unset: bool,
},
WithError {
identifier: Identifier<'a>,
error: Vec<Node<'a>>,
treat_empty_as_unset: bool,
},
Length {
identifier: Identifier<'a>,
},
Arity,
Ref {
identifier: Identifier<'a>,
},
PrefixRemoval {
identifier: Identifier<'a>,
pattern: Vec<Node<'a>>,
greedy: bool,
},
SuffixRemoval {
identifier: Identifier<'a>,
pattern: Vec<Node<'a>>,
greedy: bool,
},
Replace {
identifier: Identifier<'a>,
pattern: Vec<Node<'a>>,
replacement: Vec<Node<'a>>,
all_occurrences: bool,
},
Sub {
identifier: Identifier<'a>,
offset: isize,
length: Option<isize>,
},
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum Node<'a> {
Text { value: Cow<'a, str>, literal: bool },
Param(Param<'a>),
}
impl<'a> Node<'a> {
pub fn text(value: impl Into<Cow<'a, str>>) -> Self {
Self::Text {
value: value.into(),
literal: false,
}
}
pub fn literal(value: impl Into<Cow<'a, str>>) -> Self {
Self::Text {
value: value.into(),
literal: true,
}
}
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct Ast<'a> {
pub nodes: Vec<Node<'a>>,
}
impl<'a> Ast<'a> {
pub const fn new(nodes: Vec<Node<'a>>) -> Self {
Self { nodes }
}
}