Code not compile when use async_std (no method named `handle` found for mutable reference)

I have a minimal example of code that not work. It return next error:

error[E0599]: no method named `handle` found for mutable reference `&mut Box<dyn for<'r, 's> Fn(&'r mut HandlerInput<'s>) -> Vec<Box<(dyn PacketHandler + 'static)>> + Send>` in the current scope
   --> src\test.rs:213:17
    |
213 |         handler.handle(input);
    |                 ^^^^^^ method not found in `&mut Box<dyn for<'r, 's> Fn(&'r mut HandlerInput<'s>) -> Vec<Box<(dyn PacketHandler + 'static)>> + Send>`
    |
    = note: `handler` is a function, perhaps you wish to call it
    = help: items from traits can only be used if the trait is implemented and in scope
note: `PacketHandler` defines an item `handle`, perhaps you need to implement it
   --> src\test.rs:93:1
    |
93  | trait PacketHandler {
    | ^^^^^^^^^^^^^^^^^^^

This is my example:

use std::io::Error;
use std::sync::{Arc, mpsc, Mutex as SyncMutex};
use async_trait::async_trait;
use std::sync::mpsc::Sender;

#[derive(Debug)]
pub enum IncomeMessageType {
    ChooseRealm,
    ChooseCharacter,
    Message,
    KeyEvent,
    ResizeEvent,
}

#[derive(Clone, Debug)]
pub struct DialogIncome {
    _sender: Sender<IncomeMessageType>,
}

impl DialogIncome {
    pub fn new(sender: Sender<IncomeMessageType>) -> Self {
        Self {
            _sender: sender,
        }
    }
}

#[derive(Clone, Debug)]
pub struct MessageIncome {
    _sender: Sender<IncomeMessageType>,
}

impl MessageIncome {
    pub fn new(sender: Sender<IncomeMessageType>) -> Self {
        Self {
            _sender: sender,
        }
    }
}

#[derive(Debug)]
pub struct Session {
    pub session_key: Option<Vec<u8>>,
}

impl Session {
    pub fn new() -> Self {
        Self {
            session_key: None,
        }
    }
}

#[derive(Debug)]
pub struct DataStorage {
    pub players_map: Vec<u8>,
}

impl DataStorage {
    pub fn new() -> Self {
        Self {
            players_map: Vec::new(),
        }
    }
}

#[derive(Debug)]
pub struct HandlerInput<'a> {
    pub session: Arc<SyncMutex<Session>>,
    pub data: Option<&'a [u8]>,
    pub data_storage: Arc<SyncMutex<DataStorage>>,
    pub message_income: MessageIncome,
    pub dialog_income: DialogIncome,
}

#[derive(Debug)]
pub enum HandlerOutput {
    Data((u32, Vec<u8>, Vec<u8>)),
    ConnectionRequest(String, u16),
    Freeze,
    Void,
}

pub type HandlerResult = Result<HandlerOutput, Error>;
pub type ProcessorResult = Vec<Box<dyn PacketHandler>>;
pub type ProcessorFunction = Box<dyn Fn(&mut HandlerInput) -> ProcessorResult + Send>;

pub trait Processor {
    fn process_input(input: &mut HandlerInput) -> ProcessorResult;
}

#[async_trait]
trait PacketHandler {
    async fn handle(&mut self, input: &mut HandlerInput) -> HandlerResult;
}

pub struct Handler1;
#[async_trait]
impl PacketHandler for Handler1 {
    async fn handle(&mut self, _: &mut HandlerInput) -> HandlerResult {
        Ok(HandlerOutput::Void)
    }
}

pub struct Handler2;
#[async_trait]
impl PacketHandler for Handler2 {
    async fn handle(&mut self, _: &mut HandlerInput) -> HandlerResult {
        Ok(HandlerOutput::Void)
    }
}

pub struct TestProcessor;
impl TestProcessor {
    fn process_input(input: &mut HandlerInput) -> ProcessorResult {
        let opcode = 1; // in real project opcode read from input.data
        let handlers: ProcessorResult = match opcode {
            1 => {
                vec![
                    Box::new(Handler1),
                    Box::new(Handler2)
                ]
            },
            2 => {
                vec![
                    Box::new(Handler1),
                    Box::new(Handler2)
                ]
            },
            _ => vec![]
        };

        handlers
    }
}

pub struct TestProcessor2;
impl TestProcessor2 {
    fn process_input(_: &mut HandlerInput) -> ProcessorResult {
        // ...
    }
}

pub struct TestProcessor3;
impl TestProcessor3 {
    fn process_input(_: &mut HandlerInput) -> ProcessorResult {
        // ...
    }
}

fn get_login_processors() -> Vec<ProcessorFunction> {
    return vec![
        Box::new(TestProcessor::process_input),
    ];
}

fn get_realm_processors() -> Vec<ProcessorFunction> {
    return vec![
        Box::new(TestProcessor2::process_input),
        Box::new(TestProcessor3::process_input),
    ];
}

pub fn test() {
    let (input_tx, _) = mpsc::channel::<IncomeMessageType>();
    let input = &mut HandlerInput {
        session: Arc::new(SyncMutex::new(Session::new())),
        data: None,
        data_storage: Arc::new(SyncMutex::new(DataStorage::new())),
        dialog_income: DialogIncome::new(input_tx.clone()),
        message_income: MessageIncome::new(input_tx.clone()),
    };

    let is_connected_to_realm = true;

    let mut handlers = match is_connected_to_realm {
        true => get_login_processors(),
        false => get_realm_processors(),
    };

    for handler in handlers.iter_mut() {
        handler.handle(input);
    }
}

Could somebody help to fix this issue ?

Each handler is actually a ProcessorFunction... which is a function, and the error is clearly telling you that: A function has no methods in Rust.

1 Like