use crate::{
CitizenInfo, CitizenRegistry, NonCitizenInfo, registered_citizens, registered_non_citizens,
};
pub fn citizen_census_markdown() -> String {
let citizens = sorted_citizens();
let exemptions = sorted_non_citizens();
let mut out = render_citizen_census(&citizens);
if !exemptions.is_empty() {
out.push('\n');
out.push_str(&render_non_citizen_census(&exemptions));
}
out
}
pub fn citizen_registry_census_markdown(registry: &CitizenRegistry) -> String {
let citizens = sorted_registry_citizens(registry);
render_citizen_census(&citizens)
}
pub fn render_citizen_census(citizens: &[&CitizenInfo]) -> String {
let mut out = String::new();
out.push_str("# Generated Citizen Census\n\n");
out.push_str("Generated by `cargo test --workspace --all-features citizen`.\n");
out.push_str("Do not edit by hand.\n\n");
out.push_str(&format!("Total citizens: {}\n\n", citizens.len()));
out.push_str("| Symbol | Version | Arity | Crate |\n");
out.push_str("| --- | ---: | ---: | --- |\n");
for info in citizens {
out.push_str(&format!(
"| `{}` | {} | {} | `{}` |\n",
info.symbol, info.version, info.arity, info.crate_name
));
}
out
}
pub fn non_citizen_census_markdown() -> String {
let exemptions = sorted_non_citizens();
render_non_citizen_census(&exemptions)
}
pub fn render_non_citizen_census(exemptions: &[&NonCitizenInfo]) -> String {
let mut out = String::new();
out.push_str("# Generated Non-Citizen Exemption Census\n\n");
out.push_str("Generated by `cargo test --workspace --all-features citizen`.\n");
out.push_str("Do not edit by hand.\n\n");
out.push_str(&format!("Total exemptions: {}\n\n", exemptions.len()));
out.push_str("| Type | Kind | Descriptor | Crate | Reason |\n");
out.push_str("| --- | --- | --- | --- | --- |\n");
for info in exemptions {
out.push_str(&format!(
"| `{}` | `{}` | `{}` | `{}` | {} |\n",
info.type_name, info.kind, info.descriptor, info.crate_name, info.reason
));
}
out
}
fn sorted_citizens() -> Vec<&'static CitizenInfo> {
let mut citizens = registered_citizens().collect::<Vec<_>>();
citizens.sort_by(|left, right| {
left.symbol
.cmp(right.symbol)
.then_with(|| left.crate_name.cmp(right.crate_name))
});
citizens
}
fn sorted_registry_citizens(registry: &CitizenRegistry) -> Vec<&CitizenInfo> {
let mut citizens = registry.citizens().collect::<Vec<_>>();
citizens.sort_by(|left, right| {
left.symbol
.cmp(right.symbol)
.then_with(|| left.crate_name.cmp(right.crate_name))
});
citizens
}
fn sorted_non_citizens() -> Vec<&'static NonCitizenInfo> {
let mut exemptions = registered_non_citizens().collect::<Vec<_>>();
exemptions.sort_by(|left, right| {
left.type_name
.cmp(right.type_name)
.then_with(|| left.crate_name.cmp(right.crate_name))
});
exemptions
}