#[cfg(not(feature = "generate-models"))]
fn main() {}
#[cfg(feature = "generate-models")]
fn main() -> Result<(), Box<dyn std::error::Error>> {
let req = reqwest::blocking::get("https://reveng.sourceforge.io/crc-catalogue/all.htm")?;
let req = req.text()?;
println!("Req is {:?}", &req);
generate_models(&req, true, std::fs::File::create("src/generated_models.rs")?, "pub const", |n| format!("Some({:?})", n))?;
generate_models(&req, false, std::fs::File::create("src/generated_models_c_api.rs")?, "#[no_mangle]\npub static", |n| format!("\"{}\\0\".as_ptr()", n))?;
Ok(())
}
#[cfg(feature = "generate-models")]
fn generate_models(req: &str, gen_128: bool, mut out: impl std::io::Write, decl: &str, get_name: impl Fn(&str) -> String) -> Result<(), Box<dyn std::error::Error>> {
let re = regex::Regex::new(
r#"width=(\S+)\s+poly=(\S+)\s+init=(\S+)\s+refin=(\S+)\s+refout=(\S+)\s+xorout=(\S+)\s+check=(\S+)\s+residue=(\S+)\s+name="([^"]+)""#)?;
writeln!(out, "// generated by build/generate_models.rs")?;
writeln!(out, "use super::Model;")?;
writeln!(out, "/// CRC-8 Model\npub type Model_u8 = Model<u8>;")?;
writeln!(out, "/// CRC-16 Model\npub type Model_u16 = Model<u16>;")?;
writeln!(out, "/// CRC-32 Model\npub type Model_u32 = Model<u32>;")?;
writeln!(out, "/// CRC-64 Model\npub type Model_u64 = Model<u64>;")?;
writeln!(out, "/// CRC-128 Model\npub type Model_u128 = Model<u128>;")?;
let mut all8: Vec<String> = vec![];
let mut all16: Vec<String> = vec![];
let mut all32: Vec<String> = vec![];
let mut all64: Vec<String> = vec![];
let mut all128: Vec<String> = vec![];
for cap in re.captures_iter(req) {
println!("Writing constant for {:?}", &cap[9]);
let safe_name = cap[9].replace(|c| match c { 'a'..='z'|'A'..='Z'|'0'..='9' => false, _ => true }, "_");
let width: u32 = cap[1].parse()?;
let typ = match width {
1..=8 => {
all8.push(safe_name.clone());
"Model_u8"
},
9..=16 => {
all16.push(safe_name.clone());
"Model_u16"
},
17..=32 => {
all32.push(safe_name.clone());
"Model_u32"
},
33..=64 => {
all64.push(safe_name.clone());
"Model_u64"
},
65..=128 if gen_128 => {
all128.push(safe_name.clone());
"Model_u128"
},
_ => {
eprintln!("skipping {:?} because {} is too wide", &cap[9], width);
continue;
},
};
let name = get_name(&cap[9]);
write!(out, "/// Describes {:?} \n{} {}: {} = {} {{ width: {}, poly: {}, init: {}, refin: {}, refout: {}, xorout: {}, check: {}, residue: {}, name: {}}};\n",
&cap[9], decl,
safe_name, typ, typ,
&cap[1], &cap[2], &cap[3], &cap[4], &cap[5], &cap[6], &cap[7], &cap[8], name
)?;
}
write!(out, "\n/// A list of models that operate on the `u8` primitive.\n{} ALL_CRC_8: [Model_u8;{}] = [\n", decl, all8.len())?;
for n in &all8 {
write!(out, "\t{},\n", n)?;
}
write!(out, "];")?;
write!(out, "\n/// A list of models that operate on the `u16` primitive.\n{} ALL_CRC_16: [Model_u16;{}] = [\n", decl, all16.len())?;
for n in &all16 {
write!(out, "\t{},\n", n)?;
}
write!(out, "];")?;
write!(out, "\n/// A list of models that operate on the `u32` primitive.\n{} ALL_CRC_32: [Model_u32;{}] = [\n", decl, all32.len())?;
for n in &all32 {
write!(out, "\t{},\n", n)?;
}
write!(out, "];")?;
write!(out, "\n/// A list of models that operate on the `u64` primitive.\n{} ALL_CRC_64: [Model_u64;{}] = [\n", decl, all64.len())?;
for n in &all64 {
write!(out, "\t{},\n", n)?;
}
write!(out, "];")?;
if gen_128 {
write!(out, "\n/// A list of models that operate on the `u128` primitive.\n{} ALL_CRC_128: [Model_u128;{}] = [\n", decl, all128.len())?;
for n in &all128 {
write!(out, "\t{},\n", n)?;
}
write!(out, "];")?;
}
Ok(())
}