zero_copy_reuse/
zero_copy_reuse.rs1use nextjson::formats::Format;
13use nextjson::{Bytes, DecodeSlot, Decoder, NsonDeserialize, NsonSerialize};
14
15#[derive(Debug, PartialEq, NsonSerialize, NsonDeserialize)]
18struct Header<'a> {
19 #[njson(borrow)]
20 event: &'a str,
21 #[njson(borrow)]
22 payload: Bytes<'a>,
23 seq: u64,
24}
25
26#[derive(Debug, PartialEq, NsonSerialize, NsonDeserialize)]
30struct HeaderOwned {
31 event: String,
32 payload: Vec<u8>,
33 seq: u64,
34}
35
36fn main() -> nextjson::Result<()> {
37 let input = br#"{"event":"market.tick","payload":"raw-bytes","seq":7}"#;
42 let header: Header = nextjson::from_slice(input)?;
43 println!(
44 "借用解码: event = {:?}, payload = {:?}, seq = {}",
45 header.event,
46 header.payload.as_bytes(),
47 header.seq
48 );
49
50 let input_start = input.as_ptr() as usize;
52 let input_end = input_start + input.len();
53 let event_ptr = header.event.as_ptr() as usize;
54 let payload_ptr = header.payload.as_bytes().as_ptr() as usize;
55 assert!(
56 (input_start..input_end).contains(&event_ptr),
57 "event 必须借用输入,不能拷贝"
58 );
59 assert!(
60 (input_start..input_end).contains(&payload_ptr),
61 "payload 必须借用输入,不能拷贝"
62 );
63 println!("指针断言通过: event 与 payload 均直接指向输入切片");
64
65 let owned = HeaderOwned {
68 event: header.event.to_owned(),
69 payload: header.payload.as_bytes().to_vec(),
70 seq: header.seq,
71 };
72 let cbor = nextjson::formats::Cbor.encode(&owned)?;
73 let back: HeaderOwned = nextjson::formats::Cbor.decode(&cbor)?;
74 assert_eq!(back, owned);
75 println!("拥有型等价物经 CBOR 原生字节串往返一致: {} B", cbor.len());
76
77 let messages = [
80 br#"{"event":"a","payload":"x","seq":1}"#.as_slice(),
81 br#"{"event":"b","payload":"yy","seq":2}"#.as_slice(),
82 br#"{"event":"c","payload":"zzz","seq":3}"#.as_slice(),
83 ];
84
85 let mut slot = DecodeSlot::<Header>::new();
87 let mut decoded: Vec<Header> = Vec::new();
88 for raw in &messages {
89 let mut decoder = Decoder::new(raw);
90 Header::nextdecode_into(&mut decoder, &mut slot)?;
91 decoder.end()?;
92 decoded.push(slot.take().expect("解码成功必须写入槽"));
94 }
95 assert_eq!(decoded[0].seq, 1);
96 assert_eq!(decoded[1].event, "b");
97 assert_eq!(decoded[2].payload.as_bytes(), b"zzz");
98 println!(
99 "槽复用: 3 条消息共用 1 个 DecodeSlot,逐条解码成功: {:?}",
100 decoded.iter().map(|h| h.seq).collect::<Vec<_>>()
101 );
102
103 let mut slot2 = DecodeSlot::<Header>::new();
105 let mut d1 = Decoder::new(messages[0]);
106 Header::nextdecode_into(&mut d1, &mut slot2)?;
107 d1.end()?;
108 let first = slot2.take().unwrap();
109 let mut d2 = Decoder::new(messages[1]);
110 Header::nextdecode_into(&mut d2, &mut slot2)?;
111 d2.end()?;
112 let second = slot2.take().unwrap();
113 assert_eq!((first.seq, second.seq), (1, 2));
114 println!(
115 "同一个槽连续承载两条消息: seq {} -> seq {}",
116 first.seq, second.seq
117 );
118
119 Ok(())
120}