Skip to main content

seedlink_rs_protocol/frame/
mod.rs

1pub mod v3;
2pub mod v4;
3
4use crate::error::{Result, SeedlinkError};
5use crate::sequence::SequenceNumber;
6
7#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
8pub enum PayloadFormat {
9    MiniSeed2,
10    MiniSeed3,
11    Json,
12    Xml,
13}
14
15impl PayloadFormat {
16    /// Parse from v4 format byte.
17    pub fn from_byte(b: u8) -> Result<Self> {
18        match b {
19            b'2' => Ok(Self::MiniSeed2),
20            b'3' => Ok(Self::MiniSeed3),
21            b'J' => Ok(Self::Json),
22            b'X' => Ok(Self::Xml),
23            _ => Err(SeedlinkError::InvalidPayloadFormat(b)),
24        }
25    }
26
27    /// Serialize to v4 format byte.
28    pub fn to_byte(self) -> u8 {
29        match self {
30            Self::MiniSeed2 => b'2',
31            Self::MiniSeed3 => b'3',
32            Self::Json => b'J',
33            Self::Xml => b'X',
34        }
35    }
36}
37
38#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
39pub enum PayloadSubformat {
40    Data,
41    Event,
42    Calibration,
43    Timing,
44    Log,
45    Opaque,
46    Info,
47    InfoError,
48}
49
50impl PayloadSubformat {
51    /// Parse from v4 subformat byte.
52    pub fn from_byte(b: u8) -> Result<Self> {
53        match b {
54            b'D' => Ok(Self::Data),
55            b'E' => Ok(Self::Event),
56            b'C' => Ok(Self::Calibration),
57            b'T' => Ok(Self::Timing),
58            b'L' => Ok(Self::Log),
59            b'O' => Ok(Self::Opaque),
60            b'I' => Ok(Self::Info),
61            b'R' => Ok(Self::InfoError),
62            _ => Err(SeedlinkError::InvalidPayloadSubformat(b)),
63        }
64    }
65
66    /// Serialize to v4 subformat byte.
67    pub fn to_byte(self) -> u8 {
68        match self {
69            Self::Data => b'D',
70            Self::Event => b'E',
71            Self::Calibration => b'C',
72            Self::Timing => b'T',
73            Self::Log => b'L',
74            Self::Opaque => b'O',
75            Self::Info => b'I',
76            Self::InfoError => b'R',
77        }
78    }
79}
80
81/// Zero-copy frame — borrows payload from input buffer.
82#[derive(Clone, Debug, PartialEq, Eq)]
83pub enum RawFrame<'a> {
84    V3 {
85        sequence: SequenceNumber,
86        payload: &'a [u8],
87    },
88    V4 {
89        format: PayloadFormat,
90        subformat: PayloadSubformat,
91        sequence: SequenceNumber,
92        station_id: &'a str,
93        payload: &'a [u8],
94    },
95}
96
97impl<'a> RawFrame<'a> {
98    pub fn sequence(&self) -> SequenceNumber {
99        match self {
100            Self::V3 { sequence, .. } | Self::V4 { sequence, .. } => *sequence,
101        }
102    }
103
104    pub fn payload(&self) -> &'a [u8] {
105        match self {
106            Self::V3 { payload, .. } | Self::V4 { payload, .. } => payload,
107        }
108    }
109
110    /// Decode the payload as a miniSEED record.
111    pub fn decode(&self) -> Result<DataFrame> {
112        let record = miniseed_rs::decode(self.payload())?;
113        Ok(DataFrame {
114            sequence: self.sequence(),
115            record,
116        })
117    }
118}
119
120/// Owned frame with decoded miniSEED record.
121#[derive(Debug)]
122pub struct DataFrame {
123    pub sequence: SequenceNumber,
124    pub record: miniseed_rs::MseedRecord,
125}