Handling associated types in traits

I have this rust code

trait Foo{
    type Input ;
    type Error;
    fn run(&mut self, input: Self::Input) -> Result<(),Self::Error> {
		Ok(())
	}
}

trait Bar {
   fn create_foo() -> Result<Option<Box<dyn Foo>>, Box<dyn std::error::Error>> {
        Ok(None)
    }
}

//struct Baz{}

fn main() {}

Here I have two associated types in Foo which are Input & Error. In Bar I have create_foo() which creates Foo object based on input provided(ignore the argument to this function). My idea here is to create Foo through Bar interface.

Since Foo has associated types in it, When I compile this code, Compliler is throwing this error

error[E0191]: the value of the associated types `Error` (from trait `Foo`), `Input` (from trait `Foo`) must be specified
 --> src/main.rs:9:45
  |
3 |     type Input ;
  |     ---------- `Input` defined here
4 |     type Error;
  |     ---------- `Error` defined here
...
9 |    fn create_foo() -> Result<Option<Box<dyn Foo>>, Box<dyn std::error::Error>> {
  |                                             ^^^ help: specify the associated types: `Foo<Input = Type, Error = Type>`

For more information about this error, try `rustc --explain E0191`.
error: could not compile `playground` (bin "playground") due to previous error

I understand the error - I need to specify the type for Input & Error in create_foo()'s return statement.Since Interfaces are generic, I can't specify a concrete type for Error & input in create_foo(). Instead, I can create interfaces for both Input & Error and bind them to these interfaces would solve my problem. Which is something like this


trait InputTrait{}
trait ErrorTrait{}


trait Foo{
    type Input : InputTrait ;
    type Error: ErrorTrait;
    fn run(&mut self, input: Self::Input) -> Result<(),Self::Error> {
        Ok(())
    }
}

trait Bar {
   fn create_foo() -> Result<Option<Box<dyn Foo<Input = dyn InputTrait, Error = dyn ErrorTrait>>>, Box<dyn std::error::Error>> {
        Ok(None)
    }
}

//struct Baz{}

fn main() {}

But I feel creating interfaces for associated types wont look nicer ( you can see that return type in create_foo() is increased ) and it is increasing number of interfaces and complexity of the program.

I wanted to know what's the way to solve this? is there a defacto way of solving these kind of issues?

How about this

fn create_foo<I, E>() -> Result<Option<Box<dyn Foo<Input = I, Error = E>>>, ...>