A helpful resource for better understanding the Cow enum is The Secret Life of Cows. Be sure to click on the “playground” links in the discussion there on the serde crate.
Step-by-step, how to understand the describe() function example
(assuming I understand this, which is an if, a small if, but an if)
Part A - We can implement methods directly on shared references themselves. There is no dereferencing then (playground)
In a sense then the method implemented, when called on a shared reference, takes ownership of the shared reference, per se, not the value the shared reference points to.
use std::borrow::Cow; trait CustomInto<T> { fn custom_into(self) -> T; } impl<'a> CustomInto<Cow<'a, str>> for &'a str { fn custom_into(self) -> Cow<'a, str> { Cow::Borrowed(self) } } fn main(){ let _cow = "hello there".custom_into(); }
Part B -
Consider two traits
From<String>
From<&'a str>
Cow<'a, str> implements both traits
Cow has the associated function
fn from(s: String) → Cow<'a, str>
Cow has another associated function
fn from(s: &'a str) → Cow<'a, str>
Therefore String implements<
Consider the additional trait
Into<Cow<'a, str>>
String automatically implements Into, as does str, given that the From traits are implemented
Both String and str implement Into with a method of the following form
fn into(self) → Cow<a', str>
In the first four arms of the match expression, there are string literals upon which the method into() is called. We know the methods must have a return type of Cow<'static, str>.
A string literal is of type &str, a shared reference to a string slice.
When applying the method into(), the string literal is dereferenced into a string slice str
Then the method into() can be applied on the str. We have already seen that this method exists.