]>
git.proxmox.com Git - rustc.git/blob - src/vendor/phf_codegen/src/lib.rs
1 //! A set of builders to generate Rust source for PHF data structures at
4 //! The provided builders are intended to be used in a Cargo build script to
5 //! generate a Rust source file that will be included in a library at build
13 //! extern crate phf_codegen;
16 //! use std::fs::File;
17 //! use std::io::{BufWriter, Write};
18 //! use std::path::Path;
21 //! let path = Path::new(&env::var("OUT_DIR").unwrap()).join("codegen.rs");
22 //! let mut file = BufWriter::new(File::create(&path).unwrap());
24 //! write!(&mut file, "static KEYWORDS: phf::Map<&'static str, Keyword> =
26 //! phf_codegen::Map::new()
27 //! .entry("loop", "Keyword::Loop")
28 //! .entry("continue", "Keyword::Continue")
29 //! .entry("break", "Keyword::Break")
30 //! .entry("fn", "Keyword::Fn")
31 //! .entry("extern", "Keyword::Extern")
34 //! write!(&mut file, ";\n").unwrap();
52 //! include!(concat!(env!("OUT_DIR"), "/codegen.rs"));
54 //! pub fn parse_keyword(keyword: &str) -> Option<Keyword> {
55 //! KEYWORDS.get(keyword).cloned()
61 //! The compiler's stack will overflow when processing extremely long method
62 //! chains (500+ calls). When generating large PHF data structures, consider
63 //! looping over the entries or making each call a separate statement:
66 //! let entries = [("hello", "1"), ("world", "2")];
68 //! let mut builder = phf_codegen::Map::new();
69 //! for &(key, value) in &entries {
70 //! builder.entry(key, value);
76 //! let mut builder = phf_codegen::Map::new();
77 //! builder.entry("hello", "1");
78 //! builder.entry("world", "2");
81 #![doc(html_root_url="https://docs.rs/phf_codegen/0.7.20")]
82 extern crate phf_shared
;
83 extern crate phf_generator
;
85 use phf_shared
::PhfHash
;
86 use std
::collections
::HashSet
;
90 use std
::io
::prelude
::*;
92 /// A builder for the `phf::Map` type.
99 impl<K
: Hash
+PhfHash
+Eq
+fmt
::Debug
> Map
<K
> {
100 /// Creates a new `phf::Map` builder.
101 pub fn new() -> Map
<K
> {
104 // On Windows/MSVC there are major problems with the handling of dllimport.
105 // Here, because downstream build scripts only invoke generics from phf_codegen,
106 // the linker ends up throwing a way a bunch of static symbols we actually need.
107 // This works around the problem, assuming that all clients call `Map::new` by
108 // calling a non-generic function.
109 fn noop_fix_for_27438() {
111 noop_fix_for_27438();
116 path
: String
::from("::phf"),
120 /// Set the path to the `phf` crate from the global namespace
121 pub fn phf_path(&mut self, path
: &str) -> &mut Map
<K
> {
122 self.path
= path
.to_owned();
126 /// Adds an entry to the builder.
128 /// `value` will be written exactly as provided in the constructed source.
129 pub fn entry(&mut self, key
: K
, value
: &str) -> &mut Map
<K
> {
131 self.values
.push(value
.to_owned());
135 /// Constructs a `phf::Map`, outputting Rust source to the provided writer.
139 /// Panics if there are any duplicate keys.
140 pub fn build
<W
: Write
>(&self, w
: &mut W
) -> io
::Result
<()> {
141 let mut set
= HashSet
::new();
142 for key
in &self.keys
{
143 if !set
.insert(key
) {
144 panic
!("duplicate key `{:?}`", key
);
148 let state
= phf_generator
::generate_hash(&self.keys
);
153 disps: {}::Slice::Static(&[",
154 self.path
, state
.key
, self.path
));
155 for &(d1
, d2
) in &state
.disps
{
165 entries: {}::Slice::Static(&[", self.path
));
166 for &idx
in &state
.map
{
180 /// A builder for the `phf::Set` type.
185 impl<T
: Hash
+PhfHash
+Eq
+fmt
::Debug
> Set
<T
> {
186 /// Constructs a new `phf::Set` builder.
187 pub fn new() -> Set
<T
> {
193 /// Set the path to the `phf` crate from the global namespace
194 pub fn phf_path(&mut self, path
: &str) -> &mut Set
<T
> {
195 self.map
.phf_path(path
);
199 /// Adds an entry to the builder.
200 pub fn entry(&mut self, entry
: T
) -> &mut Set
<T
> {
201 self.map
.entry(entry
, "()");
205 /// Constructs a `phf::Set`, outputting Rust source to the provided writer.
209 /// Panics if there are any duplicate entries.
210 pub fn build
<W
: Write
>(&self, w
: &mut W
) -> io
::Result
<()> {
211 try
!(write
!(w
, "{}::Set {{ map: ", self.map
.path
));
212 try
!(self.map
.build(w
));
217 /// A builder for the `phf::OrderedMap` type.
218 pub struct OrderedMap
<K
> {
224 impl<K
: Hash
+PhfHash
+Eq
+fmt
::Debug
> OrderedMap
<K
> {
225 /// Constructs a enw `phf::OrderedMap` builder.
226 pub fn new() -> OrderedMap
<K
> {
230 path
: String
::from("::phf"),
234 /// Set the path to the `phf` crate from the global namespace
235 pub fn phf_path(&mut self, path
: &str) -> &mut OrderedMap
<K
> {
236 self.path
= path
.to_owned();
240 /// Adds an entry to the builder.
242 /// `value` will be written exactly as provided in the constructed source.
243 pub fn entry(&mut self, key
: K
, value
: &str) -> &mut OrderedMap
<K
> {
245 self.values
.push(value
.to_owned());
249 /// Constructs a `phf::OrderedMap`, outputting Rust source to the provided
254 /// Panics if there are any duplicate keys.
255 pub fn build
<W
: Write
>(&self, w
: &mut W
) -> io
::Result
<()> {
256 let mut set
= HashSet
::new();
257 for key
in &self.keys
{
258 if !set
.insert(key
) {
259 panic
!("duplicate key `{:?}`", key
);
263 let state
= phf_generator
::generate_hash(&self.keys
);
268 disps: {}::Slice::Static(&[",
269 self.path
, state
.key
, self.path
));
270 for &(d1
, d2
) in &state
.disps
{
280 idxs: {}::Slice::Static(&[", self.path
));
281 for &idx
in &state
.map
{
290 entries: {}::Slice::Static(&[", self.path
));
291 for (key
, value
) in self.keys
.iter().zip(self.values
.iter()) {
305 /// A builder for the `phf::OrderedSet` type.
306 pub struct OrderedSet
<T
> {
310 impl<T
: Hash
+PhfHash
+Eq
+fmt
::Debug
> OrderedSet
<T
> {
311 /// Constructs a new `phf::OrderedSet` builder.
312 pub fn new() -> OrderedSet
<T
> {
314 map
: OrderedMap
::new(),
318 /// Set the path to the `phf` crate from the global namespace
319 pub fn phf_path(&mut self, path
: &str) -> &mut OrderedSet
<T
> {
320 self.map
.phf_path(path
);
324 /// Adds an entry to the builder.
325 pub fn entry(&mut self, entry
: T
) -> &mut OrderedSet
<T
> {
326 self.map
.entry(entry
, "()");
330 /// Constructs a `phf::OrderedSet`, outputting Rust source to the provided
335 /// Panics if there are any duplicate entries.
336 pub fn build
<W
: Write
>(&self, w
: &mut W
) -> io
::Result
<()> {
337 try
!(write
!(w
, "{}::OrderedSet {{ map: ", self.map
.path
));
338 try
!(self.map
.build(w
));