///|
pub fn normalize_agent(agent : String) -> String {
lower_ascii(trim_ascii(agent))
}
///|
pub fn agent_tokens(agent : String) -> Array[String] {
let tokens : Array[String] = []
let mut current = ""
for _, ch in normalize_agent(agent) {
if ch.is_ascii_digit() ||
ch.is_ascii_lowercase() ||
ch.is_ascii_uppercase() ||
ch == '-' ||
ch == '_' {
current = current + [ch]
} else if current != "" {
tokens.push(current)
current = ""
}
}
if current != "" {
tokens.push(current)
}
tokens
}
///|
pub fn agent_family(agent : String) -> String {
let tokens = agent_tokens(agent)
if tokens.is_empty() {
""
} else {
tokens[0]
}
}
///|
pub fn agent_matches_token(agent : String, token : String) -> Bool {
let needle = normalize_agent(token)
if needle == "*" {
return true
}
contains_string(agent_tokens(agent), needle) ||
normalize_agent(agent).find(needle) is Some(_)
}
///|
pub fn best_agent_token(agent : String, tokens : Array[String]) -> String {
let mut best = ""
for token in tokens {
if agent_matches_token(agent, token) && token.length() > best.length() {
best = token
}
}
best
}
///|
pub fn agent_score_against(agent : String, token : String) -> Int {
if token == "*" {
0
} else if agent_matches_token(agent, token) {
normalize_agent(token).length()
} else {
-1
}
}
///|
pub fn rank_agents(agent : String, tokens : Array[String]) -> Array[String] {
let result : Array[String] = []
for token in tokens {
result.push(token)
}
for i = 0; i < result.length(); i = i + 1 {
for j = i + 1; j < result.length(); j = j + 1 {
if agent_score_against(agent, result[j]) >
agent_score_against(agent, result[i]) {
let tmp = result[i]
result[i] = result[j]
result[j] = tmp
}
}
}
result
}
///|
pub fn agent_report(agent : String, tokens : Array[String]) -> String {
"agent=" +
normalize_agent(agent) +
"\nfamily=" +
agent_family(agent) +
"\nbest=" +
best_agent_token(agent, tokens)
}