Skip to content

Commit 06b2116

Browse files
committed
Make the Default impl use a static atom.
1 parent 570fea0 commit 06b2116

File tree

2 files changed

+31
-9
lines changed

2 files changed

+31
-9
lines changed

src/atom.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ impl StringCache {
170170

171171
pub trait StaticAtomSet {
172172
fn get() -> &'static PhfStrSet;
173+
fn empty_string_index() -> u32;
173174
}
174175

175176
pub struct PhfStrSet {
@@ -191,6 +192,10 @@ impl StaticAtomSet for EmptyStaticAtomSet {
191192
};
192193
&SET
193194
}
195+
196+
fn empty_string_index() -> u32 {
197+
0
198+
}
194199
}
195200

196201
/// Use this if you don’t care about static atoms.
@@ -231,8 +236,12 @@ impl<Static: StaticAtomSet> Atom<Static> {
231236
}
232237

233238
impl<Static: StaticAtomSet> Default for Atom<Static> {
239+
#[inline]
234240
fn default() -> Self {
235-
Self::from("")
241+
Atom {
242+
unsafe_data: pack_static(Static::empty_string_index()),
243+
phantom: PhantomData
244+
}
236245
}
237246
}
238247

@@ -663,6 +672,12 @@ mod tests {
663672
assert!(i0 != d0);
664673
}
665674

675+
#[test]
676+
fn default() {
677+
assert_eq!(TestAtom::default(), test_atom!(""));
678+
assert_eq!(&*TestAtom::default(), "");
679+
}
680+
666681
#[test]
667682
fn ord() {
668683
fn check(x: &str, y: &str) {

string-cache-codegen/lib.rs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,11 @@ impl AtomType {
4646
/// // Expands to: $crate::foo::FooAtom { … }
4747
/// }
4848
pub fn new(path: &str, macro_name: &str) -> Self {
49-
let mut set = HashSet::new();
50-
set.insert(String::new()); // rust-phf requires a non-empty set
51-
assert!(macro_name.ends_with('!'));
49+
assert!(macro_name.ends_with("!"));
5250
AtomType {
5351
path: path.to_owned(),
54-
macro_name: macro_name[..macro_name.len() - 1].to_owned(),
55-
atoms: set,
52+
macro_name: macro_name[..macro_name.len() - "!".len()].to_owned(),
53+
atoms: HashSet::new(),
5654
}
5755
}
5856

@@ -70,10 +68,16 @@ impl AtomType {
7068
}
7169

7270
/// Write generated code to `destination`.
73-
pub fn write_to<W>(&self, mut destination: W) -> io::Result<()> where W: Write {
71+
pub fn write_to<W>(&mut self, mut destination: W) -> io::Result<()> where W: Write {
72+
// `impl Default for Atom` requires the empty string to be in the static set.
73+
// This also makes sure the set in non-empty,
74+
// which would cause divisions by zero in rust-phf.
75+
self.atoms.insert(String::new());
76+
7477
let atoms: Vec<&str> = self.atoms.iter().map(|s| &**s).collect();
7578
let hash_state = phf_generator::generate_hash(&atoms);
7679
let atoms: Vec<&str> = hash_state.map.iter().map(|&idx| atoms[idx]).collect();
80+
let empty_string_index = atoms.iter().position(|s| s.is_empty()).unwrap();
7781

7882
let type_name = if let Some(position) = self.path.rfind("::") {
7983
&self.path[position + "::".len() ..]
@@ -90,12 +94,15 @@ impl AtomType {
9094
w!("impl ::string_cache::StaticAtomSet for {}StaticSet {{", type_name);
9195
w!(" fn get() -> &'static ::string_cache::PhfStrSet {{");
9296
w!(" static SET: ::string_cache::PhfStrSet = ::string_cache::PhfStrSet {{");
93-
w!(" key: {:#?},", hash_state.key);
97+
w!(" key: {},", hash_state.key);
9498
w!(" disps: &{:?},", hash_state.disps);
9599
w!(" atoms: &{:#?},", atoms);
96100
w!(" }};");
97101
w!(" &SET");
98102
w!(" }}");
103+
w!(" fn empty_string_index() -> u32 {{");
104+
w!(" {}", empty_string_index);
105+
w!(" }}");
99106
w!("}}");
100107
w!("#[macro_export]");
101108
w!("macro_rules! {} {{", self.macro_name);
@@ -114,7 +121,7 @@ impl AtomType {
114121
///
115122
/// Typical usage:
116123
/// `.write_to_file(&Path::new(&env::var("OUT_DIR").unwrap()).join("foo_atom.rs"))`
117-
pub fn write_to_file(&self, path: &Path) -> io::Result<()> {
124+
pub fn write_to_file(&mut self, path: &Path) -> io::Result<()> {
118125
self.write_to(BufWriter::new(try!(File::create(path))))
119126
}
120127
}

0 commit comments

Comments
 (0)