Skip to content

Commit 983529f

Browse files
committed
Document macros.
1 parent ea6843d commit 983529f

File tree

3 files changed

+84
-23
lines changed

3 files changed

+84
-23
lines changed

Cargo.toml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,6 @@ build = "build.rs"
1414

1515
exclude = ["src/css-parsing-tests"]
1616

17-
[lib]
18-
doctest = false
19-
2017
[dev-dependencies]
2118
rustc-serialize = "0.3"
2219
tempdir = "0.3"

macros/lib.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ extern crate syn;
99

1010
use std::ascii::AsciiExt;
1111

12+
/// Find a `#[cssparser__match_ignore_ascii_case__data(string = "…", string = "…")]` attribute,
13+
/// panic if any string contains ASCII uppercase letters,
14+
/// emit a `MAX_LENGTH` constant with the length of the longest string.
1215
#[proc_macro_derive(cssparser__match_ignore_ascii_case__max_len,
1316
attributes(cssparser__match_ignore_ascii_case__data))]
1417
pub fn max_len(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
@@ -30,7 +33,10 @@ pub fn max_len(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
3033
tokens.as_str().parse().unwrap()
3134
}
3235

33-
36+
/// On `struct $Name($ValueType)`, add a new static method
37+
/// `fn map() -> &'static ::phf::Map<&'static str, $ValueType>`.
38+
/// The map’s content is given as:
39+
/// `#[cssparser__phf_map__kv_pairs(key = "…", value = "…", key = "…", value = "…")]`.
3440
#[proc_macro_derive(cssparser__phf_map,
3541
attributes(cssparser__phf_map__kv_pairs))]
3642
pub fn phf_map(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
@@ -70,6 +76,8 @@ pub fn phf_map(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
7076
tokens.as_str().parse().unwrap()
7177
}
7278

79+
/// Panic if the first attribute isn’t `#[foo(…)]` with the given name,
80+
/// or return the parameters.
7381
fn list_attr<'a>(input: &'a syn::DeriveInput, expected_name: &str) -> &'a [syn::NestedMetaItem] {
7482
match input.attrs[0].value {
7583
syn::MetaItem::List(ref name, ref nested) if name == expected_name => {
@@ -81,6 +89,8 @@ fn list_attr<'a>(input: &'a syn::DeriveInput, expected_name: &str) -> &'a [syn::
8189
}
8290
}
8391

92+
/// Panic if `sub_attr` is not a name-value like `foo = "…"` with the given name,
93+
/// or return the value.
8494
fn sub_attr_value<'a>(sub_attr: &'a syn::NestedMetaItem, expected_name: &str) -> &'a str {
8595
match *sub_attr {
8696
syn::NestedMetaItem::MetaItem(

src/lib.rs

Lines changed: 73 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -89,24 +89,36 @@ pub use serializer::{ToCss, CssStringWriter, serialize_identifier, serialize_str
8989
pub use parser::{Parser, Delimiter, Delimiters, SourcePosition};
9090
pub use unicode_range::UnicodeRange;
9191

92-
93-
/**
94-
95-
This macro is equivalent to a `match` expression on an `&str` value,
96-
but matching is case-insensitive in the ASCII range.
97-
98-
Usage example:
99-
100-
```{rust,ignore}
101-
match_ignore_ascii_case! { string,
102-
"foo" => Some(Foo),
103-
"bar" => Some(Bar),
104-
"baz" => Some(Baz),
105-
_ => None
106-
}
107-
```
108-
109-
*/
92+
/// Expands to an expression equivalent to a `match` with string patterns,
93+
/// but matching is case-insensitive in the ASCII range.
94+
///
95+
/// Requirements:
96+
///
97+
/// * The `cssparser_macros` crate must also be imported at the crate root
98+
/// * The patterns must not contain ASCII upper case letters. (They must be already be lower-cased.)
99+
///
100+
/// # Example
101+
///
102+
/// ```rust
103+
/// #[macro_use] extern crate cssparser;
104+
/// #[macro_use] extern crate cssparser_macros;
105+
///
106+
/// # fn main() {} // Make doctest not wrap everythig in its own main
107+
/// # fn dummy(function_name: &String) { let _ =
108+
/// match_ignore_ascii_case! { &function_name,
109+
/// "rgb" => parse_rgb(..),
110+
/// "rgba" => parse_rgba(..),
111+
/// "hsl" => parse_hsl(..),
112+
/// "hsla" => parse_hsla(..),
113+
/// _ => Err("unknown function")
114+
/// }
115+
/// # ;}
116+
/// # use std::ops::RangeFull;
117+
/// # fn parse_rgb(_: RangeFull) -> Result<(), &'static str> { Err("") }
118+
/// # fn parse_rgba(_: RangeFull) -> Result<(), &'static str> { Err("") }
119+
/// # fn parse_hsl(_: RangeFull) -> Result<(), &'static str> { Err("") }
120+
/// # fn parse_hsla(_: RangeFull) -> Result<(), &'static str> { Err("") }
121+
/// ```
110122
#[macro_export]
111123
macro_rules! match_ignore_ascii_case {
112124
// parse the last case plus the fallback
@@ -138,6 +150,38 @@ macro_rules! match_ignore_ascii_case {
138150
};
139151
}
140152

153+
/// Define a placeholder type `$Name`
154+
/// with a method `fn get(input: &str) -> Option<&'static $ValueType>`.
155+
///
156+
/// This method uses finds a match for the input string
157+
/// in a [`phf` map](https://github.com/sfackler/rust-phf).
158+
/// Matching is case-insensitive in the ASCII range.
159+
///
160+
/// Requirements:
161+
///
162+
/// * The `phf` and `cssparser_macros` crates must also be imported at the crate root
163+
/// * The keys must not contain ASCII upper case letters. (They must be already be lower-cased.)
164+
/// * The values must be given a strings that contain Rust syntax for a constant expression.
165+
///
166+
/// ## Example:
167+
///
168+
/// ```rust
169+
/// extern crate phf;
170+
/// #[macro_use] extern crate cssparser;
171+
/// #[macro_use] extern crate cssparser_macros;
172+
///
173+
/// # fn main() {} // Make doctest not wrap everythig in its own main
174+
///
175+
/// fn color_rgb(input: &str) -> Option<(u8, u8, u8)> {
176+
/// ascii_case_insensitive_phf_map! {
177+
/// KEYWORDS: Map<(u8, u8, u8)> = {
178+
/// "red" => "(255, 0, 0)",
179+
/// "green" => "(0, 255, 0)",
180+
/// "blue" => "(0, 0, 255)",
181+
/// }
182+
/// }
183+
/// KEYWORDS::get(input).cloned()
184+
/// }
141185
#[macro_export]
142186
macro_rules! ascii_case_insensitive_phf_map {
143187
($Name: ident : Map<$ValueType: ty> = {
@@ -162,7 +206,14 @@ macro_rules! ascii_case_insensitive_phf_map {
162206
}
163207
}
164208

209+
/// Implementation detail of match_ignore_ascii_case! and ascii_case_insensitive_phf_map! macros.
210+
///
211+
/// * Check at compile-time that none of the `$string`s contain ASCII uppercase letters
212+
/// * Define a local variable named `$output`
213+
/// to the result of calling `_match_ignore_ascii_case__to_lowercase`
214+
/// with a stack-allocated buffer as long as the longest `$string`.
165215
#[macro_export]
216+
#[doc(hidden)]
166217
macro_rules! _cssparser_internal__max_len {
167218
($input: expr => $output: ident, $($string: expr),+) => {
168219
#[derive(cssparser__match_ignore_ascii_case__max_len)]
@@ -183,7 +234,10 @@ macro_rules! _cssparser_internal__max_len {
183234
}
184235

185236

186-
/// Implementation detail of macros.
237+
/// Implementation detail of match_ignore_ascii_case! and ascii_case_insensitive_phf_map! macros.
238+
///
239+
/// Return `input`, lower-cased, unless larger than `buffer`
240+
/// which is used temporary space for lower-casing a copy of `input` if necessary.
187241
#[doc(hidden)]
188242
#[allow(non_snake_case)]
189243
pub fn _match_ignore_ascii_case__to_lowercase<'a>(buffer: &'a mut [u8], input: &'a str) -> Option<&'a str> {

0 commit comments

Comments
 (0)