Skip to content

Commit a8e29ef

Browse files
committed
docs(header): greatly expand on implementing custom headers
1 parent 7452dfa commit a8e29ef

File tree

1 file changed

+74
-0
lines changed

1 file changed

+74
-0
lines changed

src/header/mod.rs

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,80 @@
44
//! why we're using Rust in the first place. To set or get any header, an object
55
//! must implement the `Header` trait from this module. Several common headers
66
//! 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+
//! Hyper provides a large amount of the most common headers used in HTTP. If
18+
//! you need to define a custom header, it's easy to do while still taking
19+
//! advantage of the type system. Hyper includes a `header!` macro for defining
20+
//! many wrapper-style headers.
21+
//!
22+
//! ```
23+
//! #[macro_use] extern crate hyper;
24+
//! use hyper::header::Headers;
25+
//! header! { (XRequestGuid, "X-Request-Guid") => [String] }
26+
//!
27+
//! fn main () {
28+
//! let mut headers = Headers::new();
29+
//!
30+
//! headers.set(XRequestGuid("a proper guid".to_owned()))
31+
//! }
32+
//! ```
33+
//!
34+
//! This works well for simiple "string" headers. But the header system
35+
//! actually invovles 2 parts: parsing, and formatting. If you need to
36+
//! customize either part, you can do so.
37+
//!
38+
//! ## `Header` and `HeaderFormat`
39+
//!
40+
//! Consider a Do Not Track header. It can be true or false, but it represents
41+
//! that via the numerals `1` and `0`.
42+
//!
43+
//! ```
44+
//! use std::fmt;
45+
//! use hyper::header::{Header, HeaderFormat};
46+
//!
47+
//! #[derive(Debug, Clone, Copy)]
48+
//! struct Dnt(bool);
49+
//!
50+
//! impl Header for Dnt {
51+
//! fn header_name() -> &'static str {
52+
//! "DNT"
53+
//! }
54+
//!
55+
//! fn parse_header(raw: &[Vec<u8>]) -> hyper::Result<Dnt> {
56+
//! if raw.len() == 1 {
57+
//! let line = &raw[0];
58+
//! if line.len() == 1 {
59+
//! let byte = line[0];
60+
//! match byte {
61+
//! b'0' => return Ok(Dnt(true)),
62+
//! b'1' => return Ok(Dnt(false)),
63+
//! _ => ()
64+
//! }
65+
//! }
66+
//! }
67+
//! Err(hyper::Error::Header)
68+
//! }
69+
//! }
70+
//!
71+
//! impl HeaderFormat for Dnt {
72+
//! fn fmt_header(&self, f: &mut fmt::Formatter) -> fmt::Result {
73+
//! if self.0 {
74+
//! f.write_str("1")
75+
//! } else {
76+
//! f.write_str("0")
77+
//! }
78+
//! }
79+
//! }
80+
//! ```
781
use std::any::Any;
882
use std::borrow::{Cow, ToOwned};
983
use std::collections::HashMap;

0 commit comments

Comments
 (0)