1pub mod events;
2pub mod extensions;
3
4use crate::Result;
5use axum::{headers::Header, http::HeaderName};
6use std::sync::OnceLock;
7
8pub use extensions::fetch_extensions_from_blob_store_periodically;
9
10pub struct CloudflareIpCountryHeader(String);
11
12impl Header for CloudflareIpCountryHeader {
13 fn name() -> &'static HeaderName {
14 static CLOUDFLARE_IP_COUNTRY_HEADER: OnceLock<HeaderName> = OnceLock::new();
15 CLOUDFLARE_IP_COUNTRY_HEADER.get_or_init(|| HeaderName::from_static("cf-ipcountry"))
16 }
17
18 fn decode<'i, I>(values: &mut I) -> Result<Self, axum::headers::Error>
19 where
20 Self: Sized,
21 I: Iterator<Item = &'i axum::http::HeaderValue>,
22 {
23 let country_code = values
24 .next()
25 .ok_or_else(axum::headers::Error::invalid)?
26 .to_str()
27 .map_err(|_| axum::headers::Error::invalid())?;
28
29 Ok(Self(country_code.to_string()))
30 }
31
32 fn encode<E: Extend<axum::http::HeaderValue>>(&self, _values: &mut E) {
33 unimplemented!()
34 }
35}
36
37impl std::fmt::Display for CloudflareIpCountryHeader {
38 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
39 write!(f, "{}", self.0)
40 }
41}
42
43pub struct SystemIdHeader(String);
44
45impl Header for SystemIdHeader {
46 fn name() -> &'static HeaderName {
47 static SYSTEM_ID_HEADER: OnceLock<HeaderName> = OnceLock::new();
48 SYSTEM_ID_HEADER.get_or_init(|| HeaderName::from_static("x-zed-system-id"))
49 }
50
51 fn decode<'i, I>(values: &mut I) -> Result<Self, axum::headers::Error>
52 where
53 Self: Sized,
54 I: Iterator<Item = &'i axum::http::HeaderValue>,
55 {
56 let system_id = values
57 .next()
58 .ok_or_else(axum::headers::Error::invalid)?
59 .to_str()
60 .map_err(|_| axum::headers::Error::invalid())?;
61
62 Ok(Self(system_id.to_string()))
63 }
64
65 fn encode<E: Extend<axum::http::HeaderValue>>(&self, _values: &mut E) {
66 unimplemented!()
67 }
68}
69
70impl std::fmt::Display for SystemIdHeader {
71 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
72 write!(f, "{}", self.0)
73 }
74}