Я работаю с WebSockets, используя библиотеку tokio-tungstenite. Мой код выглядит следующим образом: <br/> <pre><code class="rust">println!("Подключаемся к {}", url.bright_blue());
let (ws_stream, _) = connect_async(url).await.expect("Не удалось подключить к WebSocket");
println!("Подключились");
let(mut write, mut read) = ws_stream.split();
println!("{}", "Отправка подписки на новые транзакции".bright_blue());
let msg = Message::Text("{\"method\": \"subscribeNewToken\"}".into());
write.send(msg).await.expect("Не удалось отправить");
if let Some(message) = read.next().await {
let answer = serde_json::from_str(message).expect("Ошибка чтения");
}</code></pre> <br/> У меня возникла проблема с сериализацией данных, получаемых от сервера: компилятор выдает следующую ошибку: <br/> <pre><code>error[E0308]: mismatched types
--> src/main.rs:46:43
|
46 | let answer = serde_json::from_str(message).expect("Ошибка чтения");
| -------------------- ^^^^^^^ expected `&str`, found `Result<Message, Error>`
| |
| arguments to this function are incorrect
|
= note: expected reference `&str`
found enum `Result<tokio_tungstenite::tungstenite::Message, tokio_tungstenite::tungstenite::Error>`</code></pre> <br/> Как я могу решить эту проблему?
Ошибка, которую вы получаете, связана с тем, что функция `read.next().await` возвращает `Option<Result<Message, Error>>`, а вы пытаетесь передать это значение напрямую в функцию `serde_json::from_str`, которая ожидает строку типа `&str`.
Вы можете исправить ваш код, сначала извлекая сообщение из результата, а затем сериализовать его. Вот как это можно сделать:
```rust
use tokio_tungstenite::tungstenite::Message;
use futures_util::StreamExt; // не забудьте добавить необходимый импорт
// ... ваш предыдущий код
if let Some(Ok(message)) = read.next().await {
// Используйте метод to_string() или `as_ref()` и `into()` для получения строки из `Message`
if let Message::Text(text) = message {
let answer: YourType = serde_json::from_str(&text).expect("Ошибка чтения");
// Теперь вы можете использовать переменную `answer`
} else {
println!("Получено неподходящее сообщение: {:?}", message);
}
} else {
println!("Ошибка чтения сообщения или сообщение отсутствует");
}
```
В этом коде:
1. Мы используем `if let Some(Ok(message)) = read.next().await`, чтобы извлечь сообщение только в случае успешного получения (None будет для отсутствующих сообщений, а Err - для ошибок).
2. Далее мы проверяем, является ли сообщение текстовым: `if let Message::Text(text) = message`.
3. Если это текстовое сообщение, мы передаем его в `serde_json::from_str` для десериализации. Обратите внимание, что для этого используется `&text`.
Не забудьте также заменить `YourType` на конкретный тип данных, в который вы хотите десериализовать данные из JSON.
Мне кажется, тебе достаточно явно написали в сообщении, что тебе пришёл Result, а не str, как того ждёт serde_json.
Обработай ошибку, достань Message, и из него уже строку доставай.
Я понимаю, возможно мой вопрос глупый. Но разве сложно рассказать как это делается или дать ссылку на соотвествующие материалы. Спасибо.
Да пожалуйста) https://doc.rust-lang.org/book/ch09-02-recoverable...