Created
September 30, 2020 16:07
-
-
Save alerdenisov/ac0ae1db1bd4af4a9ee4dbb93d5db3e6 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// main.rs | |
pub fn start_foo_protocol(params: foo::FooParams) -> foo::FooExecution { | |
execute(params, foo::run) | |
} | |
///////// foo.rs | |
pub enum FooMessages { | |
MessageOne, | |
MessageTwo, | |
} | |
pub enum FooErrors { | |
ErrorOne, | |
ErrorTwo, | |
} | |
/// Result of protocol execution | |
pub struct FooResult; | |
/// Shorthand for protocol types definition | |
pub type FooProtocol = Protocol<FooMessages, FooResult, FooErrors>; | |
/// Shorthand for protocol execution definition | |
pub type FooExecution = ProtocolExecution<FooMessages, FooResult, FooErrors>; | |
/////// protocol.rs | |
/// Wrapped execution message | |
#[derive(Debug, Display, Clone, Serialize, Deserialize)] | |
#[serde(rename_all = "snake_case", tag = "event", content = "body")] | |
pub enum Protocol<TM, TR, TE> { | |
#[display(fmt = "Packet {} ({} -> {})", data, sender, target)] | |
/// Communication message | |
Packet { | |
/// Sender of message | |
sender: u16, | |
/// Target recipient of message | |
target: u16, | |
/// Message data | |
data: TM, | |
}, | |
#[display(fmt = "Complete")] | |
/// Protocol result message | |
Complete(TR), | |
#[display(fmt = "Quit")] | |
/// Exit message | |
Quit, | |
#[display(fmt = "Error: {:?}", _0)] | |
/// Error message | |
Error(TE), | |
#[display(fmt = "Log: {}", _0)] | |
/// Verbose logging message | |
Log(String), | |
} | |
/// Generic type to hold execution IO | |
pub struct ProtocolExecution<TM, TR, TE> { | |
/// Atomically referenced pointer to asynchronous message bus input | |
pub input: Sender<Protocol<TM, TR, TE>>, | |
/// Atomically referenced pointer to asynchronous message bus output | |
pub output: Receiver<Protocol<TM, TR, TE>>, | |
} | |
/// Generic wrapper about protocol execution function to auto generation IO message buses | |
pub fn execute<F, TParams, TM, TR, TE>(params: TParams, func: F) -> ProtocolExecution<TM, TR, TE> | |
where | |
F: Fn(TParams, &Receiver<Protocol<TM, TR, TE>>, &Sender<Protocol<TM, TR, TE>>) + Send + 'static, | |
TParams: Send + 'static, | |
TM: Send + 'static, | |
TR: Send + 'static, | |
TE: Send + 'static, | |
{ | |
let (input_sender, input_receiver) = channel(); | |
let (output_sender, output_receiver) = channel(); | |
spawn(move || { | |
func(params, &input_receiver, &output_sender); | |
}); | |
ProtocolExecution::new(input_sender, output_receiver) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment