File: pb_rs_example_v3.rs

package info (click to toggle)
rust-quick-protobuf 0.8.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 956 kB
  • sloc: sh: 71; makefile: 2
file content (136 lines) | stat: -rw-r--r-- 5,066 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
extern crate quick_protobuf;

mod pb_rs_v3;

use std::borrow::Cow;

use crate::pb_rs_v3::data_types::mod_FooMessage::OneOftest_oneof;
use crate::pb_rs_v3::data_types::{self, BarMessage, BazMessage, FooMessage, RepeatedMessage};

// Imported fields contain package a.b, which is translated into
// mod_a::mod_b rust module
use crate::pb_rs_v3::a::b::ImportedMessage;

use quick_protobuf::{deserialize_from_slice, serialize_into_vec, BytesReader, Writer};

fn main() {
    // Generate a message, somehow
    //
    // For the example we will leverage the `Default` derive of all messages
    let message = FooMessage {
        // Regular field work as expected, optional leverages on rust Option<>
        f_int32: 54,

        // strings are borrowed (Cow)
        f_string: Cow::Borrowed("Hello world from example!"),

        // bytes too
        f_bytes: Cow::Borrowed(b"I see you!"),

        // imported fields work as expected
        f_imported: Some(ImportedMessage { i: true }),

        // nested messages are encapsulated into a rust module mod_Message
        f_nested: Some(data_types::mod_BazMessage::Nested {
            f_nested: Some(data_types::mod_BazMessage::mod_Nested::NestedMessage { f_nested: 2 }),
        }),

        // nested enums too
        f_nested_enum: data_types::mod_BazMessage::mod_Nested::NestedEnum::Baz,

        // a map!
        f_map: vec![(Cow::Borrowed("foo"), 1), (Cow::Borrowed("bar"), 2)]
            .into_iter()
            .collect(),

        // a oneof value
        test_oneof: OneOftest_oneof::f1(2),

        f_repeated_string: vec![Cow::Borrowed("goat"), Cow::Borrowed("running")],
        f_repeated_baz_message: vec![BazMessage {
            nested: Some(data_types::mod_BazMessage::Nested {
                f_nested: Some(data_types::mod_BazMessage::mod_Nested::NestedMessage {
                    f_nested: 2,
                }),
            }),
            b_int64: 10,
            b_string: Cow::Borrowed("boom\n"),
        }],

        // Each message implements Default ... which makes it much easier
        ..FooMessage::default()
    };

    // Write the message into our buffer, it could be a file, a ZipFile etc ...
    let mut out = Vec::new();
    {
        let mut writer = Writer::new(&mut out);
        writer
            .write_message(&message)
            .expect("Cannot write message!");
    }
    println!("Message written successfully! bytes={:?}", &out);

    // alternatively, a one-liner if we want to work with vec directly
    let out_vec = serialize_into_vec(&message).expect("Cannot write message!");
    assert_eq!(out, out_vec);

    // Try to read it back and confirm that we still have the exact same message
    //
    // In general, if we had written the data to say, a file, or if someone else
    // have written that data, it would be more convenient to use a `Reader` which
    // will feed an internal, owned, buffer. Here, on the contrary, we already hold
    // the `out` buffer. Thus it is more efficient to directly use a `BytesWriter`.
    let read_message = {
        let mut reader = BytesReader::from_bytes(&out);
        reader
            .read_message::<FooMessage>(&out)
            .expect("Cannot read message")
    };
    assert_eq!(message, read_message);

    // alternatively, a one-liner if we want to work with slices directly
    let read_vec = deserialize_from_slice(&out).expect("Cannot write message!");
    assert_eq!(message, read_vec);

    println!("Message read back and everything matches!");
    println!("{:#?}", read_message);

    let message = RepeatedMessage {
        bar_message: vec![BarMessage { b_int32: 0 }, BarMessage { b_int32: 9 }],
    };

    let mut out = Vec::new();
    {
        let mut writer = Writer::new(&mut out);
        writer
            .write_message(&message)
            .expect("Cannot write message!");
    }
    println!("Message written successfully! bytes={:?}", &out);

    // alternatively, a one-liner if we want to work with vec directly
    let out_vec = serialize_into_vec(&message).expect("Cannot write message!");
    assert_eq!(out, out_vec);

    // Try to read it back and confirm that we still have the exact same message
    //
    // In general, if we had written the data to say, a file, or if someone else
    // have written that data, it would be more convenient to use a `Reader` which
    // will feed an internal, owned, buffer. Here, on the contrary, we already hold
    // the `out` buffer. Thus it is more efficient to directly use a `BytesWriter`.
    let read_message = {
        let mut reader = BytesReader::from_bytes(&out);
        reader
            .read_message::<RepeatedMessage>(&out)
            .expect("Cannot read message")
    };
    assert_eq!(message, read_message);

    // alternatively, a one-liner if we want to work with slices directly
    let read_vec = deserialize_from_slice(&out).expect("Cannot write message!");
    assert_eq!(message, read_vec);

    println!("Message read back and everything matches!");
    println!("{:#?}", read_message);
}