rexact-syntax 0.2.0

Regex parsers for ECMAScript, Python, Go, Rust, PCRE2 and Java dialects, with an error catalogue
Documentation
//! Dialect names (FR-A02).

use crate::error::{ErrorCode, RexactError};

/// A regex dialect. Patterns are interpreted by the rules of the dialect they
/// were written for (RULE-10).
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Dialect {
    /// ECMAScript.
    Ecma,
    /// Python `re`.
    Python,
    /// Go / RE2.
    Go,
    /// Rust `regex`.
    Rust,
    /// PCRE2.
    Pcre2,
    /// Java `java.util.regex` (not a column of the support matrix; see docs/13 notes).
    Java,
}

impl Dialect {
    /// All dialects, in matrix column order.
    pub const ALL: [Dialect; 5] = [
        Dialect::Ecma,
        Dialect::Python,
        Dialect::Go,
        Dialect::Rust,
        Dialect::Pcre2,
    ];

    /// Command-line name.
    pub const fn name(self) -> &'static str {
        match self {
            Dialect::Ecma => "ecma",
            Dialect::Python => "python",
            Dialect::Go => "go",
            Dialect::Rust => "rust",
            Dialect::Pcre2 => "pcre2",
            Dialect::Java => "java",
        }
    }

    /// Parse a dialect name; unknown names give `RX-P002` listing valid ones.
    pub fn from_name(s: &str) -> Result<Dialect, RexactError> {
        Dialect::ALL
            .into_iter()
            .chain([Dialect::Java])
            .find(|d| d.name() == s)
            .ok_or_else(|| {
                let valid: Vec<&str> = Dialect::ALL
                    .iter()
                    .chain([Dialect::Java].iter())
                    .map(|d| d.name())
                    .collect();
                let mut e = RexactError::new(ErrorCode::P002);
                e.detail = Some(format!("'{s}'; valid dialects: {}", valid.join(", ")));
                e
            })
    }
}