Take AsRef<str> argument and return Cow<str>

The function should accept a word that can be &str or String. Then, I want to allocate a new String for the modified word during formatting if it's needed and return the value as a Cow.

fn format_word<'a>(&self, w: impl AsRef<str> + 'a) -> Cow<'a, str> {
        let w = w.as_ref();
        
        let is_correct = w
            .chars()
            .all(|c| c.is_lowercase() && !self.ignore_chars.contains(c));

        if is_correct {
            Cow::Borrowed(w)
        } else {
            Cow::Owned(
                w.chars()
                    .filter(|c| !self.ignore_chars.contains(c.clone()))
                    .collect::<String>()
                    .to_lowercase(),
            )
        }
    }

But the compiler complaining about the following.

error[E0515]: cannot return value referencing function parameter `w`
    |
165 |         let w = w.as_ref();
    |                 ---------- `w` is borrowed here
...
172 |             Cow::Borrowed(w)
    |             ^^^^^^^^^^^^^^^^ returns a value referencing data owned by the current function

Is it fixable?

I will leave the original and correct version of the function to maybe give you more context on what I'm trying to achieve.

fn format_word<'a>(&self, w: &'a str) -> Cow<'a, str> {
        let is_correct = w
            .chars()
            .all(|c| c.is_lowercase() && !self.ignore_chars.contains(c));

        if is_correct {
            Cow::Borrowed(w)
        } else {
            Cow::Owned(
                w.chars()
                    .filter(|c| !self.ignore_chars.contains(c.clone()))
                    .collect::<String>()
                    .to_lowercase(),
            )
        }
    }

This works well, but only with &str and sometimes it isn't enough.

If w is a String then that string will move into format_word and will be dropped, so the Cow can't reference it. In other words you're trying to use the lifetime created at w.as_ref() for the Cow which won't live after the function.

You could move that lifetime to a reference to w, which may not work depending on how this function is used
fn format_word<'a>(&self, w: &'a impl AsRef<str>) -> Cow<'a, str> {}

If the goal is to avoid copying data around and be kind of flexible you could consider using a Cow for w.

Maybe impl Into<Cow, 'a> could work I haven't experimented with that.

3 Likes

I too thought of Into<Cow<'a, str>>, and here's what that may look like.

2 Likes

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.