Q:

How to convert a Scala anonymous trait implementation to Rust?

I'm having difficulty converting this Scala trait to Rust
trait Inject[A, B] {
  self =>

  def inject(input: A): B

  def project(input: B): Try[A]

  def contraMap[AA](inj: Inject[AA, A]): Inject[AA, B] = new Inject[AA, B] {
    override def inject(input: AA) = self.inject(inj.inject(input))

    override def project(input: B) = self.project(input).flatMap(i => inj.project(i))
  }

  def map[BB](inj: Inject[B, BB]): Inject[A, BB] = new Inject[A, BB] {
    override def inject(input: A) = inj.inject(self.inject(input))

    override def project(input: BB) = inj.project(input).flatMap(i => self.project(i))
  }

}

Here is my Rust equivalent 
pub trait Injection<A, B> {
    fn inject(input: A) -> B;
    fn project(input: B) -> Result<A, InjectionError>;
    fn contraMap<AA>(input: Injection<AA, A>) -> Injection<AA, B>;
    fn map<BB>(input: Injection<B, BB>) -> Injection<A, BB>;
}

pub struct InjectionError {
    msg: String,
}

I am getting:
error[E0038]: the trait `Injection` cannot be made into an object
 --> src/main.rs:4:5
  |
4 |     fn contraMap<AA>(input: Injection<AA, A>) -> Injection<AA, B>;
  |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Injection` cannot be made into an object
  |
  = note: method `inject` has no receiver
  = note: method `project` has no receiver
  = note: method `contraMap` has no receiver
  = note: method `map` has no receiver

If I add a self reference, I still get the same error:
pub trait Injection<A, B> {
    fn inject(&self, input: A) -> B;
    fn project(&self, input: B) -> Result<A, InjectionError>;
    fn contraMap<AA>(&self, input: Injection<AA, A>) -> Injection<AA, B>;
    fn map<BB>(&self, input: Injection<B, BB>) -> Injection<A, BB>;
}

pub struct InjectionError {
    msg: String,
}

I am not sure how I can instantiate an anonymous Injection like I am doing in Scala. What would be the idiomatic way of converting this Scala trait to Rust?

A:

In Rust, traits only describe behavior, not data. The compiler tells you your trait is not object-safe because you want to return anything that implements the trait, and that 'anything' has no single canonical known size at compile time.
You can Box your values to put them on the heap, or use references (which will require some scary lifetime juggling and be quite brittle, but avoid the allocation). You will also need to return a concrete type from map and contraMap. Look how Rust's Iterator trait does it: It returns a Map which is generic over the original iterator and the function type it maps, wraps both and implements Iterator.  

