Recently, I've been diving into the serde library, and when it comes to the from-trait method, I find it quite puzzling. It seems to attempt to call deserialize on the trait de::Deserialize and pass in a deserializer, but I'm unsure how Rust determines which concrete type the deserialize method will be called on ? What concept in rust facilitates that ?
fn from_trait<'de, R, T>(read: R) -> Result<T>
where
R: Read<'de>,
T: de::Deserialize<'de>,
{
let mut de = Deserializer::new(read);
let value = tri!(de::Deserialize::deserialize(&mut de));
// Make sure the whole stream has been consumed.
tri!(de.end());
Ok(value)
}
pub trait Deserialize<'de>: Sized {
/// Deserialize this value from the given Serde deserializer.
///
/// See the [Implementing `Deserialize`][impl-deserialize] section of the
/// manual for more information about how to implement this method.
///
/// [impl-deserialize]: https://serde.rs/impl-deserialize.html
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>;
I can't find this method in Serde code base, so all of the following is mostly guessing, but probably right.
This is simply type inference.
from_trait returns Result<T> - here, Result is a type alias to something like Result<T, serde::Error>. That is, we know that Ok(value) at the end of the function is of type Result<T, _>, and therefore value is of type T. Then, Deserialize::deserialize returns Result<Self, _>, and tri! macro unwraps this Result to get Self, which is then assigned to value; therefore, this Self (i.e. the type method is called on) is T, too.