rustifact/phf/
ordered_set.rs

1use crate::tokens::ToTokenStream;
2use proc_macro2::TokenStream;
3use quote::quote;
4
5/// A compile time builder for an order-preserving immutable set.
6///
7/// Produces a highly optimised `OrderedSet` when output (for example, by `write_static!`) from the build script.
8///
9/// Internally, this is a wrapper for `phf_codegen::OrderedSet` from the excellent
10/// [phf_codegen](https://crates.io/crates/phf_codegen) crate.
11///
12/// *This API requires the following crate feature to be activated: `set`*
13pub struct OrderedSetBuilder<T>(phf_codegen::OrderedSet<T>);
14
15/// An order-preserving immutable set with lookup via a perfect hash function.
16///
17/// Constructable at compile time with a `BuildOrderedSet`. Unlike a `Set`, iteration order is guaranteed to
18/// match the definition order.
19///
20/// Internally, this is a wrapper for `phf::OrderedSet` from the excellent
21/// [phf](https://crates.io/crates/phf) crate.
22///
23/// *This API requires the following crate feature to be activated: `set`*
24pub struct OrderedSet<T: 'static>(phf::OrderedSet<T>);
25
26impl<T> OrderedSetBuilder<T>
27where
28    T: ToTokenStream + std::hash::Hash + phf_shared::PhfHash + Eq + phf_shared::FmtConst,
29{
30    pub fn new() -> OrderedSetBuilder<T> {
31        let mut internal = phf_codegen::OrderedSet::new();
32        internal.phf_path("rustifact::internal::phf");
33        OrderedSetBuilder(internal)
34    }
35
36    #[inline]
37    pub fn entry(&mut self, value: T) {
38        self.0.entry(value);
39    }
40}
41
42impl<T> OrderedSet<T> {
43    #[inline]
44    pub const fn len(&self) -> usize {
45        self.0.len()
46    }
47
48    #[inline]
49    pub const fn is_empty(&self) -> bool {
50        self.0.is_empty()
51    }
52
53    #[inline]
54    pub fn contains<U>(&self, value: &U) -> bool
55    where
56        U: phf_shared::PhfHash + Eq + ?Sized,
57        T: phf_shared::PhfBorrow<U>,
58    {
59        self.0.contains(value)
60    }
61
62    #[inline]
63    pub fn get_key<U>(&self, value: &U) -> Option<&T>
64    where
65        U: phf_shared::PhfHash + Eq + ?Sized,
66        T: phf_shared::PhfBorrow<U>,
67    {
68        self.0.get_key(value)
69    }
70
71    #[inline]
72    pub fn iter(&self) -> phf::ordered_set::Iter<'_, T> {
73        self.0.iter()
74    }
75
76    /// An implementation detail. You shouldn't need to call this function.
77    #[inline]
78    pub const fn init_raw(set: phf::OrderedSet<T>) -> OrderedSet<T> {
79        OrderedSet(set)
80    }
81}
82
83impl<T> ToTokenStream for OrderedSetBuilder<T>
84where
85    T: ToTokenStream + std::hash::Hash + phf_shared::PhfHash + Eq + phf_shared::FmtConst,
86{
87    fn to_toks(&self, tokens: &mut TokenStream) {
88        let set_toks_str = self.0.build().to_string();
89        if let Ok(t) = crate::internal::parse_str::<syn::Expr>(&set_toks_str) {
90            tokens.extend(quote! { rustifact::OrderedSet::init_raw(#t) });
91        } else {
92            panic!("Couldn't parse the expression '{}'", set_toks_str);
93        }
94    }
95}