diff --git a/tor-netdoc/src/keyword.rs b/tor-netdoc/src/keyword.rs index 00418446a..db2ec3ef8 100644 --- a/tor-netdoc/src/keyword.rs +++ b/tor-netdoc/src/keyword.rs @@ -25,11 +25,13 @@ pub trait Keyword: Hash + Eq + PartialEq + Copy + Clone { fn from_idx(i: usize) -> Option; /// Find a string corresponding to this keyword. This may not be the /// actual string from the document; it is indended for reporting errors. - fn to_str(&self) -> &'static str; + fn to_str(self) -> &'static str; /// Return the index for this keyword. fn idx(self) -> usize; /// Return the number of indices for this keyword. fn n_vals() -> usize; + /// Return true iff this keyword denotes an annotation. + fn is_annotation(self) -> bool; /// Convert from an index to a human-readable string. fn idx_to_str(i: usize) -> &'static str { Self::from_idx(i) @@ -37,7 +39,7 @@ pub trait Keyword: Hash + Eq + PartialEq + Copy + Clone { .unwrap_or("") } /// Return a new TokenFmtBuilder for creating rules about this keyword. - fn rule(&self) -> rules::TokenFmtBuilder { - rules::TokenFmtBuilder::new(*self) + fn rule(self) -> rules::TokenFmtBuilder { + rules::TokenFmtBuilder::new(self) } } diff --git a/tor-netdoc/src/macros.rs b/tor-netdoc/src/macros.rs index c5caf1883..f0a694af5 100644 --- a/tor-netdoc/src/macros.rs +++ b/tor-netdoc/src/macros.rs @@ -21,7 +21,7 @@ /// ``` macro_rules! decl_keyword { { $(#[$meta:meta])* $v:vis - $name:ident { $( $($s:literal)|+ => $i:ident),* $(,)? } } => { + $name:ident { $( $($anno:ident)? $($s:literal)|+ => $i:ident),* $(,)? } } => { #[derive(Copy,Clone,Eq,PartialEq,Debug,std::hash::Hash)] #[allow(non_camel_case_types)] $(#[$meta])* @@ -61,7 +61,7 @@ macro_rules! decl_keyword { }; VALS.get(i).copied() } - fn to_str(&self) -> &'static str { + fn to_str(self) -> &'static str { use $name::*; match self { // TODO: this turns "accept" | "reject" into @@ -72,6 +72,17 @@ macro_rules! decl_keyword { ANN_UNRECOGNIZED => "" } } + fn is_annotation(self) -> bool { + use $name::*; + match self { + $( $i => decl_keyword![@impl is_anno $($anno)? ], )* + UNRECOGNIZED => false, + ANN_UNRECOGNIZED => true, + } + } } - } + }; + [ @impl is_anno annotation ] => ( true ); + [ @impl is_anno $x:ident ] => ( compile_error!("unrecognized keyword; not annotation") ); + [ @impl is_anno ] => ( false ); } diff --git a/tor-netdoc/src/microdesc.rs b/tor-netdoc/src/microdesc.rs index 7ded712f4..4f7672928 100644 --- a/tor-netdoc/src/microdesc.rs +++ b/tor-netdoc/src/microdesc.rs @@ -1,7 +1,7 @@ //! Parsing implementation for Tor microdescriptors. //! //! A "microdescriptor" is an incomplete, infrequently-changing -//! summary of a relay's informatino information that is generated by +//! summary of a relay's information that is generated by //! the directory authorities. //! //! Microdescriptors are much smaller than router descriptors, and @@ -41,6 +41,7 @@ pub struct Microdesc { decl_keyword! { /// Keyword type for recognized objects in microdescriptors. MicrodescKW { + annotation "last-listed" => A_LAST_LISTED, "onion-key" => ONION_KEY, "ntor-onion-key" => NTOR_ONION_KEY, "family" => FAMILY, diff --git a/tor-netdoc/src/routerdesc.rs b/tor-netdoc/src/routerdesc.rs index 6f32e8a6a..afba602d6 100644 --- a/tor-netdoc/src/routerdesc.rs +++ b/tor-netdoc/src/routerdesc.rs @@ -113,6 +113,8 @@ decl_keyword! { /// RouterKW is an instance of Keyword, used to denote the different /// Items that are recognized as appearing in a router descriptor. RouterKW { + annotation "@source" => A_SOURCE, + annotation "@downloaded-at" => A_DOWNLOADED_AT, "accept" | "reject" => POLICY, "bandwidth" => BANDWIDTH, "bridge-distribution-request" => BRIDGE_DISTRIBUTION_REQUEST,