struct_threads/traits.rs
1/// A trait for defining a task that can be executed, typically in a separate thread.
2///
3/// Types implementing `Runnable` must be `Send` and `'static` to ensure they
4/// can be safely transferred across thread boundaries. By encapsulating state
5/// within a struct that implements this trait, you can easily manage complex
6/// thread initialization.
7///
8/// # Examples
9///
10/// ```rust
11/// use struct_threads::Runnable;
12///
13/// struct GreetingTask {
14/// name: String,
15/// }
16///
17/// impl Runnable for GreetingTask {
18/// type Output = String;
19///
20/// fn run(self) -> Self::Output {
21/// format!("Hello, {}!", self.name)
22/// }
23/// }
24/// ```
25pub trait Runnable: Send + 'static {
26 /// The type of value returned when the task completes.
27 type Output: Send + 'static;
28
29 /// Executes the task logic.
30 ///
31 /// This method consumes the task (`self`), meaning the state cannot be
32 /// reused after the thread has finished executing.
33 fn run(self) -> Self::Output;
34}
35
36/// An extension trait that provides a method to spawn a thread for a [`Runnable`] task.
37///
38/// This trait is automatically implemented for any type that implements `Runnable`.
39/// You do not need to implement this trait manually.
40pub trait Thread: Runnable {
41 /// Spawns a new standard library thread to execute the `run` method.
42 ///
43 /// This acts as a zero-cost abstraction over [`std::thread::spawn`].
44 ///
45 /// # Returns
46 ///
47 /// Returns a [`std::thread::JoinHandle`] that can be used to wait for the thread
48 /// to finish and extract its `Output`.
49 ///
50 /// # Examples
51 ///
52 /// ```rust
53 /// use struct_threads::{Runnable, Thread};
54 ///
55 /// struct MathTask(i32, i32);
56 ///
57 /// impl Runnable for MathTask {
58 /// type Output = i32;
59 /// fn run(self) -> Self::Output {
60 /// self.0 + self.1
61 /// }
62 /// }
63 ///
64 /// let task = MathTask(5, 7);
65 /// let handle = task.start(); // Provided by the Thread trait
66 ///
67 /// assert_eq!(handle.join().unwrap(), 12);
68 /// ```
69 fn start(self) -> std::thread::JoinHandle<Self::Output>;
70}
71
72impl<T: Runnable> Thread for T {
73 fn start(self) -> std::thread::JoinHandle<Self::Output> {
74 std::thread::spawn(move || self.run())
75 }
76}