Skip to content

Commit ddde353

Browse files
committed
refactor: generate_tests
Rewrite `generate_tests` to be more idiomatic.
1 parent cf7fa87 commit ddde353

File tree

1 file changed

+45
-52
lines changed
  • src/tools/unicode-table-generator/src

1 file changed

+45
-52
lines changed

src/tools/unicode-table-generator/src/main.rs

Lines changed: 45 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@
7272
//! or not.
7373
7474
use std::collections::{BTreeMap, HashMap};
75+
use std::fmt;
76+
use std::fmt::Write;
7577
use std::ops::Range;
7678

7779
use ucd_parse::Codepoints;
@@ -222,7 +224,7 @@ fn main() {
222224
let ranges_by_property = &unicode_data.ranges;
223225

224226
if let Some(path) = test_path {
225-
std::fs::write(&path, generate_tests(&write_location, ranges_by_property)).unwrap();
227+
std::fs::write(&path, generate_tests(ranges_by_property).unwrap()).unwrap();
226228
}
227229

228230
let mut table_file = String::new();
@@ -326,66 +328,57 @@ fn fmt_list<V: std::fmt::Debug>(values: impl IntoIterator<Item = V>) -> String {
326328
out
327329
}
328330

329-
fn generate_tests(data_path: &str, ranges: &[(&str, Vec<Range<u32>>)]) -> String {
331+
fn generate_tests(ranges: &[(&str, Vec<Range<u32>>)]) -> Result<String, fmt::Error> {
330332
let mut s = String::new();
331-
s.push_str("#![allow(incomplete_features, unused)]\n");
332-
s.push_str("#![feature(const_generics)]\n\n");
333-
s.push_str("\n#[allow(unused)]\nuse std::hint;\n");
334-
s.push_str(&format!("#[path = \"{data_path}\"]\n"));
335-
s.push_str("mod unicode_data;\n\n");
336-
337-
s.push_str("\nfn main() {\n");
338-
333+
writeln!(s, "#![feature(core_intrinsics)]")?;
334+
writeln!(s, "#![allow(internal_features, dead_code)]")?;
335+
writeln!(s, "// ignore-tidy-filelength")?;
336+
writeln!(s, "use std::intrinsics;")?;
337+
writeln!(s, "mod unicode_data;")?;
338+
writeln!(s, "fn main() {{")?;
339339
for (property, ranges) in ranges {
340-
s.push_str(&format!(r#" println!("Testing {property}");"#));
341-
s.push('\n');
342-
s.push_str(&format!(" {}_true();\n", property.to_lowercase()));
343-
s.push_str(&format!(" {}_false();\n", property.to_lowercase()));
344-
let mut is_true = Vec::new();
345-
let mut is_false = Vec::new();
346-
for ch_num in 0..(std::char::MAX as u32) {
347-
if std::char::from_u32(ch_num).is_none() {
348-
continue;
349-
}
350-
if ranges.iter().any(|r| r.contains(&ch_num)) {
351-
is_true.push(ch_num);
352-
} else {
353-
is_false.push(ch_num);
354-
}
355-
}
356-
357-
s.push_str(&format!(" fn {}_true() {{\n", property.to_lowercase()));
358-
generate_asserts(&mut s, property, &is_true, true);
359-
s.push_str(" }\n\n");
360-
s.push_str(&format!(" fn {}_false() {{\n", property.to_lowercase()));
361-
generate_asserts(&mut s, property, &is_false, false);
362-
s.push_str(" }\n\n");
340+
let prop = property.to_lowercase();
341+
writeln!(s, r#" println!("Testing {prop}");"#)?;
342+
writeln!(s, " {prop}_true();")?;
343+
writeln!(s, " {prop}_false();")?;
344+
let (is_true, is_false): (Vec<_>, Vec<_>) = (char::MIN..=char::MAX)
345+
.filter(|c| !c.is_ascii())
346+
.map(u32::from)
347+
.partition(|c| ranges.iter().any(|r| r.contains(c)));
348+
349+
writeln!(s, " fn {prop}_true() {{")?;
350+
generate_asserts(&mut s, &prop, &is_true, true)?;
351+
writeln!(s, " }}")?;
352+
353+
writeln!(s, " fn {prop}_false() {{")?;
354+
generate_asserts(&mut s, &prop, &is_false, false)?;
355+
writeln!(s, " }}")?;
363356
}
364357

365-
s.push('}');
366-
s
358+
writeln!(s, "}}")?;
359+
Ok(s)
367360
}
368361

369-
fn generate_asserts(s: &mut String, property: &str, points: &[u32], truthy: bool) {
362+
fn generate_asserts(
363+
s: &mut String,
364+
prop: &str,
365+
points: &[u32],
366+
truthy: bool,
367+
) -> Result<(), fmt::Error> {
368+
let truthy = if truthy { "" } else { "!" };
370369
for range in ranges_from_set(points) {
371-
if range.end == range.start + 1 {
372-
s.push_str(&format!(
373-
" assert!({}unicode_data::{}::lookup({:?}), \"{}\");\n",
374-
if truthy { "" } else { "!" },
375-
property.to_lowercase(),
376-
std::char::from_u32(range.start).unwrap(),
377-
range.start,
378-
));
379-
} else {
380-
s.push_str(&format!(" for chn in {range:?}u32 {{\n"));
381-
s.push_str(&format!(
382-
" assert!({}unicode_data::{}::lookup(std::char::from_u32(chn).unwrap()), \"{{:?}}\", chn);\n",
383-
if truthy { "" } else { "!" },
384-
property.to_lowercase(),
385-
));
386-
s.push_str(" }\n");
370+
let start = char::from_u32(range.start).unwrap();
371+
let end = char::from_u32(range.end - 1).unwrap();
372+
match range.len() {
373+
1 => writeln!(s, " assert!({truthy}unicode_data::{prop}::lookup({start:?}));")?,
374+
_ => {
375+
writeln!(s, " for c in {start:?}..={end:?} {{")?;
376+
writeln!(s, " assert!({truthy}unicode_data::{prop}::lookup(c));")?;
377+
writeln!(s, " }}")?;
378+
}
387379
}
388380
}
381+
Ok(())
389382
}
390383

391384
/// Group the elements of `set` into contigous ranges

0 commit comments

Comments
 (0)