TL; DR: Я почти уверен, что вы не можете в общих чертах.
Я не понимаю, почему это так, поскольку тип, из которого я пытаюсь преобразовать, - это Box<dyn Error>
, размер которого известен во время компиляции.
Это не то место, на которое он жалуется. Снова посмотрите на сообщение об ошибке (слегка очищенное):
the trait `Sized` is not implemented for `dyn Error`
required because of the requirements on the impl of `Error` for `Box<dyn Error>`
required because of the requirements on the impl of `From<Box<dyn Error>>` for `Handler`
required by `From::from`
Вторая строка является важной. Вот более простое воспроизведение вашей проблемы:
use std::error::Error;
fn example<E: Error>() {}
fn main() {
example::<Box<dyn Error>>();
}
error[E0277]: the size for values of type `dyn std::error::Error` cannot be known at compilation time
--> src/main.rs:6:5
|
6 | example::<Box<dyn Error>>();
| ^^^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
|
= help: the trait `std::marker::Sized` is not implemented for `dyn std::error::Error`
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
= note: required because of the requirements on the impl of `std::error::Error` for `std::boxed::Box<dyn std::error::Error>`
note: required by `example`
--> src/main.rs:3:1
|
3 | fn example<E: Error>() {}
| ^^^^^^^^^^^^^^^^^^^^^^
Error
только реализован для Box<T>
, когда T
равен Sized
и сам реализует Error
:
impl<T: Error> Error for Box<T> {
// ...
}
Сказал иначе, Box<dyn Error>
не реализует Error
.
Можно подумать, что вы можете добавить вторую реализацию From
для Box<Error>
, но это запрещено:
upstream crates may add new impl of trait `std::error::Error` for type
`std::boxed::Box<(dyn std::error::Error + 'static)>` in future versions
Лучшая альтернатива, которую я могу предложить, это реализовать From
для каждого конкретного конкретного типа, который вам нужно поддерживать:
impl From<SpecificError> for Handler {
fn from(e: SpecificError) -> Self {
Handler { error: format!("{}", e) }
}
}
impl From<Box<dyn Error>> for Handler {
fn from(e: Box<dyn Error>) -> Self {
Handler { error: format!("{}", e) }
}
}
Макрос может уменьшить шаблон здесь.