use alloc::string::String;
pub const REQUEST_API_KEY: &str = "OMG-DDS-API-Key";
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct RequestHeaders {
pub accept: Option<String>,
pub content_type: Option<String>,
pub content_length: Option<u64>,
pub cache_control: Option<String>,
pub api_key: Option<String>,
}
impl RequestHeaders {
pub fn validate_required(&self) -> Result<(), MissingHeader> {
if self.api_key.is_none() {
return Err(MissingHeader::ApiKey);
}
if self.accept.is_none() {
return Err(MissingHeader::Accept);
}
if self.cache_control.is_none() {
return Err(MissingHeader::CacheControl);
}
Ok(())
}
}
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct ResponseHeaders {
pub authentication_info: Option<String>,
pub cache_control: Option<String>,
pub content_length: Option<u64>,
pub content_type: Option<String>,
pub date: Option<String>,
pub expires: Option<String>,
pub location: Option<String>,
pub last_modified: Option<String>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum MissingHeader {
ApiKey,
Accept,
CacheControl,
}
impl core::fmt::Display for MissingHeader {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
match self {
Self::ApiKey => f.write_str("missing OMG-DDS-API-Key"),
Self::Accept => f.write_str("missing Accept"),
Self::CacheControl => f.write_str("missing Cache-Control"),
}
}
}
#[cfg(feature = "std")]
impl std::error::Error for MissingHeader {}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn request_api_key_constant_matches_spec() {
assert_eq!(REQUEST_API_KEY, "OMG-DDS-API-Key");
}
#[test]
fn validate_required_passes_with_all_three_headers() {
let h = RequestHeaders {
accept: Some(String::from("application/zerodds-web+xml")),
cache_control: Some(String::from("no-cache")),
api_key: Some(String::from("secret-key-1234")),
..Default::default()
};
assert_eq!(h.validate_required(), Ok(()));
}
#[test]
fn missing_api_key_rejected() {
let h = RequestHeaders {
accept: Some(String::from("application/zerodds-web+xml")),
cache_control: Some(String::from("no-cache")),
..Default::default()
};
assert_eq!(h.validate_required(), Err(MissingHeader::ApiKey));
}
#[test]
fn missing_accept_rejected() {
let h = RequestHeaders {
cache_control: Some(String::from("no-cache")),
api_key: Some(String::from("k")),
..Default::default()
};
assert_eq!(h.validate_required(), Err(MissingHeader::Accept));
}
#[test]
fn missing_cache_control_rejected() {
let h = RequestHeaders {
accept: Some(String::from("application/zerodds-web+xml")),
api_key: Some(String::from("k")),
..Default::default()
};
assert_eq!(h.validate_required(), Err(MissingHeader::CacheControl));
}
#[test]
fn response_headers_default_is_empty() {
let r = ResponseHeaders::default();
assert!(r.cache_control.is_none());
assert!(r.content_type.is_none());
assert!(r.location.is_none());
}
}