Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use std::string::String;
- trait Protocol {
- type Handler:?Sized;
- }
- // Generic payload for a message.
- trait Payload<P: Protocol> {
- fn accept(&self, msg: &Message<P>, handler: &P::Handler);
- }
- // Generic message as e.g. created by reading from a stream.
- // This can be used by the library code since it is not dependent on any
- // protocol or payload type.
- struct Message<P: Protocol> {
- common_field: i32,
- payload: Box<dyn Payload<P>>,
- }
- // Adaptor function to allow visiting messages directly even if the actual
- // visitor pattern is implemented over payloads.
- fn accept<P: Protocol>(msg: &Message<P>, handler: &P::Handler) {
- msg.payload.accept(msg, handler)
- }
- // Example protocol.
- struct S1Protocol;
- impl Protocol for S1Protocol {
- type Handler = S1Handler;
- }
- // Protocol-specific handler for handling masseges with a particular types.
- // This de-facto describes avalable message types handled by the protocol.
- trait S1Handler {
- fn visit_authorize(&self, msg: &Message<S1Protocol>, payload: &Authorize);
- fn visit_subscribe(&self, msg: &Message<S1Protocol>, payload: &Subscribe);
- }
- // Example message type
- struct Authorize {
- name: String,
- }
- impl Payload<S1Protocol> for Authorize {
- fn accept(&self, message: &Message<S1Protocol>, handler: &<S1Protocol as Protocol>::Handler) {
- handler.visit_authorize(message, self)
- }
- }
- // Example message type
- struct Subscribe;
- impl Payload<S1Protocol> for Subscribe {
- fn accept(&self, message: &Message<S1Protocol>, handler: &<S1Protocol as Protocol>::Handler) {
- handler.visit_subscribe(message, self)
- }
- }
- // Example of possible handler. This just prints a message.
- struct PrintHandler;
- impl S1Handler for PrintHandler {
- fn visit_authorize(&self, msg: &Message<S1Protocol>, payload: &Authorize) {
- println!("Authorize: {} {}", msg.common_field, payload.name);
- }
- fn visit_subscribe(&self, msg: &Message<S1Protocol>, _payload: &Subscribe) {
- println!("Subscribe: {}", msg.common_field);
- }
- }
- fn main() {
- let m1 = Message::<S1Protocol> {
- common_field: 1,
- payload: Box::new(
- Authorize {name: "name".to_string()}
- ),
- };
- let m2 = Message::<S1Protocol> {
- common_field: 2,
- payload: Box::new(
- Subscribe{}
- ),
- };
- let h = PrintHandler{};
- accept(&m1, &h);
- accept(&m2, &h);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement