1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/*
SPDX-License-Identifier: GPL-3.0-only
Copyright (C) 2024 Attilio DonĂ attilio.dona@gmail.com
Copyright (C) 2024 Claudio Carraro carraro.claudio@gmail.com
*/
//! # Opifex
//!
//! [Opifex][wiki] is a Latin word meaning *artisan* or *manufacturer* and referring to
//! a **worker** who created something. This crate defines a [`Worker<Mode>`] struct
//! that, like the web worker interface, represents a task which can communicate
//! back to its creator and that is able to receive messages from it.
//!
//! # Quick Start
//!
//! `Opifex` usage is very simple and intuitive.
//!
//! Suppose we need to implement a simple task: adds two integer numbers, let
//! say `a` and `b`. We can create a simple struct:
//!
//!```rust
//! #[derive(Clone, Debug)]
//! pub struct Sum {
//! a: i32,
//! b: i32,
//! }
//!```
//!
//! This struct will be the message we'll send to the following Adder task:
//!
//!```rust
//! pub struct Adder {}
//!
//! impl Task for Adder {
//! type Handle = handle::Worker<handle::TwoWay<Sum, Result>>;
//! type Output = usize;
//!
//! fn spawn(
//! &self,
//! wk_hnd: Self::Handle,
//! ) -> impl std::future::Future<Output = Self::Output> + Send + 'static {
//! let (mut rx, hnd) = wk_hnd.receiver();
//!
//! async move {
//! let mut count: usize = 0;
//!
//! loop {
//! tokio::select! {
//! Some(sum) = rx.recv() => {
//! count += 1;
//! if let Err(e) = hnd.post_message(Result::from(sum)).await {
//! println!("Oops! Sending message reports: {e}");
//! }
//! }
//! () = hnd.terminated() => {
//! println!("Worker is terminated. Bye from adder task!");
//! break;
//! }
//! }
//! }
//!
//! count
//! }
//! }
//! }
//!```
//!
//! Having such a task, and wanting to receive its results we can simply spawn
//! a worker with:
//!
//!```rust
//! let adder_worker = Worker::<TwoWay<Sum, Result>>::spawn(Adder {});
//!```
//!
//! In the same way we can implement a Response task and add it as a subscriber
//! to events generated in the Adder task. To do this we use the function
//! on_message:
//!
//!```rust
//! let response_worker = adder_worker.on_message(Response {});
//!```
//!
//! Now we can send Sum messages to the Adder task with:
//!
//!```rust
//! if let Err(e) = adder_worker.post_message(Sum { a: 24, b: 28 }).await {
//! eprintln!("Oops! sending a message to adder reports: {e}");
//! }
//!```
//!
//! The full example can be found in examples folder.
//!
//! [wiki]: https://en.wikipedia.org/wiki/Opifex
use ;
pub use Worker;
// default mpcs channel's buffer capacity
pub const BUFFER_CAPACITY: usize = 1000;
/// The goal of [`Worker`] is to spawn and communicate to and/or control a `task`.
/// To do so the worker needs to inject in the task a sort of handle that can
/// be used from inside of the task to dialogate with its worker.
///
/// To fullfill this goal, the trait [`Task`] was defined.
///
/// [`Worker`]: Worker<Mode>