use nextjson::formats::Format;
use nextjson::{Bytes, DecodeSlot, Decoder, NsonDeserialize, NsonSerialize};
#[derive(Debug, PartialEq, NsonSerialize, NsonDeserialize)]
struct Header<'a> {
#[njson(borrow)]
event: &'a str,
#[njson(borrow)]
payload: Bytes<'a>,
seq: u64,
}
#[derive(Debug, PartialEq, NsonSerialize, NsonDeserialize)]
struct HeaderOwned {
event: String,
payload: Vec<u8>,
seq: u64,
}
fn main() -> nextjson::Result<()> {
let input = br#"{"event":"market.tick","payload":"raw-bytes","seq":7}"#;
let header: Header = nextjson::from_slice(input)?;
println!(
"借用解码: event = {:?}, payload = {:?}, seq = {}",
header.event,
header.payload.as_bytes(),
header.seq
);
let input_start = input.as_ptr() as usize;
let input_end = input_start + input.len();
let event_ptr = header.event.as_ptr() as usize;
let payload_ptr = header.payload.as_bytes().as_ptr() as usize;
assert!(
(input_start..input_end).contains(&event_ptr),
"event 必须借用输入,不能拷贝"
);
assert!(
(input_start..input_end).contains(&payload_ptr),
"payload 必须借用输入,不能拷贝"
);
println!("指针断言通过: event 与 payload 均直接指向输入切片");
let owned = HeaderOwned {
event: header.event.to_owned(),
payload: header.payload.as_bytes().to_vec(),
seq: header.seq,
};
let cbor = nextjson::formats::Cbor.encode(&owned)?;
let back: HeaderOwned = nextjson::formats::Cbor.decode(&cbor)?;
assert_eq!(back, owned);
println!("拥有型等价物经 CBOR 原生字节串往返一致: {} B", cbor.len());
let messages = [
br#"{"event":"a","payload":"x","seq":1}"#.as_slice(),
br#"{"event":"b","payload":"yy","seq":2}"#.as_slice(),
br#"{"event":"c","payload":"zzz","seq":3}"#.as_slice(),
];
let mut slot = DecodeSlot::<Header>::new();
let mut decoded: Vec<Header> = Vec::new();
for raw in &messages {
let mut decoder = Decoder::new(raw);
Header::nextdecode_into(&mut decoder, &mut slot)?;
decoder.end()?;
decoded.push(slot.take().expect("解码成功必须写入槽"));
}
assert_eq!(decoded[0].seq, 1);
assert_eq!(decoded[1].event, "b");
assert_eq!(decoded[2].payload.as_bytes(), b"zzz");
println!(
"槽复用: 3 条消息共用 1 个 DecodeSlot,逐条解码成功: {:?}",
decoded.iter().map(|h| h.seq).collect::<Vec<_>>()
);
let mut slot2 = DecodeSlot::<Header>::new();
let mut d1 = Decoder::new(messages[0]);
Header::nextdecode_into(&mut d1, &mut slot2)?;
d1.end()?;
let first = slot2.take().unwrap();
let mut d2 = Decoder::new(messages[1]);
Header::nextdecode_into(&mut d2, &mut slot2)?;
d2.end()?;
let second = slot2.take().unwrap();
assert_eq!((first.seq, second.seq), (1, 2));
println!(
"同一个槽连续承载两条消息: seq {} -> seq {}",
first.seq, second.seq
);
Ok(())
}