1use bytes::Bytes;
4use std::collections::HashMap;
5use std::sync::Arc;
6
7#[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
60pub 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}