use crate::{
element::Element,
types::{Hash, ValueRef},
};
pub(crate) fn find_hashes(data: &[u8]) -> Vec<Hash> {
crate::element::Parser::new(data)
.filter_map(|e| {
if let Ok(Element::Hash(h)) = e {
Some(h)
} else {
None
}
})
.collect()
}
pub(crate) fn count_regexes(v: &ValueRef) -> usize {
if let ValueRef::Map(map) = v {
if map.len() > 1 {
return 0;
}
match map.iter().next() {
Some((&"Str", val)) => val["matches"].is_str() as usize,
Some((&"Map", val)) => {
if !val.is_map() {
return 0;
}
let key_matches = if val["keys"]["matches"].is_str() {
1
} else {
0
};
let req_matches = val["req"].as_map().map_or(0, |map| {
map.values().fold(0, |acc, val| acc + count_regexes(val))
});
let opt_matches = val["opt"].as_map().map_or(0, |map| {
map.values().fold(0, |acc, val| acc + count_regexes(val))
});
let values_matches = count_regexes(&val["values"]);
key_matches + req_matches + opt_matches + values_matches
}
Some((&"Array", val)) => {
if !val.is_map() {
return 0;
}
let contains_matches = val["contains"].as_array().map_or(0, |array| {
array.iter().fold(0, |acc, val| acc + count_regexes(val))
});
let items_matches = count_regexes(&val["items"]);
let prefix_matches = val["contains"].as_array().map_or(0, |array| {
array.iter().fold(0, |acc, val| acc + count_regexes(val))
});
contains_matches + items_matches + prefix_matches
}
Some((&"Hash", val)) => {
if !val.is_map() {
return 0;
}
count_regexes(&val["link"])
}
Some((&"Enum", val)) => val.as_map().map_or(0, |map| {
map.values().fold(0, |acc, val| acc + count_regexes(val))
}),
Some((&"Multi", val)) => val.as_array().map_or(0, |array| {
array.iter().fold(0, |acc, val| acc + count_regexes(val))
}),
_ => 0,
}
} else {
0
}
}