Какой тип данных считается неправильным в Rust?

Я работаю с 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
    --&gt; src/main.rs:46:43
     |
46   |         let answer = serde_json::from_str(message).expect("Ошибка чтения");
     |                      -------------------- ^^^^^^^ expected `&amp;str`, found `Result&lt;Message, Error&gt;`
     |                      |
     |                      arguments to this function are incorrect
     |
     = note: expected reference `&amp;str`
                     found enum `Result&lt;tokio_tungstenite::tungstenite::Message, tokio_tungstenite::tungstenite::Error&gt;`</code></pre> <br/> Как я могу решить эту проблему?
  • 9 марта 2025 г. 15:34
Ответы на вопрос 2
Ошибка, которую вы получаете, связана с тем, что функция `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...
Похожие вопросы