Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add a basic example with HTTP headers #44

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions valuable/examples/http_headers.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
use valuable::*;

#[derive(Valuable)]
struct Headers {
user_agent: String,
host: String,
content_type: ContentType,
accept_encoding: Vec<String>,
}

#[derive(Valuable)]
struct ContentType {
mime: String,
charset: String,
}

// Visit the root of the Headers struct. This visitor will find the
// `accept_encoding` field on `Headers` and extract the contents. All other fields
// are ignored.
struct VisitHeaders {
/// The extracted `accept-encoding` header values.
accept_encoding: Vec<String>,
}

// Visit the `accept-encoding` `Vec`. This visitor iterates the items in the
// list and pushes it into its `accept_encoding` vector.
struct VisitAcceptEncoding<'a> {
accept_encoding: &'a mut Vec<String>,
}

impl Visit for VisitHeaders {
fn visit_value(&mut self, value: Value<'_>) {
// We expect a `Structable` representing the `Headers` struct.
match value {
// Visiting the struct will call `visit_named_fields`.
Value::Structable(v) => v.visit(self),
// Ignore other patterns
_ => {}
}
}

fn visit_named_fields(&mut self, named_values: &NamedValues<'_>) {
// We only care about `accept_encoding`
match named_values.get_by_name("accept_encoding") {
Some(Value::Listable(accept_encoding)) => {
// Create the `VisitAcceptEncoding` instance to visit the items
// in `Listable`.
let mut visit = VisitAcceptEncoding {
accept_encoding: &mut self.accept_encoding,
};
accept_encoding.visit(&mut visit);
}
_ => {}
}
}
}

impl Visit for VisitAcceptEncoding<'_> {
/// Method called when visiting a `Listable`.
fn visit_value(&mut self, value: Value<'_>) {
if let Some(accept_encoding) = value.as_str() {
self.accept_encoding.push(accept_encoding.to_string())
}
}
}

fn main() {
let headers = Headers {
user_agent: "Mozilla/4.0 (compatible; MSIE5.01; Windows NT)".to_string(),
host: "www.example.com".to_string(),
content_type: ContentType {
mime: "text/xml".to_string(),
charset: "utf-8".to_string(),
},
accept_encoding: vec!["gzip".to_string(), "deflate".to_string()],
};

// Extract the "accept-encoding" headers
let mut visit = VisitHeaders { accept_encoding: vec![] };
valuable::visit(&headers, &mut visit);

assert_eq!(&["gzip", "deflate"], &visit.accept_encoding[..]);
}