The From trait enables type conversions. Implementing From automatically gives you Into!
// Implementing From
impl From<i32> for MyType {
fn from(value: i32) -> Self {
MyType(value)
}
}
// You get Into for free!
let x: MyType = 42.into();
let y: MyType = MyType::from(42);Convention: Implement From, not Into. The blanket implementation handles Into automatically.
// String conversions
impl From<&str> for MyString {
fn from(s: &str) -> Self {
MyString(s.to_string())
}
}
// Error conversions
impl From<std::io::Error> for MyError {
fn from(e: std::io::Error) -> Self {
MyError::Io(e)
}
}// 1 SOL = 1,000,000,000 lamports
const LAMPORTS_PER_SOL: u64 = 1_000_000_000;
struct Lamports(u64);
struct Sol(f64);
impl From<Sol> for Lamports {
fn from(sol: Sol) -> Self {
Lamports((sol.0 * LAMPORTS_PER_SOL as f64) as u64)
}
}
impl From<Lamports> for Sol {
fn from(lamports: Lamports) -> Self {
Sol(lamports.0 as f64 / LAMPORTS_PER_SOL as f64)
}
}impl TryFrom<i64> for Lamports {
type Error = &'static str;
fn try_from(value: i64) -> Result<Self, Self::Error> {
if value < 0 {
Err("Lamports cannot be negative")
} else {
Ok(Lamports(value as u64))
}
}
}Implement From conversions between Sol and Lamports:
Sol(1.5).into() → Lamports(1_500_000_000)Lamports(1_500_000_000).into() → Sol(1.5)impl From<Sol> for Lamports {
fn from(sol: Sol) -> Self {
Lamports((sol.0 * 1_000_000_000.0) as u64)
}
}
impl From<Lamports> for Sol {
fn from(lamports: Lamports) -> Self {
Sol(lamports.0 as f64 / 1_000_000_000.0)
}
}