1 //! Declaration for the Keyword trait.
2 
3 use crate::parse::rules;
4 use std::hash::Hash;
5 
6 /// A Keyword identifies the possible types of a keyword for an Item.
7 ///
8 /// These do not map one-to-one to Item strings: several Item strings
9 /// may be placed in a single Keyword -- for example, when their order
10 /// is significant with respect to one another, like "accept" and
11 /// "reject" in router descriptors.
12 ///
13 /// Every keyword has an "index", which is a small number suitable for
14 /// indexing an array.  These are used in Section and SectionRules.
15 ///
16 /// Turning a string into a keyword cannot fail: there is always an
17 /// "UNRECOGNIZED" keyword.
18 ///
19 /// See macro::decl_keyword! for help defining a Keyword type for a
20 /// network document.
21 ///
22 /// TODO: I'd rather have this be pub(crate), but I haven't figured out
23 /// how to make that work; there is a cascading change of other stuff that
24 /// would need to be more hidden.
25 pub trait Keyword: Hash + Eq + PartialEq + Copy + Clone {
26     /// Find a Keyword corresponding to a string that appears in a
27     /// network document.
from_str(s: &str) -> Self28     fn from_str(s: &str) -> Self;
29     /// Try to find the keyword corresponding to a given index value,
30     /// as used in Section and SectionRules.
from_idx(i: usize) -> Option<Self>31     fn from_idx(i: usize) -> Option<Self>;
32     /// Find a string corresponding to this keyword.  This may not be the
33     /// actual string from the document; it is intended for reporting errors.
to_str(self) -> &'static str34     fn to_str(self) -> &'static str;
35     /// Return the index for this keyword.
idx(self) -> usize36     fn idx(self) -> usize;
37     /// Return the number of indices for this keyword.
n_vals() -> usize38     fn n_vals() -> usize;
39     /// Return the "UNRECOGNIZED" keyword.
unrecognized() -> Self40     fn unrecognized() -> Self;
41     /// Return the "ANN_UNRECOGNIZED" keyword.
ann_unrecognized() -> Self42     fn ann_unrecognized() -> Self;
43     /// Return true iff this keyword denotes an annotation.
is_annotation(self) -> bool44     fn is_annotation(self) -> bool;
45     /// Convert from an index to a human-readable string.
idx_to_str(i: usize) -> &'static str46     fn idx_to_str(i: usize) -> &'static str {
47         Self::from_idx(i)
48             .map(|x| x.to_str())
49             .unwrap_or("<out of range>")
50     }
51     /// Return a new TokenFmtBuilder for creating rules about this keyword.
rule(self) -> rules::TokenFmtBuilder<Self>52     fn rule(self) -> rules::TokenFmtBuilder<Self> {
53         rules::TokenFmtBuilder::new(self)
54     }
55 }
56