///|
/// Utility functions shared across the framework.
///
/// See `utils.go` equivalent.
///|
/// Join an array of strings with a separator.
pub fn join_strings(strings : Array[String], sep : String) -> String {
let mut result = ""
for s in strings {
if result != "" {
result = result + sep
}
result = result + s
}
result
}
///|
/// Guess MIME type from file extension.
pub fn guess_content_type(path : String) -> String {
let ext = match path.rev_find(".") {
Some(pos) => path[pos:].to_owned()
None => ""
}
match ext {
".html" | ".htm" => "text/html; charset=utf-8"
".css" => "text/css; charset=utf-8"
".js" => "application/javascript; charset=utf-8"
".json" => "application/json; charset=utf-8"
".png" => "image/png"
".jpg" | ".jpeg" => "image/jpeg"
".gif" => "image/gif"
".svg" => "image/svg+xml"
".ico" => "image/x-icon"
".woff" => "font/woff"
".woff2" => "font/woff2"
".ttf" => "font/ttf"
".txt" => "text/plain; charset=utf-8"
".xml" => "application/xml; charset=utf-8"
".pdf" => "application/pdf"
_ => "application/octet-stream"
}
}
///|
/// Simple URL percent-decoding.
pub fn url_decode(s : String) -> String {
let mut result = ""
let mut i = 0
let chars = s.to_array()
while i < chars.length() {
let ch = chars[i]
if ch == '+' {
result = result + " "
i = i + 1
} else if ch == '%' && i + 2 < chars.length() {
let hex = chars[i + 1].to_string() + chars[i + 2].to_string()
match parse_hex(hex) {
Some(byte) => {
result = result + Int::unsafe_to_char(byte).to_string()
i = i + 3
}
None => {
result = result + "%"
i = i + 1
}
}
} else {
result = result + ch.to_string()
i = i + 1
}
}
result
}
///|
/// Parse a 2-character hex string to a byte value.
fn parse_hex(hex : String) -> Int? {
if hex.length() != 2 {
return None
}
let chars = hex.to_array()
let hi = hex_digit(chars[0])
let lo = hex_digit(chars[1])
match (hi, lo) {
(Some(h), Some(l)) => Some(h * 16 + l)
_ => None
}
}
///|
/// Convert a hex char to its numeric value.
fn hex_digit(ch : Char) -> Int? {
match ch {
'0' => Some(0)
'1' => Some(1)
'2' => Some(2)
'3' => Some(3)
'4' => Some(4)
'5' => Some(5)
'6' => Some(6)
'7' => Some(7)
'8' => Some(8)
'9' => Some(9)
'a' | 'A' => Some(10)
'b' | 'B' => Some(11)
'c' | 'C' => Some(12)
'd' | 'D' => Some(13)
'e' | 'E' => Some(14)
'f' | 'F' => Some(15)
_ => None
}
}