pub fn is_prose_like(data: &[u8]) -> Option<bool> {
const MIN_SAMPLE_BYTES: usize = 256;
if data.len() < MIN_SAMPLE_BYTES {
return None;
}
let mut alpha = 0usize;
let mut space = 0usize;
let mut digit = 0usize;
let mut structural = 0usize;
for &byte in data {
match byte {
b'a'..=b'z' | b'A'..=b'Z' => alpha += 1,
b' ' | b'\n' | b'\r' | b'\t' => space += 1,
b'0'..=b'9' => digit += 1,
b'{' | b'}' | b'[' | b']' | b'"' | b':' | b',' | b'=' | b'<' | b'>' | b'(' | b')'
| b';' | b'_' | b'/' | b'\\' => structural += 1,
_ => {}
}
}
let len = data.len() as f64;
Some(
(alpha + space) as f64 / len >= 0.85
&& structural as f64 / len <= 0.04
&& digit as f64 / len <= 0.03,
)
}
#[cfg(test)]
mod tests {
use super::is_prose_like;
#[test]
fn classifies_real_content_shapes() {
let prose = "It is a truth universally acknowledged, that a single man in \
possession of a good fortune, must be in want of a wife. However \
little known the feelings or views of such a man may be on his \
first entering a neighbourhood, this truth is so well fixed in \
the minds of the surrounding families, that he is considered as \
the rightful property of some one or other of their daughters."
.repeat(2);
assert_eq!(is_prose_like(prose.as_bytes()), Some(true));
let json = r#"{"id":"4818103462","type":"PushEvent","actor":{"id":583231,"login":"octocat","display_login":"octocat","gravatar_id":"","url":"https://api.github.com/users/octocat"},"repo":{"id":1296269,"name":"octocat/Hello-World"},"payload":{"push_id":1558437314,"size":1,"distinct_size":1,"ref":"refs/heads/main"}}"#
.repeat(2);
assert_eq!(is_prose_like(json.as_bytes()), Some(false));
let code = "static int vf610_mscm_ir_domain_alloc(struct irq_domain *domain, \
unsigned int virq,\n\tunsigned int nr_irqs, void *arg)\n{\n\tstruct \
irq_fwspec *fwspec = arg;\n\tstruct irq_fwspec parent_fwspec;\n\tint \
i, irq = fwspec->param[0];\n\n\tif (WARN_ON(nr_irqs != 1))\n\t\treturn \
-EINVAL;\n"
.repeat(3);
assert_eq!(is_prose_like(code.as_bytes()), Some(false));
assert_eq!(is_prose_like(b"too short"), None);
}
}