Repository: typst/typst
File: crates/typst-library/src/foundations/str.rs (Rust)

Code before:
/// The numbers 1 to 10.
/// ```
#[ty(scope)]
#[derive(Debug, Clone)]
pub struct Regex(regex::Regex);

impl Regex {
    /// Create a new regular expression.
    pub fn new(re: &str) -> StrResult<Self> {
        regex::Regex::new(re).map(Self).map_err(|err| eco_format!("{err}"))
    }
}

#[scope]
impl Regex {
    /// Create a regular expression from a string.
    #[func(constructor)]
    pub fn construct(
        /// The regular expression as a string.
        ///
        /// Both Typst strings and regular expressions use backslashes for
        /// escaping. To produce a regex escape sequence that is also valid in
        /// Typst, you need to escape the backslash itself (e.g., writing
        /// `{regex("\\\\")}` for the regex `\\`). Regex escape sequences that
        /// are not valid Typst escape sequences (e.g., `\d` and `\b`) can be
        /// entered into strings directly, but it's a good practice to still
        /// escape them to avoid ambiguity (i.e., `{regex("\\b\\d")}`). See the
        /// [list of valid string escape sequences]($str.escapes).
        ///
        /// If you need many escape sequences, you can also create a raw element
        /// and extract its text to use it for your regular expressions:
        /// ``{regex(`\d+\.\d+\.\d+`.text)}``.
        regex: Spanned<Str>,
    ) -> SourceResult<Regex> {
        Self::new(&regex.v).at(regex.span)
    }
}

impl Deref for Regex {
    type Target = regex::Regex;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl Repr for Regex {
    fn repr(&self) -> EcoString {
        eco_format!("regex({})", self.0.as_str().repr())
    }
}

Review comment (suggestion):
```suggestion
        /// entered into strings directly, but it's good practice to still
```
this was changed from my proposal, but this one reads better to me (ChatGPT agrees and English is the one thing it's good at...)

Code after:
        index,
        len
    )
}

/// The char boundary access error message.
#[cold]
fn not_a_char_boundary(index: i64) -> EcoString {
    eco_format!("string index {} is not a character boundary", index)
}

/// The error message when the string is empty.
#[cold]
fn string_is_empty() -> EcoString {
    "string is empty".into()
}

/// A regular expression.
///
/// Can be used as a [show rule selector]($styling/#show-rules) and with
/// [string methods]($str) like `find`, `split`, and `replace`.
///
/// [See here](https://docs.rs/regex/latest/regex/#syntax) for a specification
/// of the supported syntax.
///
/// # Example
/// ```example
/// // Works with string methods.
/// #"a,b;c".split(regex("[,;]"))
///
/// // Works with show rules.
/// #show regex("\\d+"): set text(red)
///
/// The numbers 1 to 10.
/// ```
#[ty(scope)]
#[derive(Debug, Clone)]
pub struct Regex(regex::Regex);

impl Regex {
    /// Create a new regular expression.
    pub fn new(re: &str) -> StrResult<Self> {
        regex::Regex::new(re).map(Self).map_err(|err| eco_format!("{err}"))
    }
}

#[scope]
impl Regex {
    /// Create a regular expression from a string.
    #[func(constructor)]
    pub fn construct(