rama_http_headers/lib.rs
1//! # Typed HTTP Headers
2//!
3//! rama has the opinion that headers should be strongly-typed, because that's
4//! why we're using Rust in the first place. To set or get any header, an object
5//! must implement the `Header` trait from this module. Several common headers
6//! are already provided, such as `Host`, `ContentType`, `UserAgent`, and others.
7//!
8//! # Why Typed?
9//!
10//! Or, why not stringly-typed? Types give the following advantages:
11//!
12//! - More difficult to typo, since typos in types should be caught by the compiler
13//! - Parsing to a proper type by default
14//!
15//! # Defining Custom Headers
16//!
17//! ## Implementing the `Header` trait
18//!
19//! Consider a Do Not Track header. It can be true or false, but it represents
20//! that via the numerals `1` and `0`.
21//!
22//! ```
23//! use rama_http_types::{HeaderName, HeaderValue};
24//! use rama_http_headers::Header;
25//!
26//! struct Dnt(bool);
27//!
28//! impl Header for Dnt {
29//! fn name() -> &'static HeaderName {
30//! &rama_http_types::header::DNT
31//! }
32//!
33//! fn decode<'i, I>(values: &mut I) -> Result<Self, rama_http_headers::Error>
34//! where
35//! I: Iterator<Item = &'i HeaderValue>,
36//! {
37//! let value = values
38//! .next()
39//! .ok_or_else(rama_http_headers::Error::invalid)?;
40//!
41//! if value == "0" {
42//! Ok(Dnt(false))
43//! } else if value == "1" {
44//! Ok(Dnt(true))
45//! } else {
46//! Err(rama_http_headers::Error::invalid())
47//! }
48//! }
49//!
50//! fn encode<E>(&self, values: &mut E)
51//! where
52//! E: Extend<HeaderValue>,
53//! {
54//! let s = if self.0 {
55//! "1"
56//! } else {
57//! "0"
58//! };
59//!
60//! let value = HeaderValue::from_static(s);
61//!
62//! values.extend(std::iter::once(value));
63//! }
64//! }
65//! ```
66//!
67//! # Rama
68//!
69//! Crate used by the end-user `rama` crate and `rama` crate authors alike.
70//!
71//! Learn more about `rama`:
72//!
73//! - Github: <https://github.com/plabayo/rama>
74//! - Book: <https://ramaproxy.org/book/>
75
76#![doc(
77 html_favicon_url = "https://raw.githubusercontent.com/plabayo/rama/main/docs/img/old_logo.png"
78)]
79#![doc(html_logo_url = "https://raw.githubusercontent.com/plabayo/rama/main/docs/img/old_logo.png")]
80#![cfg_attr(docsrs, feature(doc_auto_cfg, doc_cfg))]
81#![cfg_attr(test, allow(clippy::float_cmp))]
82#![cfg_attr(not(test), warn(clippy::print_stdout, clippy::dbg_macro))]
83
84mod header;
85#[doc(inline)]
86pub use header::{Error, Header};
87
88pub use mime::Mime;
89
90#[macro_use]
91pub mod util;
92
93mod common;
94mod map_ext;
95
96pub mod specifier;
97
98pub use self::common::*;
99pub use self::map_ext::HeaderMapExt;
100
101pub mod encoding;
102pub mod forwarded;
103
104mod client_hints;
105pub use client_hints::{
106 ClientHint, all_client_hint_header_name_strings, all_client_hint_header_names, all_client_hints,
107};
108
109pub mod dep {
110 //! dependencies rama-http-headers
111
112 pub use mime;
113}