diffs-fancy-regex 0.1.0

Fork of fancy-regex 0.16.2 maintained only for diffs-rs: adds caller-owned search scratch, scoped engine sharing, and required-byte metadata. Use upstream fancy-regex (https://github.com/fancy-regex/fancy-regex) instead.
Documentation
use crate::{Expr, LookAround};

pub(crate) fn required(expr: &Expr) -> Option<u128> {
    match expr {
        Expr::Literal { val, casei: false } => Some(
            val.bytes()
                .filter(u8::is_ascii)
                .fold(0, |bytes, byte| bytes | (1u128 << byte)),
        ),
        Expr::Concat(children) => children
            .iter()
            .try_fold(0, |bytes, child| Some(bytes | required(child)?)),
        Expr::Alt(children) => children
            .iter()
            .try_fold(u128::MAX, |bytes, child| Some(bytes & required(child)?)),
        Expr::Group(child) | Expr::AtomicGroup(child) => required(child),
        Expr::LookAround(child, LookAround::LookAhead | LookAround::LookBehind) => required(child),
        Expr::Repeat { child, lo, .. } => {
            required(child).map(|bytes| if *lo == 0 { 0 } else { bytes })
        }
        Expr::Conditional { .. }
        | Expr::SubroutineCall(_)
        | Expr::UnresolvedNamedSubroutineCall { .. }
        | Expr::BackrefWithRelativeRecursionLevel { .. } => None,
        Expr::LookAround(child, _) => required(child).map(|_| 0),
        _ => Some(0),
    }
}