Skip to main content

anachro_icd/
component.rs

1//! # Client Messages
2//!
3//! These are messages that are sent FROM the peripheral
4//! Component/Client, TO the central Arbitrator.
5//!
6//! The [`Component` enum](enum.Component.html) is the top level
7//! message sent by Component/Clients.
8
9use crate::{PubSubPath, Version};
10use serde::{Deserialize, Serialize};
11
12/// Component Message
13///
14/// This is the primary message sent FROM the peripheral
15/// Component/Client, TO the central Arbitrator.
16#[derive(Debug, Serialize, Deserialize, Eq, PartialEq)]
17pub enum Component<'a> {
18    /// Control Messages
19    ///
20    /// These are used to establish or manage the connection
21    /// between the Component/Client and Arbitrator
22    #[serde(borrow)]
23    Control(Control<'a>),
24
25    /// Pub/Sub messages
26    ///
27    /// These are used to send or receive Pub/Sub messages
28    #[serde(borrow)]
29    PubSub(PubSub<'a>),
30}
31
32/// Pub/Sub Message
33///
34/// These messages are used to communicate on the Pub/Sub
35/// communication layer
36#[derive(Debug, Serialize, Deserialize, Eq, PartialEq)]
37pub struct PubSub<'a> {
38    /// The path in question, common to all message types
39    #[serde(borrow)]
40    pub path: PubSubPath<'a>,
41
42    /// The pub/sub message type
43    pub ty: PubSubType<'a>,
44}
45
46/// Pub/Sub Message Type
47///
48/// The specific kind of pub/sub message
49#[derive(Debug, Serialize, Deserialize, Eq, PartialEq)]
50pub enum PubSubType<'a> {
51    /// Publish Message
52    ///
53    /// Publish the given message/payload on the given path
54    Pub { payload: &'a [u8] },
55
56    /// Subscribe Message
57    ///
58    /// Subscribe to the given path
59    Sub,
60
61    /// Unsubscribe Message
62    ///
63    /// Unsubscribe to the given path
64    Unsub,
65}
66
67/// Control Messages
68///
69/// These messages are used to communicate on the control layer
70#[derive(Debug, Serialize, Deserialize, Eq, PartialEq)]
71pub struct Control<'a> {
72    /// Sequence Number
73    ///
74    /// This number is chosen by the Client/Component, and
75    /// will be echoed back by the Arbitrator when replying
76    pub seq: u16,
77
78    /// Control Message Type
79    ///
80    /// The specific control message
81    #[serde(borrow)]
82    pub ty: ControlType<'a>,
83}
84
85/// Control Message Type
86///
87/// The specific kind of Control Message
88#[derive(Debug, Serialize, Deserialize, Eq, PartialEq)]
89pub enum ControlType<'a> {
90    /// Register Component
91    ///
92    /// This message is used to establish/reset the connection
93    /// between a given client and an Arbitrator
94    #[serde(borrow)]
95    RegisterComponent(ComponentInfo<'a>),
96
97    /// Register PubSubShortID
98    ///
99    /// This message is used to register a path "short code",
100    /// which can use a u16 instead of a full utf-8 path to save
101    /// message bandwidth
102    #[serde(borrow)]
103    RegisterPubSubShortId(PubSubShort<'a>),
104}
105
106/// Information about this Component/Client needed for
107/// registration
108#[derive(Debug, Serialize, Deserialize, Eq, PartialEq)]
109pub struct ComponentInfo<'a> {
110    /// The name of the Client/Component
111    #[serde(borrow)]
112    pub name: crate::Name<'a>,
113
114    /// The verson of the Client/Component
115    pub version: Version,
116}
117
118/// Pub/Sub Short Code Registration
119#[derive(Debug, Serialize, Deserialize, Eq, PartialEq)]
120pub struct PubSubShort<'a> {
121    /// The 'long' UTF-8 path to register
122    pub long_name: &'a str,
123
124    /// The 'short' u16 path to register
125    pub short_id: u16,
126}
127
128#[cfg(test)]
129mod test {
130    use super::*;
131    use postcard::{from_bytes, to_stdvec};
132
133    #[test]
134    fn ser_check() {
135        let name = crate::Name::borrow_from_str("cool-board");
136        let version = Version {
137            major: 0,
138            minor: 1,
139            trivial: 0,
140            misc: 123,
141        };
142
143        let msg = Component::Control(Control {
144            seq: 0x0504,
145            ty: ControlType::RegisterComponent(ComponentInfo { name, version }),
146        });
147
148        let ser_msg = to_stdvec(&msg).unwrap();
149        assert_eq!(
150            &ser_msg[..],
151            &[
152                0x00, // Component::Control
153                0x04, 0x05, // seq
154                0x00, // ControlType::RegisterComponent
155                0x0A, b'c', b'o', b'o', b'l', b'-', b'b', b'o', b'a', b'r', b'd', 0x00, 0x01, 0x00,
156                123,
157            ]
158        );
159
160        let deser_msg: Component = from_bytes(&ser_msg).unwrap();
161
162        assert_eq!(msg, deser_msg);
163    }
164}