architect_api/utils/
envelope.rs1#[cfg(feature = "netidx")]
2use crate::TypedMessage;
3use crate::{ComponentId, MessageTopic, UserId};
4use anyhow::Result;
5#[cfg(feature = "netidx")]
6use derive::FromValue;
7use enumflags2::BitFlags;
8#[cfg(feature = "netidx")]
9use netidx_derive::Pack;
10use schemars::JsonSchema;
11use serde::{Deserialize, Serialize};
12use uuid::Uuid;
13
14#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize, JsonSchema)]
15#[cfg_attr(feature = "netidx", derive(Pack))]
16#[cfg_attr(feature = "netidx", derive(FromValue))]
17pub enum Address {
18 Component(ComponentId),
19 Channel(UserId, u32),
20 ChannelSubscriptionOnly,
25}
26
27impl From<ComponentId> for Address {
28 #[inline(always)]
29 fn from(id: ComponentId) -> Self {
30 Self::Component(id)
31 }
32}
33
34impl std::fmt::Display for Address {
35 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
36 match self {
37 Address::Component(id) => write!(f, "#{}", id),
38 Address::Channel(user_id, channel) => write!(f, "{}:{}", user_id, channel),
39 Address::ChannelSubscriptionOnly => write!(f, "~"),
40 }
41 }
42}
43
44impl Address {
45 #[inline(always)]
46 pub fn is_loopback(&self) -> bool {
47 match self {
48 Address::Component(id) => id.is_loopback(),
49 Address::Channel(..) => false,
50 Address::ChannelSubscriptionOnly => false,
51 }
52 }
53
54 #[inline(always)]
55 pub fn component<T>(id: T) -> Result<Self>
56 where
57 T: TryInto<ComponentId>,
58 <T as TryInto<ComponentId>>::Error: std::error::Error + Send + Sync + 'static,
59 {
60 Ok(Self::Component(id.try_into()?))
61 }
62
63 pub fn component_id(&self) -> Option<ComponentId> {
64 match self {
65 Address::Component(id) => Some(*id),
66 _ => None,
67 }
68 }
69
70 pub fn user_id(&self) -> Option<UserId> {
71 match self {
72 Address::Channel(user_id, _) => Some(*user_id),
73 _ => None,
74 }
75 }
76}
77
78#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, JsonSchema)]
80#[cfg_attr(feature = "netidx", derive(Pack))]
81#[cfg_attr(feature = "netidx", derive(FromValue))]
82pub struct Envelope<M: 'static> {
83 pub src: Address,
84 pub dst: Address,
85 pub stamp: Stamp,
86 pub msg: M,
87}
88
89impl<M> Envelope<M> {
90 pub fn system_control(msg: M) -> Self {
91 Self {
92 src: Address::Component(ComponentId::none()),
93 dst: Address::Component(ComponentId::none()),
94 stamp: Stamp::new(None, Default::default()),
95 msg,
96 }
97 }
98}
99
100#[cfg(feature = "netidx")]
101impl Envelope<TypedMessage> {
102 pub fn topics(&self) -> BitFlags<MessageTopic> {
103 self.msg.topics() | self.stamp.additional_topics
104 }
105}
106
107#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, JsonSchema)]
108#[cfg_attr(feature = "netidx", derive(Pack))]
109#[cfg_attr(feature = "netidx", derive(FromValue))]
110pub struct Stamp {
111 pub user_id: Option<UserId>,
112 pub sequence: Option<Sequence>,
113 pub additional_topics: BitFlags<MessageTopic>,
114}
115
116impl Stamp {
117 pub fn new(
121 user_id: Option<UserId>,
122 additional_topics: BitFlags<MessageTopic>,
123 ) -> Self {
124 Self { user_id, sequence: None, additional_topics }
125 }
126}
127
128#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, JsonSchema)]
129#[cfg_attr(feature = "netidx", derive(Pack))]
130#[cfg_attr(feature = "netidx", derive(FromValue))]
131pub enum Sequence {
132 Local(u64),
133 Remote { core_id: Uuid, last_seqno: Option<u64>, seqno: u64 },
134}