Skip to content

Commit

Permalink
feat: add callback
Browse files Browse the repository at this point in the history
  • Loading branch information
katopz committed Sep 13, 2023
1 parent 1102686 commit 4b25b68
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 1 deletion.
3 changes: 2 additions & 1 deletion src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@
- [Enum](rust/r3/enum.md)
- [Derive More](rust/r3/derive-more.md)
- [Typed Builder](rust/r3/typed-builder.md)
- [Generic array](rust/r3/generic-array.md)
- [Generic Array](rust/r3/generic-array.md)
- [AsRef](rust/r3/as-ref.md)
- [Callback](rust/r3/callback.md)
- [R2 - Expert](rust/r2/mod.md)
- [Hello Github Action](rust/r2/hello-github-action.md)
- [Hello Actix CloudRun](rust/r2/hello-actix-cloudrun.md)
Expand Down
130 changes: 130 additions & 0 deletions src/rust/r3/callback.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
# Create your own lib

## How to implement `callback`.

> 🤔 Refer to : https://stackoverflow.com/questions/41081240/idiomatic-callbacks-in-rust
### 1️⃣ Store the `callback` as `FnMut` in the `Box` with the callback setter generic on callback type. 🤯

```rust,editable
type Callback = fn();
struct Processor {
callback: Callback,
}
impl Processor {
fn set_callback(&mut self, c: Callback) {
self.callback = c;
}
fn process_events(&self) {
(self.callback)();
}
}
fn simple_callback() {
println!("hello world!");
}
fn main() {
let p = Processor {
callback: simple_callback,
};
p.process_events(); // hello world!
}
```

### 2️⃣ Callbacks as generic function objects

```rust,editable
struct Processor<CB> {
callback: CB,
}
impl<CB> Processor<CB>
where
CB: FnMut(),
{
fn set_callback(&mut self, c: CB) {
self.callback = c;
}
fn process_events(&mut self) {
(self.callback)();
}
}
fn main() {
let s = "world!".to_string();
let callback = || println!("hello {}", s);
let mut p = Processor { callback };
p.process_events();
}
```

### 3️⃣ Non-generic callbacks: function trait objects

```rust,editable
struct Processor {
callback: Box<dyn FnMut()>,
}
impl Processor {
fn set_callback(&mut self, c: impl FnMut() + 'static) {
self.callback = Box::new(c);
}
fn process_events(&mut self) {
(self.callback)();
}
}
fn simple_callback() {
println!("hello");
}
fn main() {
let mut p = Processor {
callback: Box::new(simple_callback),
};
p.process_events();
let s = "world!".to_string();
let callback2 = move || println!("hello {}", s);
p.set_callback(callback2);
p.process_events();
}
```

### 4️⃣ Lifetime of references inside boxed closures

```rust,editable
struct Processor<'a> {
callback: Box<dyn FnMut() + 'a>,
}
impl<'a> Processor<'a> {
fn set_callback(&mut self, c: impl FnMut() + 'a) {
self.callback = Box::new(c);
}
fn process_events(&mut self) {
(self.callback)();
}
}
fn simple_callback() {
println!("hello");
}
fn main() {
let mut p = Processor {
callback: Box::new(simple_callback),
};
p.process_events();
let s = "world!".to_string();
let callback2 = move || println!("hello {}", s);
p.set_callback(callback2);
p.process_events();
}
```

0 comments on commit 4b25b68

Please sign in to comment.