2

I have a trait:

pub trait Plugin {
    type Error: error::Error;

    fn handle(&mut self, client: & Client, message: Message) -> Result<(), Self::Error>;
}

There are many implementations of this trait (each implementation contains a specific error type):

impl ::Plugin for first::Plugin {
    type Error = first::Error;

    fn handle(&mut self, client: & Client, message: Message) -> first::Result<()> {
        ...
        Ok(())
    }
}

impl ::Plugin for second::Plugin {
    type Error = second::Error;

    fn handle(&mut self, client: & Client, message: Message) -> second::Result<()> {
        ...
        Ok(())
    }
}

I need to create vector of plugins:

let mut plugins: Vec<Box<Plugin<Error=_>>> = vec![
    Box::new(first::Plugin::new()),
    Box::new(second::Plugin::new()),
];

But the code throws this error:

error: type mismatch resolving `<plugins::first::Plugin<'_> as plugin::Plugin>::Error == plugins::second::error::Error`:

How to reorganize the code to create vector of plugins (dynamic dispatch, impl trait Plugin) which contains an associated type (also dynamic dispatch, impl trait error::Error)?

--

Here is the complete code:

fn main() {
    let mut plugins: Vec<Box<Plugin<Error = _>>> = vec![
        Box::new(first::Plugin::new()),
        Box::new(second::Plugin::new()),
    ];
}

pub trait Plugin {
    type Error: std::error::Error;

    fn handle(&mut self) -> Result<(), Self::Error>;
}

mod first {
    use std;

    pub struct Plugin;

    impl Plugin {
        pub fn new() -> Plugin {
            Plugin
        }
    }

    impl ::Plugin for Plugin {
        type Error = Error;

        fn handle(&mut self) -> Result<(), Error> {
            Ok(())
        }
    }

    #[derive(Debug)]
    pub struct Error;

    impl std::fmt::Display for Error {
        fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
            write!(f, "{}", "first error")
        }
    }

    impl std::error::Error for Error {
        fn description(&self) -> &str {
            "first error"
        }
    }
}

mod second {
    use std;

    pub struct Plugin;

    impl Plugin {
        pub fn new() -> Plugin {
            Plugin
        }
    }

    impl ::Plugin for Plugin {
        type Error = Error;

        fn handle(&mut self) -> Result<(), Error> {
            Ok(())
        }
    }

    #[derive(Debug)]
    pub struct Error;

    impl std::fmt::Display for Error {
        fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
            write!(f, "{}", "second error")
        }
    }

    impl std::error::Error for Error {
        fn description(&self) -> &str {
            "second error"
        }
    }
}

Rust playground

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Aleksandr
  • 1,303
  • 2
  • 11
  • 19

0 Answers0