///|
/// Pure utility helpers for tool handlers.
///|
pub fn required_string(obj : Json, key : String) -> String? {
match obj {
Object(map) =>
match map.get(key) {
Some(String(s)) => Some(s)
_ => None
}
_ => None
}
}
///|
pub fn optional_string(obj : Json, key : String) -> String? {
required_string(obj, key)
}
///|
pub fn optional_int(obj : Json, key : String) -> Int? {
match obj {
Object(map) =>
match map.get(key) {
Some(Number(n, ..)) => Some(n.to_int())
_ => None
}
_ => None
}
}
///|
pub fn count_occurrences(text : String, needle : String) -> Int {
if needle.is_empty() {
return 0
}
let mut count = 0
let mut offset = 0
while offset <= text.length() {
let rest = text.unsafe_substring(start=offset, end=text.length())
match rest.find(needle) {
Some(idx) => {
count = count + 1
offset = offset + idx + needle.length()
}
None => break
}
}
count
}
///|
pub fn clamp(v : Int, min_v : Int, max_v : Int) -> Int {
if v < min_v {
min_v
} else if v > max_v {
max_v
} else {
v
}
}
///|
pub fn normalize_path(path : String) -> String {
let mut out = path.trim().to_owned().replace_all(old="\\", new="/")
while out.contains("//") {
out = out.replace_all(old="//", new="/")
}
if out.has_suffix("/") && out.length() > 1 {
out.unsafe_substring(start=0, end=out.length() - 1)
} else {
out
}
}
///|
pub fn resolve_path(
path : String,
allowed_dir : String?,
) -> Result[String, String] {
let normalized = normalize_path(path)
if normalized.contains("../") || normalized.contains("..\\") {
return Err("Path traversal detected")
}
match allowed_dir {
Some(dir) => {
let base = normalize_path(dir)
if normalized == base || normalized.has_prefix(base + "/") {
Ok(normalized)
} else {
Err("Path " + path + " is outside allowed directory " + dir)
}
}
None => Ok(normalized)
}
}
///|
pub fn guard_command(command : String, restrict_to_workspace : Bool) -> String? {
let lower = command.trim().to_owned().to_lower()
let deny_fragments = [
"rm -rf", "rm -fr", "del /f", "del /q", "rmdir /s", "format", "mkfs", "diskpart",
"dd if=", "> /dev/sd", "shutdown", "reboot", "poweroff", ":(){",
]
for frag in deny_fragments {
if lower.contains(frag) {
return Some(
"Error: Command blocked by safety guard (dangerous pattern detected)",
)
}
}
if restrict_to_workspace {
if lower.contains("../") || lower.contains("..\\") {
return Some(
"Error: Command blocked by safety guard (path traversal detected)",
)
}
}
None
}
///|
pub fn validate_url(url : String) -> Result[Unit, String] {
if !(url.has_prefix("http://") || url.has_prefix("https://")) {
return Err("Only http/https allowed")
}
let rest = if url.has_prefix("https://") {
url.unsafe_substring(start=8, end=url.length())
} else {
url.unsafe_substring(start=7, end=url.length())
}
if rest.is_empty() || rest.has_prefix("/") {
return Err("Missing domain")
}
Ok(())
}
///|
pub fn web_fetch_result_json(
url : String,
final_url : String,
status : Int,
extractor : String,
text : String,
truncated : Bool,
) -> String {
Json::object({
"url": url.to_json(),
"finalUrl": final_url.to_json(),
"status": status.to_json(),
"extractor": extractor.to_json(),
"truncated": truncated.to_json(),
"length": text.length().to_json(),
"text": text.to_json(),
}).stringify()
}