Rust protobuf serialization все испорчено - PullRequest
1 голос
/ 08 марта 2019

Я использую rust-protobuf версию 2.4 У меня есть следующий код

let mut msg = vec![];
let mut str = protobuf::CodedOutputStream::vec(&mut msg);
let mut rmsg = user_manager::user::user_data::new();
rmsg.set_id("1234".into());
rmsg.set_nick("test".into());
str.write_message(1, &rmsg).unwrap();
str.flush().unwrap();
println!("{:?}", msg);
let test: register_msg = protobuf::parse_from_bytes(&msg[..]).unwrap();
println!("serialized: {:?}\noriginal: {:?}", test, rmsg);

и соответствующее описание прототипа выглядит следующим образом

message user_data{
    string id           = 1; //required
    string nick         = 2;
    string theme        = 3;
    string admin_id     = 4;
    string lang         = 5;
    double credit       = 6; //required
    double bonus_credit = 7; //required
};

и то, что я получаю в результате, все испорчено output

Прежде всего, зачем мне нужно вводить номер, если я сериализую все сообщение? это действительно странный дизайн.

Во-вторых, первое поле, как вы можете видеть в файле proto, это id, но в результате сериализации показано, что пакет protobuf сериализировал все в поле nick, которое является вторым полем.

Я что-то не так делаю или это может быть ошибкой в ​​библиотеке?

ОБНОВЛЕНИЕ 1:

Я изменил write_msg на write_to_bytes Вот так выглядит мой код.

let mut rmsg = user_manager::user::user_data::new();
rmsg.set_id("1234".into());
rmsg.set_nick("test".into());
let msg = rmsg.write_to_bytes().unwrap();
println!("{:?}", msg);
println!("{:?}", &msg[..]);
let test: register_msg = protobuf::parse_from_bytes(&msg).unwrap();
println!("serialized: {:?}\noriginal: {:?}", test, rmsg);

и, тем не менее, вывод все испорчен. out

Ответы [ 2 ]

2 голосов
/ 08 марта 2019

Вы можете использовать Message::write_to_bytes для сериализации сообщения, которое можно проанализировать с помощью parse_from_bytes.

Кроме того, убедитесь, что вы десериализуете тот же тип, который вы сериализовали.

Вотпример программы, которая работает правильно:

mod protos;
use protobuf::Message;
use protos::user_data::user_data;

fn main() {
    let mut rmsg = user_data::new();
    rmsg.set_id("1234".into());
    rmsg.set_nick("test".into());

    let msg = rmsg.write_to_bytes().unwrap();
    println!("{:?}", msg);

    let test: user_data = protobuf::parse_from_bytes(&msg).unwrap();
    println!("serialized: {:?}\noriginal: {:?}", test, rmsg);
}
1 голос
/ 08 марта 2019

Эта строка:

str.write_message(1, &rmsg).unwrap();

записывает сообщение rmsg в виде суб-сообщения с идентификатором поля 1.Таким образом, поля оказываются на один уровень вложения глубже, как если бы ваш .proto был:

message wrappermsg {
    user_data msg = 1;
}

Правильный метод:

rmsg.write_to(&mut str);
...