///|
/// Measure before UTF-8 allocation or conversion to an Int32 byte count.
fn byte_length(text : String) -> Int32 raise PartitionError {
let mut total = 0L
let mut i = 0
while i < text.length() {
let c = text[i].to_int()
if c >= 0xd800 && c <= 0xdbff {
if i == text.length() - 1 || text[i + 1] < 0xdc00 || text[i + 1] > 0xdfff {
raise InvalidTextEncoding
}
total += 4L
i += 2
} else {
if c >= 0xdc00 && c <= 0xdfff {
raise InvalidTextEncoding
}
total += if c < 0x80 { 1L } else if c < 0x800 { 2L } else { 3L }
i += 1
}
if total > 2147483647L {
raise Overflow("UTF-8 bytes")
}
}
total.to_int()
}
///|
fn checked_count(text : String, count : (String) -> Int32 raise) -> Int32 raise {
let actual = count(text)
if actual < 0 {
raise InvalidCount(actual)
}
actual
}
///|
fn add_tokens(total : Int64, tokens : Int32) -> Int64 raise PartitionError {
if total > 9223372036854775807L - tokens.to_int64() {
raise Overflow("total tokens")
}
total + tokens.to_int64()
}
///|
fn volume_id(number : Int32) -> String {
let digits = number.to_string()
"part-" + "0".repeat(Int32::max(0, 4 - digits.length())) + digits
}