Как поставить ограничение для функции web_sys :: HtmlElement :: from - PullRequest
0 голосов
/ 01 марта 2020

С e_text типа web_sys::HtmlDivElement и e_button типа web_sys::HtmlButtonElement эта функция создает замыкание для обратного вызова on_click. Компилируется и работает нормально.

let a = buildCbClosure(web_sys::HtmlElement::from(e_text));

fn buildCbClosure(mut e : web_sys::HtmlElement) -> Closure<dyn FnMut(web_sys::MouseEvent)> {
    let a = Closure::wrap(Box::new(move |event: web_sys::MouseEvent| {
        handleButtonClick(&event);
        e.set_text_content(Some("Text - Klik"));
    }) as Box<dyn FnMut(_)>);
    a
}

e_button.set_onclick(Some(a.as_ref().unchecked_ref()));

Следующий шаг - обобщить и переместить web_sys::HtmlElement::from в функцию buildCbClosure, но не обнаружил привязку к e, которая это фиксирует. Пробовал что-то вроде ниже, и это очевидная черта From в неправильном направлении. Другое направление похоже на общий подъем из разных подтипов web_sys::HtmlElement:


fn buildCbClosure<T : From<web_sys::HtmlElement>>(mut t : T) -> Closure<dyn FnMut(web_sys::MouseEvent)> {
    let mut elem = web_sys::HtmlElement::from(t);
    let a = Closure::wrap(Box::new(move |event: web_sys::MouseEvent| {
        handleButtonClick(&event);
        elem.set_text_content(Some("Text - Klik"));
    }) as Box<dyn FnMut(_)>);
    a
}

Дает:

error[E0277]: the trait bound `web_sys::HtmlElement: std::convert::From<T>` is not satisfied
--> src/lib.rs:59:20
|
59 |     let mut elem = web_sys::HtmlElement::from(t);
|                    ^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::convert::From<T>` is not implemented for `web_sys::HtmlElement`

1 Ответ

1 голос
/ 01 марта 2020

Инверсия черты From равна Into. Into<T> автоматически реализуется для типа O, если реализация From<O> существует для T.

fn buildCbClosure(e : impl Into<web_sys::HtmlElement>) -> Closure<dyn FnMut(web_sys::MouseEvent)> {
    let mut e = e.into(); // `e` is an HtmlElement.
}

Теперь любой t, который может быть передан на HtmlElement::from(t) можно напрямую перейти на buildCbClosure(t).

...