-
Notifications
You must be signed in to change notification settings - Fork 0
/
lazy.rs
70 lines (59 loc) · 1.8 KB
/
lazy.rs
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
use std::io::Cursor;
use phenix_runtime::{
bytes::{ByteSpan, Bytes},
Decodable, DecodingError, Encodable,
};
#[derive(Encodable, Decodable)]
#[phenix_runtime::by_parts]
pub struct Message {
pub from: String,
pub to: String,
pub text: String,
}
#[derive(Debug)]
struct LazyMessage {
pub from: String,
pub to: String,
// It is possible to store the ByteSlice<'a, T> directly, but that requires
// a lifetime.
text: ByteSpan<String>,
}
impl LazyMessage {
pub fn new(bytes: &[u8]) -> Result<Self, DecodingError> {
let mut from = None;
let mut to = None;
let mut text = None;
for part in Message::recognize_by_parts(&mut Bytes::new(bytes)) {
match part? {
// Decode short presumably strings eagerly.
MessagePart::From(part) => from = Some(part.decode()?),
MessagePart::To(part) => to = Some(part.decode()?),
// Store the byte location of presumably long string for lazy
// decoding.
MessagePart::Text(part) => text = Some(part.span()),
}
}
Ok(LazyMessage {
from: from.unwrap(),
to: to.unwrap(),
text: text.unwrap(),
})
}
pub fn text(&self, bytes: &[u8]) -> String {
self.text.decode(bytes).unwrap()
}
}
fn main() {
let message = Message {
from: "Felix".to_string(),
to: "Aurelia".to_string(),
text: "Very long message".to_string(),
};
let mut cursor = Cursor::new(Vec::new());
message.encode(&mut cursor).unwrap();
let bytes = cursor.into_inner();
let lazy = LazyMessage::new(&bytes).unwrap();
println!("from: {}", lazy.from);
println!("to: {}", lazy.to);
println!("text: {}", lazy.text(&bytes));
}