1

Can u please explain the rust error for this?

pub trait OrderEvent {}

#[derive(Debug)]
pub struct OrderCreatedEvent {
    pub order_id: String,
}

impl OrderEvent for OrderCreatedEvent {}

pub fn handle_create<E: OrderEvent>(_state: OrderState, command: CreateOrderCommand) -> Vec<E> {
    let events = vec![OrderCreatedEvent {
        order_id: command.order_id,
    }];

    events
}

Rust tells me:

mismatched types [E0308] expected type parameter `E`,
found struct `OrderCreatedEvent` Note: expected struct `Vec<E>` found struct `Vec<OrderCreatedEvent>`

Event implements the OrderEvent trait and it is trait bound. Why is this not allowed?

kind_robot
  • 2,383
  • 4
  • 31
  • 45

1 Answers1

1

Use this signature instead:

pub fn handle_create(_state: OrderState, command: CreateOrderCommand) -> Vec<impl OrderEvent>

In Rust, using impl Trait as a type has opposite meanings in a parameter type vs in the return type. See https://doc.rust-lang.org/book/ch10-02-traits.html#returning-types-that-implement-traits

Solomon Ucko
  • 5,724
  • 3
  • 24
  • 45
  • thanks! what is the type signature for the returned Vec? `let events: Vec = handle_create(...)` is wrong of course. this is not correct either `let events: Vec` – kind_robot Feb 22 '23 at 05:02
  • You need not specify the type. – vikram2784 Feb 22 '23 at 05:49
  • @kind_robot Because the bracket generic parameter is meant to be **variadic** over the **input**. "Variadic" meaning for different input types, the compiler must generate different function bodies (and for the same input type, the compiler must generate the same function body). Here your return value is not variadic over the input. What you want is an **opaque** return type. Opaque means the signature only tells part of the type information but the actual type is **determined** somewhere else. And the bracket generic parameter does not have this meaning. – First_Strike Feb 22 '23 at 07:36