use std::collections::HashMap;
use crate::body::Body;
use crate::value::Value;
#[derive(Debug, Clone)]
pub struct Message {
pub headers: HashMap<String, Value>,
pub body: Body,
}
impl Default for Message {
fn default() -> Self {
Self {
headers: HashMap::new(),
body: Body::Empty,
}
}
}
impl Message {
pub fn new(body: impl Into<Body>) -> Self {
Self {
headers: HashMap::new(),
body: body.into(),
}
}
pub fn header(&self, key: &str) -> Option<&Value> {
self.headers.get(key)
}
pub fn header_ic(&self, key: &str) -> Option<&Value> {
self.headers
.iter()
.find(|(k, _)| k.eq_ignore_ascii_case(key))
.map(|(_, v)| v)
}
pub fn set_header(&mut self, key: impl Into<String>, value: impl Into<Value>) {
self.headers.insert(key.into(), value.into());
}
pub fn set_header_normalized(&mut self, key: impl Into<String>, value: impl Into<Value>) {
self.headers
.insert(key.into().to_ascii_lowercase(), value.into());
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_message_default() {
let msg = Message::default();
assert!(msg.body.is_empty());
assert!(msg.headers.is_empty());
}
#[test]
fn test_message_new_with_body() {
let msg = Message::new("hello");
assert_eq!(msg.body.as_text(), Some("hello"));
}
#[test]
fn test_message_headers() {
let mut msg = Message::default();
msg.set_header("key", Value::String("value".into()));
assert_eq!(msg.header("key"), Some(&Value::String("value".into())));
assert_eq!(msg.header("missing"), None);
}
#[test]
fn test_header_ic_case_insensitive() {
let mut msg = Message::default();
msg.set_header("Content-Type", Value::String("application/json".into()));
assert_eq!(
msg.header_ic("content-type"),
Some(&Value::String("application/json".into()))
);
assert_eq!(
msg.header_ic("CONTENT-TYPE"),
Some(&Value::String("application/json".into()))
);
}
#[test]
fn test_set_header_normalized_lowercases_key() {
let mut msg = Message::default();
msg.set_header_normalized("X-Request-Id", Value::String("abc-123".into()));
assert!(msg.headers.contains_key("x-request-id"));
assert_eq!(
msg.header("x-request-id"),
Some(&Value::String("abc-123".into()))
);
}
}