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);