Where to implement trait bound on enum variant

⚓ Rust    📅 2025-10-29    👤 surdeus    👁️ 6      

surdeus

Warning

This post was published 33 days ago. The information described in this article may have changed.

I'm trying to combine two functions with the following signatures.

fn add_event_listener<T>( &mut self, name: &str, callback: T, group: &str, id: &str)
where
    T: FnMut(Event) + 'static,
{
    let element = Template::get_element_by_id(id);
    let target: EventTarget = element.into();
    let cb = Closure::<dyn FnMut(Event)>::new(callback);
    let name_string = String::from(name);

    // snip
}
fn add_progress_listener<T>( &mut self, name: &str, callback: T, group: &str, reader: FileReader
) where
    T: FnMut(ProgressEvent) + 'static,
{
    let target: EventTarget = reader.into();
    let cb = Closure::<dyn FnMut(ProgressEvent)>::new(callback);
    let name_string = String::from(name);

    // snip
}

I put the variables in a struct with enums...

enum AddListenerTarget<'a> {
    Str(&'a str),
    FileReader(FileReader),
}
enum AddListenerGroup {
    GroupA,
    GroupB,
}
enum EventType {
    Evt(Event),
    PrgEvt(ProgressEvent),
}
struct AddListener<'a> {
    name: String,
    callback: EventType,
    group: AddListenerGroup,
    target: AddListenerTarget<'a>,
}

...but now I don't know how to implement the trait bounds I lost.

fn add_listener(&mut self, l: AddListener) { // <-- no "where" clause
    let name_string = String::from(l.name);

    use EventType::*;
    match l.callback {
        Evt(callback) => {
            if let AddListenerTarget::Str(id) = l.target {
                let element = Template::get_element_by_id(id);
                let target: EventTarget = element.into();
                let cb = Closure::<dyn FnMut(Event)>::new(callback); // <-- needs trait bound

                // snip
            }
        }
        PrgEvt(callback) => {
            if let AddListenerTarget::FileReader(reader) = l.target {
                let target: EventTarget = reader.into();
                let cb = Closure::<dyn FnMut(ProgressEvent)>::new(callback); // <-- needs trait bound

                // snip
            }
        }
    }

Error (one for each closure)

error[E0277]: the trait bound `Event: IntoWasmClosure<dyn FnMut(Event)>` is not satisfied
   --> src/view/mod.rs:177:63
    |
177 |                     let cb = Closure::<dyn FnMut(Event)>::new(callback);
    |                              -------------------------------- ^^^^^^^^ the trait `FnMut(Event)` is not implemented for `Event`
    |                              |
    |                              required by a bound introduced by this call
    |
    = note: required for `Event` to implement `IntoWasmClosure<dyn FnMut(Event)>`
note: required by a bound in `Closure::<T>::new`
   --> /media/d1/lnx/home/user/.local/share/rust/cargo/registry/src/index.crates.io-1949cf8c6b5b557f/wasm-bindgen-0.2.100/src/closure.rs:274:12
    |
272 |     pub fn new<F>(t: F) -> Closure<T>
    |            --- required by a bound in this associated function
273 |     where
274 |         F: IntoWasmClosure<T> + 'static,
    |            ^^^^^^^^^^^^^^^^^^ required by this bound in `Closure::<T>::new`

I tried putting the trait bounds on the enum but it did not go well. Any suggestions? Thanks in advance.

1 post - 1 participant

Read full topic

🏷️ Rust_feed