poststation_api_icd/
postsock.rs

1//! Poststation Sockets API types
2//!
3//! You probably don't want to use this directly! You probably want to use the `poststation-sdk`
4//! crate instead, which gives you concrete interfaces. Consider this the "raw" definition of
5//! available endpoints and types.
6
7use chrono::{DateTime, Local};
8use postcard_rpc::{
9    endpoints, host_client::SchemaReport, standard_icd::WireError, topics, Key, TopicDirection,
10};
11use postcard_schema::Schema;
12use serde::{Deserialize, Serialize};
13use uuid::Uuid;
14
15pub type DeviceDatas = Vec<DeviceData>;
16pub type OptSchemaReport = Option<SchemaReport>;
17pub type OptVecLog = Option<Vec<Log>>;
18pub type OptVecTopicMsg = Option<Vec<TopicMsg>>;
19
20endpoints! {
21    list = RACK_ENDPOINTS;
22    | EndpointTy            | RequestTy             | ResponseTy        | Path                          |
23    | ----------            | ---------             | ----------        | ----                          |
24    | GetDevicesEndpoint    | ()                    | DeviceDatas       | "rack/devices/get"            |
25    | GetSchemasEndpoint    | u64                   | OptSchemaReport   | "rack/devices/schemas/get"    |
26    | GetLogsEndpoint       | LogRequest            | OptVecLog         | "rack/devices/logs/get"       |
27    | GetLogsRangeEndpoint  | LogRangeRequest       | OptVecLog         | "rack/devices/logs/range/get" |
28    | GetTopicsEndpoint     | TopicRequest          | OptVecTopicMsg    | "rack/devices/topics/get"     |
29    | ProxyEndpoint         | ProxyRequest          | ProxyResponse     | "rack/devices/proxy"          |
30    | PublishEndpoint       | PublishRequest        | PublishResponse   | "rack/devices/publish"        |
31    | StartStreamEndpoint   | TopicStreamRequest    | TopicStreamResult | "rack/devices/stream/start"   |
32    | StopStreamEndpoint    | Uuidv7                | ()                | "rack/devices/stream/stop"    |
33}
34
35topics! {
36    list = RACK_TOPICS_IN;
37    direction = TopicDirection::ToServer;
38    | TopicTy               | MessageTy         | Path                      |
39    | -------               | ---------         | ----                      |
40}
41
42topics! {
43    list = RACK_TOPICS_OUT;
44    direction = TopicDirection::ToClient;
45    | TopicTy               | MessageTy         | Path                      |
46    | -------               | ---------         | ----                      |
47    | SubscribeTopic        | TopicStreamMsg    | "rack/devices/stream"     |
48}
49
50#[derive(Debug, PartialEq, Serialize, Deserialize, Hash, Schema)]
51pub struct DeviceData {
52    pub serial: u64,
53    pub name: String,
54    pub is_connected: bool,
55    pub manufacturer: Option<String>,
56    pub product: Option<String>,
57}
58
59#[derive(Debug, PartialEq, Serialize, Deserialize, Hash, Schema)]
60pub struct LogRequest {
61    pub serial: u64,
62    pub count: u32,
63}
64
65#[derive(Debug, PartialEq, Serialize, Deserialize, Hash, Schema)]
66pub struct LogRangeRequest {
67    pub serial: u64,
68    pub anchor: Anchor,
69    pub direction: Direction,
70    pub count: u32,
71}
72
73#[derive(Debug, PartialEq, Serialize, Deserialize, Hash, Schema)]
74pub enum Direction {
75    Before,
76    After,
77}
78
79#[derive(Debug, PartialEq, Serialize, Deserialize, Hash, Schema)]
80pub enum Anchor {
81    Uuid(Uuidv7),
82    UnixMsTs(u64),
83}
84
85// TODO: now that postcard-schema has a Schema impl for Uuid we might
86// not actually need this anymore
87#[derive(Debug, PartialEq, Serialize, Deserialize, Hash, Schema)]
88pub struct Uuidv7(pub [u8; 16]);
89
90impl From<Uuid> for Uuidv7 {
91    fn from(value: Uuid) -> Self {
92        Self(value.into_bytes())
93    }
94}
95
96impl From<Uuidv7> for Uuid {
97    fn from(val: Uuidv7) -> Self {
98        Uuid::from_bytes(val.0)
99    }
100}
101
102#[derive(Debug, PartialEq, Serialize, Deserialize, Hash, Schema)]
103pub struct Log {
104    pub uuidv7: Uuidv7,
105    pub msg: String,
106}
107
108impl Uuidv7 {
109    pub fn id_to_time(&self) -> DateTime<Local> {
110        let uuid = Uuid::from_bytes(self.0);
111        let ts = uuid.get_timestamp().unwrap();
112        let (a, b) = ts.to_unix();
113        DateTime::from_timestamp(a as i64, b).unwrap().into()
114    }
115}
116
117#[derive(Debug, PartialEq, Serialize, Deserialize, Hash, Schema)]
118pub struct TopicRequest {
119    pub serial: u64,
120    pub path: String,
121    pub key: Key,
122    pub count: u32,
123}
124
125#[derive(Debug, PartialEq, Serialize, Deserialize, Hash, Schema)]
126pub struct TopicMsg {
127    pub uuidv7: Uuidv7,
128    pub msg: Vec<u8>,
129}
130
131#[derive(Debug, PartialEq, Serialize, Deserialize, Hash, Schema)]
132pub struct TopicStreamRequest {
133    pub serial: u64,
134    pub path: String,
135    pub key: Key,
136}
137
138#[derive(Debug, PartialEq, Serialize, Deserialize, Hash, Schema)]
139pub struct TopicStreamMsg {
140    pub stream_id: Uuidv7,
141    pub msg: Vec<u8>,
142}
143
144#[derive(Debug, PartialEq, Serialize, Deserialize, Hash, Schema)]
145pub enum TopicStreamResult {
146    Started(Uuidv7),
147    NoDeviceKnown,
148    DeviceDisconnected,
149    NoSuchTopic,
150}
151
152#[derive(Debug, PartialEq, Serialize, Deserialize, Schema)]
153pub struct ProxyRequest {
154    pub serial: u64,
155    pub path: String,
156    pub req_key: Key,
157    pub resp_key: Key,
158    pub seq_no: u32,
159    pub req_body: Vec<u8>,
160}
161
162#[derive(Debug, PartialEq, Serialize, Deserialize, Schema)]
163pub enum ProxyResponse {
164    Ok {
165        resp_key: Key,
166        seq_no: u32,
167        body: Vec<u8>,
168    },
169    WireErr {
170        resp_key: Key,
171        seq_no: u32,
172        body: WireError,
173    },
174    OtherErr(String),
175}
176
177#[derive(Debug, PartialEq, Serialize, Deserialize, Schema)]
178pub struct PublishRequest {
179    pub serial: u64,
180    pub path: String,
181    pub topic_key: Key,
182    pub seq_no: u32,
183    pub topic_body: Vec<u8>,
184}
185
186#[derive(Debug, PartialEq, Serialize, Deserialize, Schema)]
187pub enum PublishResponse {
188    Sent,
189    OtherErr(String),
190}