# 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)>();
}
```