Skip to content

Commit ae2e654

Browse files
committed
Use the quote crate for code generation
1 parent 122d793 commit ae2e654

File tree

2 files changed

+50
-31
lines changed

2 files changed

+50
-31
lines changed

string-cache-codegen/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@ path = "lib.rs"
1515
[dependencies]
1616
string_cache_shared = {path = "../shared", version = "0.3"}
1717
phf_generator = "0.7.15"
18+
quote = "0.3.9"

string-cache-codegen/lib.rs

Lines changed: 49 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@
99

1010
extern crate phf_generator;
1111
extern crate string_cache_shared as shared;
12+
#[macro_use] extern crate quote;
1213

1314
use std::collections::HashSet;
1415
use std::fs::File;
1516
use std::io::{self, Write, BufWriter};
17+
use std::iter;
1618
use std::path::Path;
1719

1820
/// A builder for a static atom set and relevant macros
@@ -67,52 +69,68 @@ impl AtomType {
6769

6870
/// Write generated code to `destination`.
6971
pub fn write_to<W>(&mut self, mut destination: W) -> io::Result<()> where W: Write {
72+
destination.write_all(
73+
self.to_tokens()
74+
.as_str()
75+
// Insert some newlines to make the generated code slightly easier to read.
76+
.replace(" [ \"", "[\n\"")
77+
.replace("\" , ", "\",\n")
78+
.replace(" ( \"", "\n( \"")
79+
.replace("; ", ";\n")
80+
.as_bytes())
81+
}
82+
83+
fn to_tokens(&mut self) -> quote::Tokens {
7084
// `impl Default for Atom` requires the empty string to be in the static set.
7185
// This also makes sure the set in non-empty,
7286
// which would cause divisions by zero in rust-phf.
7387
self.atoms.insert(String::new());
7488

7589
let atoms: Vec<&str> = self.atoms.iter().map(|s| &**s).collect();
7690
let hash_state = phf_generator::generate_hash(&atoms);
77-
let atoms: Vec<&str> = hash_state.map.iter().map(|&idx| atoms[idx]).collect();
78-
let empty_string_index = atoms.iter().position(|s| s.is_empty()).unwrap();
91+
let phf_generator::HashState { key, disps, map } = hash_state;
92+
let atoms: Vec<&str> = map.iter().map(|&idx| atoms[idx]).collect();
93+
let empty_string_index = atoms.iter().position(|s| s.is_empty()).unwrap() as u32;
94+
let data = (0..atoms.len()).map(|i| quote::Hex(shared::pack_static(i as u32)));
7995

8096
let type_name = if let Some(position) = self.path.rfind("::") {
8197
&self.path[position + "::".len() ..]
8298
} else {
8399
&self.path
84100
};
101+
let static_set_name = quote::Ident::from(format!("{}StaticSet", type_name));
102+
let type_name = quote::Ident::from(type_name);
103+
let macro_name = quote::Ident::from(&*self.macro_name);
104+
let path = iter::repeat(quote::Ident::from(&*self.path));
85105

86-
macro_rules! w {
87-
($($arg: expr),+) => { try!(writeln!(destination, $($arg),+)) }
88-
}
89-
90-
w!("pub type {} = ::string_cache::Atom<{}StaticSet>;", type_name, type_name);
91-
w!("pub struct {}StaticSet;", type_name);
92-
w!("impl ::string_cache::StaticAtomSet for {}StaticSet {{", type_name);
93-
w!(" fn get() -> &'static ::string_cache::PhfStrSet {{");
94-
w!(" static SET: ::string_cache::PhfStrSet = ::string_cache::PhfStrSet {{");
95-
w!(" key: {},", hash_state.key);
96-
w!(" disps: &{:?},", hash_state.disps);
97-
w!(" atoms: &{:#?},", atoms);
98-
w!(" }};");
99-
w!(" &SET");
100-
w!(" }}");
101-
w!(" fn empty_string_index() -> u32 {{");
102-
w!(" {}", empty_string_index);
103-
w!(" }}");
104-
w!("}}");
105-
w!("#[macro_export]");
106-
w!("macro_rules! {} {{", self.macro_name);
107-
for (i, atom) in atoms.iter().enumerate() {
108-
w!("({:?}) => {{ $crate::{} {{ unsafe_data: 0x{:x}, phantom: ::std::marker::PhantomData }} }};",
109-
atom,
110-
self.path,
111-
shared::pack_static(i as u32)
112-
);
106+
quote! {
107+
pub type #type_name = ::string_cache::Atom<#static_set_name>;
108+
pub struct #static_set_name;
109+
impl ::string_cache::StaticAtomSet for #static_set_name {
110+
fn get() -> &'static ::string_cache::PhfStrSet {
111+
static SET: ::string_cache::PhfStrSet = ::string_cache::PhfStrSet {
112+
key: #key,
113+
disps: &#disps,
114+
atoms: &#atoms,
115+
};
116+
&SET
117+
}
118+
fn empty_string_index() -> u32 {
119+
#empty_string_index
120+
}
121+
}
122+
#[macro_export]
123+
macro_rules! #macro_name {
124+
#(
125+
(#atoms) => {
126+
$crate::#path {
127+
unsafe_data: #data,
128+
phantom: ::std::marker::PhantomData,
129+
}
130+
};
131+
)*
132+
}
113133
}
114-
w!("}}");
115-
Ok(())
116134
}
117135

118136
/// Create a new file at `path` and write generated code there.

0 commit comments

Comments
 (0)