Skip to content

Instantly share code, notes, and snippets.

@haraldh
Created June 23, 2020 11:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save haraldh/47789f21923b54284fdac5fcc11b9ef6 to your computer and use it in GitHub Desktop.
Save haraldh/47789f21923b54284fdac5fcc11b9ef6 to your computer and use it in GitHub Desktop.
use &mut T, Box<T> and &mut dyn T in one function
use std::ops::DerefMut;
use std::thread::sleep;
use std::time::Duration;
trait DigitalInput {
fn set_state(&mut self, _new_state: bool);
}
trait Mutable<T: ?Sized> {
fn ref_mut(&mut self) -> &mut T;
}
impl<'a, T: ?Sized> Mutable<T> for &'a mut T {
fn ref_mut(&mut self) -> &'_ mut T {
self
}
}
impl<T: ?Sized> Mutable<T> for Box<T> {
fn ref_mut(&mut self) -> &'_ mut T {
self.deref_mut()
}
}
fn flash_periodically<L: Mutable<P>, P: DigitalInput + ?Sized>(mut lamp: L, interval: Duration) {
let mut current_state = false;
loop {
lamp.ref_mut().set_state(current_state);
current_state = !current_state;
sleep(interval);
}
}
struct Pin;
impl DigitalInput for Pin {
fn set_state(&mut self, _new_state: bool) {
unimplemented!()
}
}
fn main() {
let pin: &mut Pin = &mut Pin;
flash_periodically(pin, Duration::from_millis(100));
let pin: Box<dyn DigitalInput> = Box::new(Pin);
flash_periodically(pin, Duration::from_millis(100));
let pin: &mut dyn DigitalInput = &mut Pin;
flash_periodically(pin, Duration::from_millis(100));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment