stablesats_shared/pubsub/
message.rs1use serde::{de::DeserializeOwned, Deserialize, Serialize};
2use uuid::Uuid;
3
4use crate::time::*;
5
6#[derive(
7 Copy, Clone, PartialEq, Eq, Hash, Debug, Default, serde::Serialize, serde::Deserialize,
8)]
9#[serde(transparent)]
10#[repr(transparent)]
11pub struct CorrelationId(Uuid);
12impl CorrelationId {
13 pub fn new() -> Self {
14 let id = Uuid::new_v4();
15 Self(id)
17 }
18}
19impl std::fmt::Display for CorrelationId {
20 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
21 write!(f, "{}", self.0)
22 }
23}
24
25#[derive(Clone, Serialize, Deserialize, Debug)]
26#[serde(rename_all = "camelCase")]
27pub struct MessageMetadata {
28 pub published_at: TimeStamp,
29 pub correlation_id: CorrelationId,
30}
31
32impl MessageMetadata {
33 pub fn new() -> Self {
34 Self {
35 correlation_id: CorrelationId::new(),
36 published_at: TimeStamp::now(),
37 }
38 }
39}
40impl Default for MessageMetadata {
41 fn default() -> Self {
42 Self::new()
43 }
44}
45
46#[derive(Serialize, Deserialize, Debug)]
47#[serde(rename_all = "camelCase")]
48pub struct Envelope<P: MessagePayload> {
49 pub meta: MessageMetadata,
51 pub payload_type: String,
52 #[serde(bound = "P: DeserializeOwned")]
53 pub payload: P,
54}
55
56impl<P: MessagePayload> Envelope<P> {
57 pub(super) fn new(payload: P) -> Self {
58 Self {
59 meta: MessageMetadata::new(),
60 payload_type: <P as MessagePayload>::message_type().to_string(),
61 payload,
62 }
63 }
64}
65
66pub trait MessagePayload:
67 Serialize + DeserializeOwned + Clone + Sized + Sync + Send + Unpin + 'static
68{
69 fn message_type() -> &'static str;
70 fn channel() -> &'static str;
71}
72
73pub mod serialize_as_string {
74 use std::fmt::Display;
75 use std::str::FromStr;
76
77 use serde::{de, Deserialize, Deserializer, Serializer};
78
79 pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
80 where
81 T: Display,
82 S: Serializer,
83 {
84 serializer.collect_str(value)
85 }
86
87 pub fn deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error>
88 where
89 T: FromStr,
90 T::Err: Display,
91 D: Deserializer<'de>,
92 {
93 String::deserialize(deserializer)?
94 .parse()
95 .map_err(de::Error::custom)
96 }
97}