#[client_task_enum]Expand description
§#[client_task_enum]
The #[client_task_enum] attribute is applied to an enum to delegate ClientTask related trait
implementations to its variants. Each variant must wrap a struct that is a valid client task
(often decorated with #[client_task])
This macro generates From implementations for each variant, allowing for easy conversion
from a specific task struct to the enum. It also delegates methods from ClientTask,
ClientTaskEncode, and ClientTaskDecode to the inner task.
client_task_enum also require error flag, specified the custom error type for RpcError<E: RpcErrCodec>
§#[action] on enum variants
As an alternative to defining the action inside the subtype, you can specify a static action
directly on an enum variant using the #[action(...)] attribute. Only one action (numeric, or
string literal, or numeric enum) is allowed per variant.
When #[action(...)] is used on a variant, the inner type does not need to define an action in this case,
but if it does, the enum’s action will take precedence.
§Example:
use razor_stream::client::task::{ClientTask, ClientTaskCommon, ClientTaskAction, ClientTaskDone};
use razor_stream::error::RpcError;
use nix::errno::Errno;
use razor_stream_macros::{client_task, client_task_enum};
use serde_derive::{Deserialize, Serialize};
use crossfire::{mpsc, MTx};
#[derive(PartialEq, Debug)]
#[repr(u8)]
enum FileAction {
Open = 1,
Close = 2,
}
// Action can be specified in the FileTask enum
#[client_task(debug)]
pub struct FileOpenTask {
#[field(common)]
common: ClientTaskCommon,
#[field(req)]
req: String,
#[field(resp)]
resp: Option<()>,
#[field(res)]
res: Option<Result<(), RpcError<Errno>>>,
#[field(noti)]
noti: Option<MTx<mpsc::List<FileTask>>>,
}
// Action can be either with client_task
#[client_task(FileAction::Close, debug)]
pub struct FileCloseTask {
#[field(common)]
common: ClientTaskCommon,
#[field(req)]
req: (),
#[field(resp)]
resp: Option<()>,
#[field(res)]
res: Option<Result<(), RpcError<Errno>>>,
#[field(noti)]
noti: Option<MTx<mpsc::List<FileTask>>>,
}
#[client_task_enum(error=Errno)]
#[derive(Debug)]
pub enum FileTask {
#[action(FileAction::Open)]
Open(FileOpenTask),
Close(FileCloseTask),
}
// Usage
let (tx, rx) = mpsc::unbounded_blocking();
// Test Open Task
let open_task = FileOpenTask {
common: ClientTaskCommon::default(),
req: "/path/to/file".to_string(),
resp: None,
res: None,
noti: Some(tx.clone()),
};
let mut file_task: FileTask = open_task.into();
assert_eq!(file_task.get_action(), razor_stream::proto::RpcAction::Num(1));
file_task.set_ok();
file_task.done();
let received = rx.recv().unwrap();
assert!(matches!(received, FileTask::Open(_)));
// Test Close Task
let close_task = FileCloseTask {
common: ClientTaskCommon::default(),
req: (),
resp: None,
res: None,
noti: Some(tx),
};
let mut file_task: FileTask = close_task.into();
assert_eq!(file_task.get_action(), razor_stream::proto::RpcAction::Num(2));
file_task.set_ok();
file_task.done();
let received = rx.recv().unwrap();
assert!(matches!(received, FileTask::Close(_)));