#Working with futures

1 messages · Page 1 of 1 (latest)

hollow sky
#

I am trying to create amqp message processor. I wish to create similar API to one that described in fn main()
Unfortunately, i am unable to access message on line 25,
Is there any proper way to do this or I should wait for TAIT's?

hazy ridge
#

what would the use of TAIT be here?

hollow sky
#

yes, so it will be one processing function, but if I want to do

amqp.handler::<DemoMessage>(Box::pin(async |message| {
        println!("processing DemoMessage {:#?}", message);
    }));

then I am unable to do that. because then I should type
pub callback: Vec<(TypeId, Fun<'a, T>)>,
after Subscriber will be Subscriber<T>, so it will be impossible to add more handlers.

#

TAIT would allow me to do such

use std::{any::Any, fmt::Debug};

trait Job {
    type Message: Debug;
    fn run(&self, message: Self::Message);
}

struct Subscriber {
    handlers: Vec<Box<dyn Job<Message = dyn Any>>>,
}

impl Subscriber {
    fn add_handler<'a, T: Job<Message = dyn Any>>(&mut self, handler: Box<T>)
    where
        T: Any + 'a,
    {
        self.handlers.push(handler);
    }
}

#[derive(Debug)]
struct DemoMessage {
    id: String,
}

struct DemoJob;

impl Job for DemoJob {
    type Message = DemoMessage;

    fn run(&self, message: Self::Message) {
        println!("run: {:?}", message);
    }
}

struct HelloMessage {
    id: String,
}

#[tokio::main]
async fn main() {
    let mut subscriber = Subscriber { handlers: vec![] };
    subscriber.add_handler(Box::new(DemoJob));
}
hazy ridge
#

right now also Job<Message = dyn Any> is invalid by itself

hollow sky
#

so there is no way to implement Subscriber as I wish?

#

yes, is invalid, because I couldn't type Job<Message = T>

hazy ridge
hollow sky
#

just I could go this way

#![feature(async_closure)]
use std::{any::Any, fmt::Debug};

trait Job {
    type Message: Debug;
    fn run(&self, message: Self::Message);
}

trait Message {}

struct Subscriber<M> {
    handlers: Vec<Box<dyn Job<Message = M>>>,
}

impl<M> Subscriber<M> {
    fn add_handler<T>(&mut self, handler: T)
    where
        T: Job<Message = M> + 'static,
    {
        self.handlers.push(Box::new(handler));
    }
}

#[derive(Clone, Debug)]
struct DemoMessage {
    id: String,
}

struct DemoJob;

impl Job for DemoJob {
    type Message = DemoMessage;
    fn run(&self, message: Self::Message) {
        println!("run: {:?}", message);
    }
}

#[tokio::main]
async fn main() {
    let mut subscriber = Subscriber { handlers: vec![] };
    subscriber.add_handler(DemoJob);
}

but Subscriber becomes <T>, so unable to add more Job handlers.

hollow sky
#

29 line

hazy ridge
#

if you want to check the type use TypeId

#

?crate as-any

fossil compassBOT
#

provide the AsAny trait

Version

0.3.0

Downloads

12 416

hazy ridge
#

you can use this for the Message trait

#

and then .as_any().downcast_ref().clone()

hollow sky
#

Could anyone explain why does this work, and why i couldnt access fields from struct? But debug is printing values.

hazy ridge
#

you can print a dyn Debug and you don't know what type it is

hollow sky
#

i mean, it works, it sees values and accessing them, but I couldn't from same function

#

this code will not work

#

I just added println!("{}", message.id); after println!("{:#?}", message);