Repository: typst/typst
File: crates/typst-library/src/text/mod.rs (Rust)

Code before:

impl PlainText for Packed<TextElem> {
    fn plain_text(&self, text: &mut EcoString) {
        text.push_str(self.text());
    }
}

/// A lowercased font family like "arial".
#[derive(Debug, Clone)]
pub struct FontFamily {
    name: EcoString,
    coverage: Option<Regex>,
}

impl Hash for FontFamily {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.name.hash(state);
        self.coverage_str().hash(state);
    }
}

impl PartialEq for FontFamily {
    fn eq(&self, other: &Self) -> bool {
        self.name == other.name && self.coverage_str() == other.coverage_str()
    }
}

impl FontFamily {
    /// Create a named font family variant.
    pub fn new(string: &str) -> Self {
        Self::new_with_coverage(string, None).unwrap()
    }

    pub fn new_with_coverage(
        string: &str,
        coverage: Option<Value>,
    ) -> HintedStrResult<Self> {
        let coverage = match coverage {
            Some(Value::Str(name)) => {
                if &*name == "latin-in-cjk" {
                    static LATIN_IN_CJK_REGEX: LazyLock<Regex> = LazyLock::new(|| {
                        Regex::new( "[^\u{00B7}\u{2013}\u{2014}\u{2018}\u{2019}\u{201C}\u{201D}\u{2025}-\u{2027}\u{2E3A}]").unwrap()
                    });
                    Some(LATIN_IN_CJK_REGEX.clone())
                } else {
                    bail!("unknown character set");
                }
            }
            Some(coverage) => {
                let regex = coverage.cast::<Regex>()?;
                let ast = regex_syntax::ast::parse::Parser::new()

Review comment (suggestion):
Those can be derived since Typst's `Regex` type already handles this

Code after:
        // Instead, it leaves the passed argument structurally unchanged, but
        // styles all text in it.
        let styles = Self::set(engine, args)?;
        let body = args.expect::<Content>("body")?;
        Ok(body.styled_with_map(styles))
    }
}

impl PlainText for Packed<TextElem> {
    fn plain_text(&self, text: &mut EcoString) {
        text.push_str(self.text());
    }
}

/// A lowercased font family like "arial".
#[derive(Debug, Clone, PartialEq, Hash)]
pub struct FontFamily {
    // The name of the font family
    name: EcoString,
    // A regex that defines the Unicode codepoints supported by the font.
    covers: Option<Covers>,
}

impl FontFamily {
    /// Create a named font family variant.
    pub fn new(string: &str) -> Self {
        Self::with_coverage(string, None)
    }

    /// Create a font family by name and optional Unicode coverage.
    pub fn with_coverage(string: &str, covers: Option<Covers>) -> Self {
        Self { name: string.to_lowercase().into(), covers }
    }

    /// The lowercased family name.
    pub fn as_str(&self) -> &str {
        &self.name
    }

    /// The user-set coverage of the font family.
    pub fn covers(&self) -> Option<&Regex> {
        self.covers.as_ref().map(|covers| covers.as_regex())
    }
}

cast! {
    FontFamily,
    self => self.name.into_value(),
    string: EcoString => Self::new(&string),
    mut v: Dict => {
        let ret = Self::with_coverage(