node_workers/
as_payload.rs

1use std::path::PathBuf;
2
3use serde_json::{json, Value};
4
5/// Represents an empty payload that can be sent to a node worker
6/// ```
7/// use node_workers::{EmptyPayload, WorkerPool};
8/// # use std::error::Error;
9///
10/// # fn main() -> Result<(), Box<dyn Error>> {
11/// let mut pool = WorkerPool::setup("examples/worker", 1);
12/// let payloads = vec![EmptyPayload::new(), EmptyPayload::new()];
13/// pool.perform::<(), _>("ping", payloads)?;
14/// # Ok(())
15/// # }
16/// ```
17pub struct EmptyPayload {}
18impl EmptyPayload {
19  pub fn new() -> EmptyPayload {
20    EmptyPayload {}
21  }
22  /// Convenient method to create an array of empty payload
23  /// ```
24  /// use node_workers::{EmptyPayload, WorkerPool};
25  /// # use std::error::Error;
26  ///
27  /// # fn main() -> Result<(), Box<dyn Error>> {
28  /// let mut pool = WorkerPool::setup("examples/worker", 1);
29  /// let payloads = EmptyPayload::bulk(2);
30  /// pool.perform::<(), _>("ping", payloads)?;
31  /// # Ok(())
32  /// # }
33  /// ```
34  pub fn bulk(n: u32) -> Vec<EmptyPayload> {
35    (0..n).into_iter().map(|_| EmptyPayload::new()).collect()
36  }
37}
38impl Default for EmptyPayload {
39  fn default() -> Self {
40    Self::new()
41  }
42}
43impl AsPayload for EmptyPayload {
44  fn to_payload(self) -> Value {
45    Value::Null
46  }
47}
48
49/// Represent a data that can be sent to a node worker.
50/// Under the hood, node worker can only receive and transfer back serde_json::Value.
51/// This trait is mainly for convenience as it is already implemented for all primitive types, and lets you
52/// send all kinds of data to a node worker without boilerplate.
53pub trait AsPayload {
54  fn to_payload(self) -> Value;
55}
56
57impl AsPayload for Value {
58  fn to_payload(self) -> Value {
59    self
60  }
61}
62
63impl<T: AsPayload> AsPayload for Option<T> {
64  fn to_payload(self) -> Value {
65    if let Some(val) = self {
66      val.to_payload()
67    } else {
68      Value::Null
69    }
70  }
71}
72
73impl AsPayload for PathBuf {
74  fn to_payload(self) -> Value {
75    self.to_str().unwrap().to_payload()
76  }
77}
78
79macro_rules! impl_all {
80    ($($ty: ty),*) => {
81        $(
82            impl AsPayload for $ty {
83                fn to_payload(self) -> Value {
84                    json!({ "_inner_payload": self})
85                }
86            }
87        )*
88    }
89}
90
91/// A macro to quickly create an array of payload. This is usefull for running a task with payloads of different types.
92/// ```
93/// use node_workers::{EmptyPayload, WorkerPool, AsPayload, make_payloads};
94/// # use std::error::Error;
95///
96/// # fn main() -> Result<(), Box<dyn Error>> {
97/// let mut pool = WorkerPool::setup("examples/worker", 1);
98/// let payloads = make_payloads!(EmptyPayload::new(), 20, "test");
99/// pool.perform::<(), _>("ping", payloads)?;
100/// # Ok(())
101/// # }
102/// ```
103#[macro_export]
104macro_rules! make_payloads {
105    ( $( $a:expr ),* ) => {
106      {
107        let mut vec: Vec<serde_json::Value> = Vec::new();
108        $( vec.push($a.to_payload()); )*
109        vec
110      }
111    };
112  }
113
114impl_all!(usize, isize, u8, i8, u16, i16, u32, i32, u64, i64, u128, i128, f32, f64, &str, String);