///|
pub(open) trait FromString {
from_string(String) -> Self
}
///|
pub(open) trait Debug: Show {
to_debug_string(Self) -> String = _
}
///|
impl Debug with to_debug_string(self) {
to_debug_string(self)
}
///|
pub impl Debug for String with to_debug_string(self) {
to_debug_string(self)
}
///|
pub fn[T : Show] to_debug_string(val : T) -> String {
let logger = StringBuilder::new()
val.output(logger)
// self.output(logger)
logger.to_string()
}
///|
pub(open) trait ToString {
to_string(Self) -> String
}
///|
pub impl ToString for Char with to_string(self) {
"\{self}"
}
///|
pub impl ToString for StringBuilder with to_string(self) {
self.to_string()
}
///|
pub(open) trait JoinToString {
join_all(Self) -> String
}
///|
pub(open) trait ConcatToString: ToString {
concat_to_string(Self, Self) -> String
}
///|
pub impl ConcatToString for Char with concat_to_string(a, b) {
"\{a}\{b}"
}
///|
pub impl ToString for String with to_string(a) {
a |> String::to_string()
}
///|
pub impl ConcatToString for String with concat_to_string(a, b) {
a + b
}
///|
pub(open) trait ToInt {
to_int(Self) -> Int
}
///|
pub(open) trait FromInt {
from_int(Int) -> Self
}
///|
pub impl ToInt for Int with to_int(self) {
self
}
///|
pub impl FromInt for Int with from_int(self) {
self
}
///|
pub(open) trait GetChar {
op_get(Self, Int) -> Char
}
///|
pub impl GetChar for String with op_get(self, idx) {
self.charcode_at(idx).unsafe_to_char()
}
///|
pub(open) trait GetUtf16CodePoint: GetChar + Length {
get_utf16(Self, Int) -> Utf16CodePoint = _
get_utf16_exn(Self, Int) -> Utf16CodePoint raise GetUtf16CharError = _
}
///|
impl GetUtf16CodePoint with get_utf16(self, idx_word) {
match (try? self.get_utf16_exn(idx_word)) {
Ok(a) => a
Err(e) => {
if DEBUGGER {
match e {
OutOfRange(_) => abort("`idx_word` out of range")
InvalidStringHighSurrogate =>
abort("high surrogate appeared at the ending")
InvalidStringLowSurrogate =>
abort("low surrogate appeared at the beginning")
UnreachableCode(_) => abort("unreachable code reached")
}
}
panic()
}
}
}
///|
pub(all) suberror GetUtf16CharError {
OutOfRange(Int, length~ : Int) // `idx_word` out of range
InvalidStringHighSurrogate // high surrogate appeared at the ending
InvalidStringLowSurrogate // low surrogate appeared at the beginning
UnreachableCode(Int) // unreachable code reached
} derive(Show)
///|
impl GetUtf16CodePoint with get_utf16_exn(str, idx_word) {
guard 0 <= idx_word && idx_word < str.length() else {
raise OutOfRange(idx_word, length=str.length())
}
let c = str.op_get(idx_word)
let w = c.to_int()
if (0 <= w && w < 0xD800) || (0xE000 <= w && w <= 0xFFFF) {
return BMP(c)
} else if 0xD800 <= w && w <= 0xDBFF {
if idx_word + 1 < str.length() {
let wl = str.op_get(idx_word + 1).to_int()
HighSurrogate(combine_surrogate_pair_int(w, wl))
} else {
raise InvalidStringHighSurrogate
}
} else if 0xDC00 <= w && w <= 0xDFFF {
if idx_word - 1 >= 0 {
let wh = str.op_get(idx_word - 1).to_int()
LowSurrogate(combine_surrogate_pair_int(wh, w))
} else {
raise InvalidStringLowSurrogate
}
} else {
raise UnreachableCode(w)
}
}
///|
pub(open) trait ToChar {
to_char(Self) -> Char
}
///|
pub impl ToChar for Char with to_char(self) {
self
}
///|
// pub impl ToChar for String with to_char(self) { self[0] }
///|
pub impl ToChar for Int with to_char(self) {
self.unsafe_to_char()
}
// ///|
// pub(open) trait Default {
// default() -> Self
// }
// ///|
// pub impl[T : Default] Default for Ref[T] with default() {
// Ref::new(T::default())
// }
///|
pub(open) trait ToByte {
to_byte(Self) -> Byte
}
///|
pub impl ToByte for Int with to_byte(self) = "%i32_to_byte"