pub trait Job {
fn encode(&self) -> Vec<u8>;
fn decode(input: &[u8]) -> Self;
fn ack(&self) -> Vec<u8>;
fn run(&self) -> std::result::Result<(), Box<dyn std::error::Error>>;
}
#[cfg(test)]
mod tests {
use super::*;
use crate::*;
use rmp_serde as rmps;
enum MsgType {
Hello,
Unknown,
}
impl From<u8> for MsgType {
fn from(t: u8) -> MsgType {
match t {
0 => MsgType::Hello,
_ => MsgType::Unknown,
}
}
}
impl From<MsgType> for u8 {
fn from(t: MsgType) -> u8 {
match t {
MsgType::Hello => 0,
MsgType::Unknown => 255,
}
}
}
#[derive(Default, Debug, Clone, PartialEq, PartialOrd, Serialize, Deserialize)]
pub struct Hello {
name: String,
age: u8,
}
impl Job for Hello {
fn encode(&self) -> Vec<u8> {
rmps::to_vec(&self).unwrap()
}
fn decode(input: &[u8]) -> Hello {
let hello: Hello = rmps::from_read(input).unwrap();
hello
}
fn ack(&self) -> Vec<u8> {
let name = &self.name;
let age = &self.age;
let ack_string = format!("Hello from {name}, aged {age}");
Vec::from(ack_string)
}
fn run(&self) -> std::result::Result<(), Box<dyn std::error::Error>> {
self.ack();
Ok(())
}
}
#[test]
fn test_job_encode_decode() {
let hello = Hello {
name: "Anthony J. Martinez".to_owned(),
age: 38,
};
let encoded = hello.encode();
let decoded = Hello::decode(&encoded);
assert_eq!(hello, decoded)
}
#[test]
fn test_job_ack() {
let hello = Hello {
name: "Anthony J. Martinez".to_owned(),
age: 38,
};
let hello_vec = hello.ack();
assert_eq!(
hello_vec,
Vec::from("Hello from Anthony J. Martinez, aged 38")
)
}
#[test]
fn test_job_run() {
let hello = Hello {
name: "Anthony J. Martinez".to_owned(),
age: 38,
};
assert!(hello.run().is_ok())
}
}