|
1 |
| -extern crate string_cache_shared; |
| 1 | +extern crate phf_shared; |
| 2 | +extern crate phf_generator; |
2 | 3 |
|
3 |
| -use string_cache_shared::{STATIC_ATOM_SET, ALL_NS, pack_static}; |
| 4 | +#[path = "src/shared.rs"] #[allow(dead_code)] mod shared; |
| 5 | +#[path = "src/static_atom_list.rs"] mod static_atom_list; |
4 | 6 |
|
5 | 7 | use std::env;
|
6 |
| -use std::ascii::AsciiExt; |
7 | 8 | use std::fs::File;
|
8 | 9 | use std::io::{BufWriter, Write};
|
| 10 | +use std::mem; |
9 | 11 | use std::path::Path;
|
| 12 | +use std::slice; |
10 | 13 |
|
11 | 14 | fn main() {
|
12 |
| - let path = Path::new(&env::var("OUT_DIR").unwrap()).join("ns_atom_macros_without_plugin.rs"); |
13 |
| - let mut file = BufWriter::new(File::create(&path).unwrap()); |
14 |
| - writeln!(file, r"#[macro_export]").unwrap(); |
15 |
| - writeln!(file, r"macro_rules! ns {{").unwrap(); |
16 |
| - writeln!(file, "(\"\") => {{ $crate::Namespace({}) }};", atom("")).unwrap(); |
17 |
| - for &(prefix, url) in ALL_NS { |
18 |
| - if !prefix.is_empty() { |
19 |
| - generate_combination("".to_owned(), prefix, url, &mut file); |
20 |
| - } |
21 |
| - } |
22 |
| - writeln!(file, r"}}").unwrap(); |
| 15 | + let hash_state = generate(); |
| 16 | + write_static_atom_set(&hash_state); |
| 17 | + write_atom_macro(&hash_state); |
| 18 | +} |
23 | 19 |
|
24 |
| - writeln!(file, r"#[macro_export]").unwrap(); |
25 |
| - writeln!(file, r"macro_rules! atom {{").unwrap(); |
26 |
| - for &s in STATIC_ATOM_SET.iter() { |
27 |
| - if is_ident(s) { |
28 |
| - writeln!(file, r"( {} ) => {{ {} }};", s, atom(s)).unwrap(); |
| 20 | +fn generate() -> phf_generator::HashState { |
| 21 | + let mut set = std::collections::HashSet::new(); |
| 22 | + for atom in static_atom_list::ATOMS { |
| 23 | + if !set.insert(atom) { |
| 24 | + panic!("duplicate static atom `{:?}`", atom); |
29 | 25 | }
|
30 |
| - writeln!(file, r"({:?}) => {{ {} }};", s, atom(s)).unwrap(); |
31 | 26 | }
|
32 |
| - writeln!(file, r"}}").unwrap(); |
| 27 | + phf_generator::generate_hash(static_atom_list::ATOMS) |
33 | 28 | }
|
34 | 29 |
|
35 |
| -fn generate_combination(prefix1: String, suffix: &str, url: &str, file: &mut BufWriter<File>) { |
36 |
| - if suffix.is_empty() { |
37 |
| - writeln!(file, r"({:?}) => {{ $crate::Namespace({}) }};", prefix1, atom(url)).unwrap(); |
38 |
| - writeln!(file, r"( {} ) => {{ $crate::Namespace({}) }};", prefix1, atom(url)).unwrap(); |
39 |
| - } else { |
40 |
| - let prefix2 = prefix1.clone(); |
41 |
| - generate_combination(prefix1 + &*suffix[..1].to_ascii_lowercase(), &suffix[1..], url, file); |
42 |
| - generate_combination(prefix2 + &*suffix[..1].to_ascii_uppercase(), &suffix[1..], url, file); |
| 30 | +fn write_static_atom_set(hash_state: &phf_generator::HashState) { |
| 31 | + let path = Path::new(&std::env::var("OUT_DIR").unwrap()).join("static_atom_set.rs"); |
| 32 | + let mut file = BufWriter::new(File::create(&path).unwrap()); |
| 33 | + macro_rules! w { |
| 34 | + ($($arg: expr),+) => { (writeln!(&mut file, $($arg),+).unwrap()) } |
| 35 | + } |
| 36 | + w!("pub static STATIC_ATOM_SET: StaticAtomSet = StaticAtomSet {{"); |
| 37 | + w!(" key: {},", hash_state.key); |
| 38 | + w!(" disps: &["); |
| 39 | + for &(d1, d2) in &hash_state.disps { |
| 40 | + w!(" ({}, {}),", d1, d2); |
| 41 | + } |
| 42 | + w!(" ],"); |
| 43 | + w!(" atoms: &["); |
| 44 | + for &idx in &hash_state.map { |
| 45 | + w!(" {:?},", static_atom_list::ATOMS[idx]); |
43 | 46 | }
|
| 47 | + w!(" ],"); |
| 48 | + w!("}};"); |
44 | 49 | }
|
45 | 50 |
|
46 |
| -fn atom(s: &str) -> String { |
47 |
| - let data = pack_static(STATIC_ATOM_SET.get_index_or_hash(s).unwrap() as u32); |
48 |
| - format!("$crate::Atom {{ data: 0x{:x} }}", data) |
| 51 | +fn write_atom_macro(hash_state: &phf_generator::HashState) { |
| 52 | + let set = shared::StaticAtomSet { |
| 53 | + key: hash_state.key, |
| 54 | + disps: leak(hash_state.disps.clone()), |
| 55 | + atoms: leak(hash_state.map.iter().map(|&idx| static_atom_list::ATOMS[idx]).collect()), |
| 56 | + }; |
| 57 | + |
| 58 | + let path = Path::new(&env::var("OUT_DIR").unwrap()).join("atom_macro.rs"); |
| 59 | + let mut file = BufWriter::new(File::create(&path).unwrap()); |
| 60 | + writeln!(file, r"#[macro_export]").unwrap(); |
| 61 | + writeln!(file, r"macro_rules! atom {{").unwrap(); |
| 62 | + for &s in set.iter() { |
| 63 | + let data = shared::pack_static(set.get_index_or_hash(s).unwrap() as u32); |
| 64 | + writeln!(file, r"({:?}) => {{ $crate::Atom {{ data: 0x{:x} }} }};", s, data).unwrap(); |
| 65 | + } |
| 66 | + writeln!(file, r"}}").unwrap(); |
49 | 67 | }
|
50 | 68 |
|
51 |
| -fn is_ident(s: &str) -> bool { |
52 |
| - let mut chars = s.chars(); |
53 |
| - !s.is_empty() && match chars.next().unwrap() { |
54 |
| - 'a'...'z' | 'A'...'Z' | '_' => true, |
55 |
| - _ => false |
56 |
| - } && chars.all(|c| match c { |
57 |
| - 'a'...'z' | 'A'...'Z' | '_' | '0'...'9' => true, |
58 |
| - _ => false |
59 |
| - }) |
| 69 | +fn leak<T>(v: Vec<T>) -> &'static [T] { |
| 70 | + let slice = unsafe { slice::from_raw_parts(v.as_ptr(), v.len()) }; |
| 71 | + mem::forget(v); |
| 72 | + slice |
60 | 73 | }
|
0 commit comments