Extracting name with regex and borrowing issue``

    /// Name extracted from the subject.
    /// May return an empty string if there's no subject.
    pub fn name(&self) -> &str {
        let re1 = regex!(r#"..."#);
        let re2 = regex!(r"...");

        if let Some(captured) = re1.captures(&self.subject) {
            return captured[1].trim();
        }

        if let Some(captured) = re2.captures(&self.subject) {
            return captured[1].trim();
        }
        ""
    }

The struct looks like this:

pub struct File {
    pub subject: String,
    /// more fields but not relevant here
}

Errors:

error[E0515]: cannot return value referencing local variable `captured`
   --> src\lib.rs:122:20
    |
122 |             return captured[1].trim();
    |                    --------^^^^^^^^^^
    |                    |
    |                    returns a value referencing data owned by the current function
    |                    `captured` is borrowed here

Aside from the error, I also have a question on whether I should return an empty string or say an Option? In my original python code this was:

    @cached_property
    def name(self) -> str:
        if parsed := re.search(r'"..."', self.subject):
            return parsed.group(1).strip()
        elif parsed := re.search(r"...", self.subject):
            return parsed.group(1).strip()
        else:
            return ""

The index operator can only return a reference with a short lifetime. See the docs. If you use get instead, this will work.

Use Option.

3 Likes

Does this look like the correct approach?

    pub fn name(&self) -> Option<&str> {
        let re1 = regex!(r#"..."#);
        let re2 = regex!(r"...");

        if let Some(captured) = re1.captures(&self.subject) {
            return captured.get(1).map_or(None, |m| Some(m.as_str().trim()));
        }

        if let Some(captured) = re2.captures(&self.subject) {
            return captured.get(1).map_or(None, |m| Some(m.as_str().trim()));
        }
        None
    }

Just use map or ?

captured.get(1).map(|m| m.as_str().trim())
// or
captured.get(1)?.as_str().trim()
2 Likes

Thank you!

1 Like