///|
fn escape_text(value : StringView) -> String {
let out = StringBuilder::new(size_hint=value.length())
for ch in value {
match ch {
'&' => out.write_string("&")
'<' => out.write_string("<")
'>' => out.write_string(">")
_ => out.write_char(ch)
}
}
out.to_string()
}
///|
fn escape_attr_value(value : StringView, quote : Char) -> String {
let out = StringBuilder::new(size_hint=value.length())
for ch in value {
match ch {
'&' => out.write_string("&")
'<' => out.write_string("<")
'>' => out.write_string(">")
'"' if quote == '"' => out.write_string(""")
'\'' if quote == '\'' => out.write_string("'")
_ => out.write_char(ch)
}
}
out.to_string()
}
///|
fn escape_js_string(value : StringView, quote : Char) -> String {
let out = StringBuilder::new(size_hint=value.length())
for ch in value {
match ch {
'\\' => out.write_string("\\\\")
'\n' => out.write_string("\\n")
'\r' => out.write_string("\\r")
'\t' => out.write_string("\\t")
'\u{0008}' => out.write_string("\\b")
'\u{000C}' => out.write_string("\\f")
'"' if quote == '"' => out.write_string("\\\"")
'\'' if quote == '\'' => out.write_string("\\'")
'<' => out.write_string("\\u003c")
'>' => out.write_string("\\u003e")
'\u{2028}' => out.write_string("\\u2028")
'\u{2029}' => out.write_string("\\u2029")
_ => out.write_char(ch)
}
}
out.to_string()
}
///|
fn percent_encode_url(value : StringView) -> String {
let bytes = @utf8.encode(value)
let out = StringBuilder::new(size_hint=bytes.length())
for index in 0.. Bool {
let value = byte.to_int()
(value >= 0x41 && value <= 0x5A) ||
(value >= 0x61 && value <= 0x7A) ||
(value >= 0x30 && value <= 0x39) ||
value == 0x2F ||
value == 0x3A ||
value == 0x40 ||
value == 0x3F ||
value == 0x26 ||
value == 0x3D ||
value == 0x23 ||
value == 0x2B ||
value == 0x2D ||
value == 0x2E ||
value == 0x5F ||
value == 0x7E
}
///|
/// Append one byte as an uppercase percent-encoded triplet.
///
/// The output form is `%HH`, using hexadecimal digits `0`-`9` and `A`-`F`.
pub fn write_percent_encoded_byte(out : StringBuilder, byte : Byte) -> Unit {
let value = byte.to_int()
out.write_char('%')
out.write_char(hex_digit_upper(value / 16))
out.write_char(hex_digit_upper(value % 16))
}
///|
fn hex_digit_upper(value : Int) -> Char {
match value {
0 => '0'
1 => '1'
2 => '2'
3 => '3'
4 => '4'
5 => '5'
6 => '6'
7 => '7'
8 => '8'
9 => '9'
10 => 'A'
11 => 'B'
12 => 'C'
13 => 'D'
14 => 'E'
15 => 'F'
_ => '0'
}
}
///|
/// Return whether `value` contains `needle`.
///
/// This scans by `Char`, so non-BMP characters are treated as single
/// characters even though MoonBit string offsets are UTF-16 code units.
pub fn string_contains_char(value : StringView, needle : Char) -> Bool {
for ch in value {
if ch == needle {
return true
}
}
false
}