cardano_net/packet/
frame.rs

1use cardano_sdk::protocol::Time;
2use std::fmt;
3
4pub fn build(time: Time, idf: IdAndResponder, payload_length: u16) -> [u8; 8] {
5    let v = ((time.0 as u64) << 32) | ((idf.0 as u64) << 16) | (payload_length as u64);
6    v.to_be_bytes()
7}
8
9pub fn parse(header: [u8; 8]) -> (Time, IdAndResponder, usize) {
10    let v = u64::from_be_bytes(header);
11    let time = (v >> 32) as u32;
12    let idf = (v >> 16) as u16;
13    let len = v as u16;
14    (Time(time), IdAndResponder(idf), len as usize)
15}
16
17#[derive(Clone, Copy)]
18pub struct IdAndResponder(u16);
19
20impl IdAndResponder {
21    pub fn id(self) -> u16 {
22        self.0 & ID_MASK
23    }
24
25    pub fn is_responder(self) -> bool {
26        self.0 >> 15 == 1
27    }
28
29    pub const fn sender(id: u16) -> Self {
30        assert!(id < 0x80_00);
31        IdAndResponder(id)
32    }
33
34    pub const fn responder(id: u16) -> Self {
35        assert!(id < 0x80_00);
36        IdAndResponder(id | 0x80_00)
37    }
38
39    pub const fn new(id: u16, responder: bool) -> Self {
40        if responder {
41            Self::responder(id)
42        } else {
43            Self::sender(id)
44        }
45    }
46}
47
48const ID_MASK: u16 = 0x7f_ff;
49
50impl fmt::Debug for IdAndResponder {
51    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
52        write!(
53            f,
54            "{}:{}",
55            self.id(),
56            if self.is_responder() { 'R' } else { 'S' }
57        )
58    }
59}
60
61impl fmt::Display for IdAndResponder {
62    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63        write!(
64            f,
65            "{}:{}",
66            self.id(),
67            if self.is_responder() { 'R' } else { 'S' }
68        )
69    }
70}
71
72#[derive(Clone, Debug)]
73pub struct PacketBytes {
74    pub time: Time,
75    pub idf: IdAndResponder,
76    pub inner: Vec<u8>,
77}
78
79impl PacketBytes {
80    pub fn id(&self) -> u16 {
81        self.idf.id()
82    }
83
84    pub fn is_responder(&self) -> bool {
85        self.idf.is_responder()
86    }
87}