Я пытаюсь использовать Iced (фреймворк пользовательского интерфейса на основе архитектуры Elm) с Reqwest (обертка над гипер), который может использовать Serde для десериализации JSON.
Независимо они работают правильно, но я новичок в Rust и что-то в моей реализации не так.
Я начинаю с сетевой функции (в процессе).
#[derive(Deserialize, Debug, Clone)]
pub(crate) enum Error {
APIError,
ParseError,
}
impl From<reqwest::Error> for Error {
fn from(error: reqwest::Error) -> Self {
Error::APIError
}
}
pub(crate) async fn post<T>(request: Request) -> Result<T, Error>
where
T: DeserializeOwned + Debug + Clone,
{
let headers = standard_headers(request.params);
let response = Client::new()
.post(&format!("{}{}", request.base, request.path))
.json(&request.body)
.headers(headers)
.send()
.await?
.json::<T>()
.await?;
Ok(response)
}
и я пытаюсь использовать его как часть Iced:
fn new() -> (Runner, Command<Message>) {
(
Runner::Loading,
Command::perform(post(Login::request()), Message::Next),
)
}
и я получаю ошибку компиляции:
error[E0277]: `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely
--> src/feature/runner/runner.rs:42:13
|
42 | Command::perform(post(Login::request()), Message::Next),
| ^^^^^^^^^^^^^^^^ `*mut (dyn std::ops::Fn() + 'static)` cannot be shared between threads safely
|
::: <snip>/futures/src/command/native.rs:29:22
|
29 | future: impl Future<Output = T> + 'static + Send,
| ------------------ required by this bound in `iced_futures::command::native::Command::<T>::perform`
|
= help: within `core::fmt::Void`, the trait `std::marker::Sync` is not implemented for `*mut (dyn std::ops::Fn() + 'static)`
Я полагаю, что проблема связана с использованием T: DeserializeOwned и времени жизни в post
, при этом право собственности является таким что тип T
в async fn post
может находиться в потоке, отличном от асинхронного вызова в Command (отсюда и упоминание Send
.
Ответ может быть даже в пожизненной ссылке, но у меня еще недостаточно знаний, чтобы увидеть его или понять, правильно ли я думаю. Я вернулся к использованию конкретного типа вместо T
, который работает.
Я хотел бы понять, почему эта проблема существует и что я могу сделать, чтобы решить ее.
Заранее спасибо!