///|
pub struct Coverage {
total : Int
allowed : Int
blocked : Int
unmatched : Int
} derive(Debug, Eq)
///|
pub fn coverage(
text : String,
agent : String,
paths : Array[String],
) -> Coverage {
let robots = parse(text)
let mut allowed = 0
let mut blocked = 0
let mut unmatched = 0
for path in paths {
let decision = decide(robots, agent, path)
if decision.matched_kind == "none" {
unmatched += 1
}
if decision.allowed {
allowed += 1
} else {
blocked += 1
}
}
{ total: paths.length(), allowed, blocked, unmatched }
}
///|
pub fn coverage_line(c : Coverage) -> String {
"total=" +
c.total.to_string() +
" allowed=" +
c.allowed.to_string() +
" blocked=" +
c.blocked.to_string() +
" unmatched=" +
c.unmatched.to_string()
}
///|
pub fn coverage_report(
text : String,
agent : String,
paths : Array[String],
) -> String {
coverage_line(coverage(text, agent, paths))
}
///|
pub fn sample_paths_from_rules(robots : Robots) -> Array[String] {
let paths : Array[String] = ["/"]
for group in robots.groups {
for rule in group.rules {
if rule.pattern != "" && !contains_string(paths, rule.pattern) {
paths.push(rule.pattern)
}
let child = sample_child_path(rule.pattern)
if child != "" && !contains_string(paths, child) {
paths.push(child)
}
}
}
sort_paths_by_depth(paths)
}
///|
pub fn sample_child_path(pattern : String) -> String {
if pattern == "" {
""
} else if pattern.has_suffix("/") {
pattern + "sample"
} else if pattern.find("*") is Some(_) {
text_replace(pattern, "*", "sample")
} else {
pattern + "/sample"
}
}
///|
pub fn auto_coverage_report(text : String, agent : String) -> String {
let paths = sample_paths_from_rules(parse(text))
coverage_report(text, agent, paths)
}