///|
/// Decodes UTF-16 storage into Unicode scalar values, preserving unpaired units.
pub fn text_code_points(text : String) -> Array[Int] {
  let output : Array[Int] = []
  let mut index = 0
  while index < text.length() {
    let first = text[index].to_int()
    if first >= 0xD800 && first <= 0xDBFF && index + 1 < text.length() {
      let second = text[index + 1].to_int()
      if second >= 0xDC00 && second <= 0xDFFF {
        output.push(0x10000 + (first - 0xD800) * 0x400 + second - 0xDC00)
        index = index + 2
        continue
      }
    }
    output.push(first)
    index = index + 1
  }
  output
}

///|
/// Encodes Unicode scalar values as MoonBit strings.
pub fn code_points_text(values : Array[Int]) -> String {
  let mut output = ""
  for value in values {
    if value >= 0 && value <= 0xFFFF {
      output = output + value.to_uint16().unsafe_to_char().to_string()
    } else if value >= 0x10000 && value <= 0x10FFFF {
      let adjusted = value - 0x10000
      let high = 0xD800 + adjusted / 0x400
      let low = 0xDC00 + adjusted % 0x400
      output = output + high.to_uint16().unsafe_to_char().to_string()
      output = output + low.to_uint16().unsafe_to_char().to_string()
    } else {
      output = output + "�"
    }
  }
  output
}