///|
fn lower(text : String) -> String {
text.to_lower()
}
///|
fn clean(text : String) -> String {
text.trim().replace_all(old="\t", new=" ").to_owned()
}
///|
fn parse_digits(text : String) -> Int? {
let trimmed = text.trim().to_owned()
if trimmed.is_empty() {
return None
}
let mut value = 0
for ch in trimmed {
let code = ch.to_int()
if code < 48 || code > 57 {
return None
}
value = value * 10 + code - 48
}
Some(value)
}
///|
fn csv_count(text : String) -> Int {
if text.trim().is_empty() {
return 0
}
let mut count = 0
for part in text.split(",") {
if !part.trim().is_empty() {
count += 1
}
}
count
}
///|
fn clamp_score(score : Int) -> Int {
if score < 0 {
0
} else if score > 100 {
100
} else {
score
}
}
///|
fn severity_text(severity : Severity) -> String {
if severity == Pass {
"pass"
} else if severity == Warn {
"warn"
} else {
"fail"
}
}
///|
fn json_escape(text : String) -> String {
text
.replace_all(old="\\", new="\\\\")
.replace_all(old="\"", new="\\\"")
.replace_all(old="\n", new="\\n")
}
///|
fn split_tag_value(item : String) -> (String, String) {
let parts = item.split("=").to_array()
if parts.length() < 2 {
("", "")
} else {
(lower(parts[0].trim().to_owned()), parts[1].trim().to_owned())
}
}
///|
fn tag_value(text : String, key : String) -> String {
let wanted = lower(key)
for segment in text.split(";") {
let item = clean(segment.to_owned())
if item.is_empty() {
continue
}
let (tag, value) = split_tag_value(item)
if tag == wanted {
return value
}
}
""
}
///|
fn has_tag(text : String, key : String) -> Bool {
!tag_value(text, key).is_empty()
}
///|
fn colon_value(text : String, key : String) -> String {
let wanted = lower(key)
for line in text.split("\n") {
let item = line.to_owned().trim().to_owned()
if item.is_empty() {
continue
}
let parts = item.split(":").to_array()
if parts.length() < 2 {
continue
}
let tag = lower(parts[0].trim().to_owned())
if tag == wanted {
return parts[1].trim().to_owned()
}
}
""
}
///|
fn colon_values(text : String, key : String) -> Array[String] {
let wanted = lower(key)
let values = Array::new()
for line in text.split("\n") {
let item = line.to_owned().trim().to_owned()
if item.is_empty() {
continue
}
let parts = item.split(":").to_array()
if parts.length() < 2 {
continue
}
let tag = lower(parts[0].trim().to_owned())
if tag == wanted {
values.push(parts[1].trim().to_owned())
}
}
values
}
///|
fn list_contains_token(text : String, token : String) -> Bool {
let wanted = lower(token)
for part in text.split(":") {
if lower(part.to_owned().trim().to_owned()) == wanted {
return true
}
}
for part in text.split(",") {
if lower(part.to_owned().trim().to_owned()) == wanted {
return true
}
}
false
}
///|
fn csv_contains_token(text : String, token : String) -> Bool {
let wanted = lower(token)
for part in text.split(",") {
if lower(part.to_owned().trim().to_owned()) == wanted {
return true
}
}
false
}
///|
fn starts_with_https_url(text : String) -> Bool {
lower(text.trim().to_owned()).has_prefix("https://")
}
///|
fn contains_svg_path(text : String) -> Bool {
let item = lower(text.trim().to_owned())
item.contains(".svg")
}
///|
fn rough_base64_bits(text : String) -> Int {
let mut useful = 0
for ch in text.trim().to_owned() {
let code = ch.to_int()
let digit = code >= 48 && code <= 57
let upper = code >= 65 && code <= 90
let lower_letter = code >= 97 && code <= 122
if digit || upper || lower_letter || ch == '+' || ch == '/' {
useful += 1
}
}
useful * 6
}
///|
fn bool_text(value : Bool) -> String {
if value {
"true"
} else {
"false"
}
}
///|
fn append_json_string(
out : StringBuilder,
key : String,
value : String,
) -> Unit {
out.write_string("\"")
out.write_string(json_escape(key))
out.write_string("\":\"")
out.write_string(json_escape(value))
out.write_string("\"")
}
///|
fn append_json_int(out : StringBuilder, key : String, value : Int) -> Unit {
out.write_string("\"")
out.write_string(json_escape(key))
out.write_string("\":")
out.write_string(value.to_string())
}
///|
fn append_json_bool(out : StringBuilder, key : String, value : Bool) -> Unit {
out.write_string("\"")
out.write_string(json_escape(key))
out.write_string("\":")
out.write_string(bool_text(value))
}
///|
fn normalize_domain(text : String) -> String {
lower(text.trim().to_owned())
}
///|
fn has_wildcard_host(text : String) -> Bool {
text.trim().to_owned().contains("*")
}
///|
fn positive_or_zero(value : Int) -> Int {
if value < 0 {
0
} else {
value
}
}
///|
fn max_int(a : Int, b : Int) -> Int {
if a > b {
a
} else {
b
}
}
///|
fn min_int(a : Int, b : Int) -> Int {
if a < b {
a
} else {
b
}
}