# HasA ```rust= /// A timer_list wrapper. #[pin_data] // also need pin drop struct Timer{ #[pin] opaque: Opaque<bindings::timer_list> } /// Timeout is a sub trait of `Field`. pub trait Timeout: Field<Type=Timer> { fn timeout(base: &(<Self as Field>::Base)); } /// The actual C function pointer set when a timer is created. /// It will be called when time is up. extern "C" fn bridge<F: Timeout>(ptr: *mut timer_list) { // container_of! let t = unsafe { *(unproject::<F as Field>(ptr)) }; F::timeout(t); } impl Timer { pub fn new<F: Timeout>(..) -> impl PinInit<Self> { pin_init!(Self { opaque <- Opaque::ffi_init(|timer_list| { unsafe { bindings::init_timer_list( ..., bridge::<F>, ) } }) }) } } /// As long as "has a timer", you can schedule one, need /// to specify which via `field_of!`. impl<T> for T { fn schedule<F>(&self, timeout: Duration) where F: Timeout + Field<Base=T>, { let timer = project<F>(self); unsafe { bindings::mod_timer(timer, timeout.to_jiffies()); } } } impl Foo { /// Different timers may share the same timeout function. pub fn timeout(&self) { todo!(); } } impl Timeout for field_of!(Foo, timer) { fn timeout(foo: &Foo) { foo.timeout(); } } impl Timeout for field_of!(Foo, timer2) { fn timeout(foo: &Foo) { foo.timeout(); } } /// Consider we have a struct has two timers #[pin_data] struct Foo { x: X, y: Y, #[pin] timer: Timer, #[pin] timer2: Timer, } fn main() { stack_pin_init!( let foo = Foo { .. timer <- Timer::new::<field_of!(Foo, timer)>(..), timer2 <- Timer::new::<field_of!(Foo, timer2)>(..) } } foo.schedule::<field_of!(Foo, timer)>(); } ```