#Working with futures
1 messages · Page 1 of 1 (latest)
you can use ```rs
fn make_service_fn<T>(message: JobMessage<&T>) -> Option<impl Future + '_>
where
T: Debug + 'static,
{
(message.0 as &dyn Any)
.downcast_ref::<DemoMessage>()
.map(|demo| async move {
println!("downcasted {:?}", demo);
})
}
what would the use of TAIT be here?
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));
}
no feature would allow you to transform Job<Message = T> into Job<Message = dyn Any> automatically, and there's no mention of TAIT in your code
right now also Job<Message = dyn Any> is invalid by itself
so there is no way to implement Subscriber as I wish?
yes, is invalid, because I couldn't type Job<Message = T>
there probably is, but kinda different
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.
this is something you can do: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=92a6da81d7ba6720cb74abcdb0e22442
and also is there is any way to fix this one/
https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=2b0cf85014a10688e967d38b36b4ae73
A browser interface to the Rust compiler to experiment with the language
29 line
type_name isn't supposed to be used for logic in your program
if you want to check the type use TypeId
?crate as-any
A browser interface to the Rust compiler to experiment with the language
Could anyone explain why does this work, and why i couldnt access fields from struct? But debug is printing values.
Debug is a trait, and it is implemented on a concrete type, so it knows the fields
you can print a dyn Debug and you don't know what type it is