Skip to content

Instantly share code, notes, and snippets.

@aib
Last active November 22, 2022 12:35
Show Gist options
  • Save aib/9c076f3d0c99789463f652e5e86572a1 to your computer and use it in GitHub Desktop.
Save aib/9c076f3d0c99789463f652e5e86572a1 to your computer and use it in GitHub Desktop.
use std::sync::Arc;
type Log = Box<dyn Fn(&str)>;
struct OpenLibrary {
pub log: Log,
}
struct OpenDevice {
library: Arc<OpenLibrary>,
}
impl OpenLibrary {
pub fn new(log: Log) -> Arc<OpenLibrary> {
log("Open library");
Arc::new(OpenLibrary { log })
}
pub fn do_use(&self) {
(self.log)(" Use library");
}
pub fn open_device(self: Arc<Self>) -> OpenDevice {
OpenDevice::new(self.clone())
}
}
impl Drop for OpenLibrary {
fn drop(&mut self) {
(self.log)("Close library");
}
}
impl OpenDevice {
fn new(library: Arc<OpenLibrary>) -> OpenDevice {
(library.log)(" Open device");
OpenDevice { library }
}
pub fn do_use(&self) {
(self.library.log)(" Use device");
}
pub fn close(self) -> Arc<OpenLibrary> {
self.library.clone()
}
}
impl Drop for OpenDevice {
fn drop(&mut self) {
(self.library.log)(" Close device");
}
}
fn main() {
let log = |s: &str| { println!("{}", s) };
{ // Case 1: Lib -> Dev -> Done
let lib = OpenLibrary::new(Box::new(log));
lib.do_use();
let dev = lib.open_device();
dev.do_use();
}
{ // Case 2: Lib -> Dev -> Lib -> Done
let lib = OpenLibrary::new(Box::new(log));
lib.do_use();
let dev = lib.open_device();
dev.do_use();
let lib = dev.close();
lib.do_use();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment