Skip to main content

coreon_core/
message.rs

1//! Message — payload + headers, the in/out of an Exchange.
2
3use bytes::Bytes;
4use std::collections::HashMap;
5use std::sync::Arc;
6
7/// Body variants carried by a Message.
8///
9/// `Custom` uses `Arc<dyn Any>` so arbitrary application types can flow
10/// through the pipeline without the core knowing about them.
11#[derive(Clone, Debug, Default)]
12pub enum Body {
13    #[default]
14    Empty,
15    Bytes(Bytes),
16    Text(String),
17    Custom(Arc<dyn std::any::Any + Send + Sync>),
18}
19
20impl Body {
21    pub fn as_text(&self) -> Option<&str> {
22        match self {
23            Body::Text(s) => Some(s.as_str()),
24            _ => None,
25        }
26    }
27
28    pub fn as_bytes(&self) -> Option<&Bytes> {
29        match self {
30            Body::Bytes(b) => Some(b),
31            _ => None,
32        }
33    }
34}
35
36impl From<String> for Body {
37    fn from(s: String) -> Self {
38        Body::Text(s)
39    }
40}
41
42impl From<&str> for Body {
43    fn from(s: &str) -> Self {
44        Body::Text(s.to_owned())
45    }
46}
47
48impl From<Bytes> for Body {
49    fn from(b: Bytes) -> Self {
50        Body::Bytes(b)
51    }
52}
53
54impl From<Vec<u8>> for Body {
55    fn from(v: Vec<u8>) -> Self {
56        Body::Bytes(Bytes::from(v))
57    }
58}
59
60/// Header values are string-typed for MVP. A future revision may widen
61/// this to a tagged enum if performance/type-safety demands it.
62pub type HeaderMap = HashMap<String, String>;
63
64#[derive(Clone, Debug, Default)]
65pub struct Message {
66    pub headers: HeaderMap,
67    pub body: Body,
68}
69
70impl Message {
71    pub fn new(body: impl Into<Body>) -> Self {
72        Self {
73            headers: HeaderMap::new(),
74            body: body.into(),
75        }
76    }
77
78    pub fn with_header(mut self, k: impl Into<String>, v: impl Into<String>) -> Self {
79        self.headers.insert(k.into(), v.into());
80        self
81    }
82
83    pub fn header(&self, k: &str) -> Option<&str> {
84        self.headers.get(k).map(|s| s.as_str())
85    }
86}