mod chars;
mod context;
mod generator;
mod node;
mod parse;
mod repr;
mod util;
use std::{
io::{Result, Write},
sync::LazyLock,
};
use crypto_bigint::{NonZero, U256};
use zeroize::Zeroizing;
pub use chars::{CharRange, Chars};
pub use context::Context;
pub use generator::{Generator, GeneratorFunc, Word, Words};
pub use node::Node;
pub use parse::Error as ParseError;
#[derive(Debug)]
pub struct Expr<'a> {
pub root: Node,
pub context: Option<&'a Context<'a>>,
}
pub trait Eval {
fn size(&self) -> NonZero<U256>;
fn write_to(&self, w: &mut dyn Write, index: Zeroizing<U256>) -> Result<()>;
}
pub trait EvalContext {
type Context<'a>: ?Sized + 'a;
fn size(&self, context: &Self::Context<'_>) -> NonZero<U256>;
fn write_to(
&self,
context: &Self::Context<'_>,
w: &mut dyn Write,
index: Zeroizing<U256>,
) -> Result<()>;
}
static DEFAULT_CONTEXT: LazyLock<Context<'static>> = LazyLock::new(Context::default);
impl Expr<'_> {
pub fn new(root: Node) -> Self {
Expr {
root,
context: None,
}
}
}
impl<'a> Expr<'a> {
pub fn with_context(root: Node, context: &'a Context<'a>) -> Self {
Expr {
root,
context: Some(context),
}
}
pub fn get_context(&self) -> &Context<'a> {
self.context.unwrap_or(&DEFAULT_CONTEXT)
}
}
impl Eval for Expr<'_> {
fn size(&self) -> NonZero<U256> {
self.root.size(self.get_context())
}
fn write_to(&self, w: &mut dyn Write, index: Zeroizing<U256>) -> Result<()> {
self.root.write_to(self.get_context(), w, index)
}
}