Почему я всегда получаю ошибку "завершающие символы" при попытке проанализировать данные с serde_json? - PullRequest
1 голос
/ 29 июня 2019

У меня есть сервер, который возвращает запросы в формате JSON.При попытке разобрать данные я всегда получаю ошибку "завершающие символы".Это происходит только при получении JSON от почтальона

let type_of_request = parsed_request[1];
let content_of_msg: Vec<&str> = msg_from_client.split("\r\n\r\n").collect();

println!("{}", content_of_msg[1]); 
// Will print "{"username":"user","password":"password","email":"dwadwad"}"

let res: serde_json::Value = serde_json::from_str(content_of_msg[1]).unwrap();

println!("The username is: {}", res["username"]);

при получении данных от почтальона это происходит:

thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Error("trailing characters", line: 1, column: 60)', src\libcore\result.rs:997:5

, но при наличии строки внутри Rust:

let j = "{\"username\":\"user\",\"password\":\"password\",\"email\":\"dwadwad\"}";

let res: serde_json::Value = serde_json::from_str(j).unwrap();

println!("The username is: {}", res["username"]);

это работает как шарм:

The username is: "user"

РЕДАКТИРОВАТЬ : Очевидно, что когда я прочитал сообщение в буфер и превратил его в строку, он сохранил все NULL-символы, которые имел буферкоторые, конечно, последние символы.

1 Ответ

1 голос
/ 30 июня 2019

Глядя на serde json code , можно найти следующий комментарий над соответствующим элементом enum ErrorCode:

/// JSON has non-whitespace trailing characters after the value.
TrailingCharacters,

Итак, как следует из кода ошибки, у вас есть некоторый трейлингсимвол, который не является пробелом.В своем фрагменте вы говорите:

println!("{}", content_of_msg[1]); 
// Will print "{"username":"user","password":"password","email":"dwadwad"}"

Если вы буквально скопируете и вставили напечатанный вывод здесь, я бы отметил, что не ожидаю, что вывод будет заключен в начальные и конечные кавычки.Вы включили их сами или они были частью того, что было напечатано?Если они были напечатаны, я подозреваю, что это источник вашей проблемы.

Редактировать:

Фактически, я могу почти воссоздать это, используя необработанную строку с ведущими / завершающими кавычками в Rust:

extern crate serde_json;

#[cfg(test)]
mod tests {
    #[test]
    fn test_serde() {
        let s =
            r#""{"username":"user","password":"password","email":"dwadwad"}""#;
        println!("{}", s);
        let _res: serde_json::Value = serde_json::from_str(s).unwrap();
    }
}

Запуск через cargo test приводит к:

test tests::test_serde ... FAILED

failures:

---- tests::test_serde stdout ----
"{"username":"user","password":"password","email":"dwadwad"}"
thread 'tests::test_serde' panicked at 'called `Result::unwrap()` on an `Err` value: Error("trailing characters", line: 1, column: 4)', src/libcore/result.rs:997:5
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.


failures:
    tests::test_serde

Обратите внимание, что мой печатный вывод также включает в себя начальные / конечные кавычки, и я также получаю ошибку TrailingCharacter, хотя и придругой столбец.

Редактировать 2:

Исходя из вашего комментария о том, что вы сами добавили заключительные цитаты, у вас есть известная хорошая строка (та, которую вы определили в Rust)и тот, который, по вашему мнению, должен соответствовать ему, но не соответствует (тот, что поступил от Почтальона).

Это проблема с данными, поэтому мы должны проверить данные.Вы можете адаптировать приведенный ниже код, чтобы сравнить правильную строку с другой:

#[test]
fn test_str_comp() {
    // known good string we'll compare against                                                                                                                                             
    let good =
        r#"{"username":"user","password":"password","email":"dwadwad"}"#;
    // lengthened string, additional characters                                                                                                                                            
    // also n and a in username are transposed                                                                                                                                             
    let bad =
        r#"{"useranme":"user","password":"password","email":"dwadwad"}abc"#;
    let good_size = good.chars().count();
    let bad_size = bad.chars().count();
    for (idx, (c1, c2)) in (0..)
        .zip(good.chars().zip(bad.chars()))
        .filter(|(_, (c1, c2))| c1 != c2)
    {
        println!(
            "Strings differ at index {}: (good: `{}`, bad: `{}`)",
            idx, c1, c2
        );
    }
    if good_size < bad_size {
        let trailing = bad.chars().skip(good_size);
        println!(
            "bad string contains extra characters: `{}`",
            trailing.collect::<String>()
        );
    } else if good_size > bad_size {
        let trailing = good.chars().skip(bad_size);
        println!(
            "good string contains extra characters: `{}`",
            trailing.collect::<String>()
        );
    }

    assert!(false);
}

Для моего примера это приводит к ошибке:

test tests::test_str_comp ... FAILED

failures:

---- tests::test_str_comp stdout ----
Strings differ at index 6: (good: `n`, bad: `a`)
Strings differ at index 7: (good: `a`, bad: `n`)
bad string contains extra characters: `abc`
thread 'tests::test_str_comp' panicked at 'assertion failed: false', src/lib.rs:52:9
note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.


failures:
    tests::test_str_comp
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...