Skip to main content

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}