Skip to main content

nerve_ipc/
types.rs

1//! Shared protocol types and enums.
2//!
3//! Defines `MessageType`, `FrameFlags`, `RequestId`, and
4//! `ProtocolErrorKind`, plus conversions like `TryFrom<u8>`.
5
6/// Wire-level message type discriminant.
7///
8/// New types will be added as the protocol evolves; match arms should
9/// always include a wildcard (`_`) or use `TryFrom<u8>` rather than
10/// directly matching on the integer value.
11#[non_exhaustive]
12#[repr(u8)]
13#[derive(Debug, Clone, Copy, PartialEq, Eq)]
14pub enum MessageType {
15    Ping = 0x01,
16    SearchQuery = 0x02,
17    SearchResult = 0x03,
18    AiToken = 0x04,
19    Cancel = 0x05,
20
21    // agentic scaffolding
22    AgentTaskStart = 0x10,
23    AgentTaskEvent = 0x11,
24    AgentTaskDone = 0x12,
25}
26
27// frame flags
28bitflags::bitflags! {
29    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
30    pub struct FrameFlags: u8 {
31        // More frames will follow for this request
32        const STREAM = 0b0000_0001;
33
34        // final frame for this request
35        const FINAL = 0b0000_0010;
36    }
37}
38
39// request id
40#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
41#[repr(transparent)]
42pub struct RequestId(pub u64);
43
44/// Internal classification of protocol-level errors.
45///
46/// New variants will be added as error handling evolves; downstream
47/// matches should include a wildcard arm.
48#[non_exhaustive]
49#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
50pub enum ProtocolErrorKind {
51    /// The frame magic bytes do not match `0x4E455256` ("NERV").
52    InvalidMagic,
53    /// The frame version field does not match the supported version.
54    UnsupportedVersion,
55    /// The frame header or payload cannot be parsed.
56    MalformedFrame,
57    /// The `payload_length` field exceeds `MAX_PAYLOAD_SIZE`.
58    PayloadTooLarge,
59    /// The `msg_type` field does not correspond to a known `MessageType`.
60    UnknownMessageType,
61    /// An implementation-level failure unrelated to wire data.
62    InternalError,
63}
64
65impl TryFrom<u8> for MessageType {
66    type Error = ();
67
68    fn try_from(value: u8) -> Result<Self, Self::Error> {
69        match value {
70            0x01 => Ok(MessageType::Ping),
71            0x02 => Ok(MessageType::SearchQuery),
72            0x03 => Ok(MessageType::SearchResult),
73            0x04 => Ok(MessageType::AiToken),
74            0x05 => Ok(MessageType::Cancel),
75            0x10 => Ok(MessageType::AgentTaskStart),
76            0x11 => Ok(MessageType::AgentTaskEvent),
77            0x12 => Ok(MessageType::AgentTaskDone),
78            _ => Err(()),
79        }
80    }
81}