rustifact/phf/
set.rs

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