///|
/// RFC 3629 scalar validation/counting without allocating a decoded String.
fn utf8_scalar_count(data : BytesView) -> Int raise MatError {
  let mut offset = 0
  let mut count = 0
  while offset < data.length() {
    let first = data[offset].to_int()
    let width = if first <= 127 {
      1
    } else if first >= 194 && first <= 223 {
      2
    } else if first >= 224 && first <= 239 {
      3
    } else if first >= 240 && first <= 244 {
      4
    } else {
      0
    }
    if width == 0 || width > data.length() - offset {
      fail("invalid-char", offset, "Malformed UTF-8 character payload")
    }
    for i = 1; i < width; i = i + 1 {
      let value = data[offset + i].to_int()
      if value < 128 || value > 191 {
        fail("invalid-char", offset + i, "Malformed UTF-8 continuation")
      }
    }
    if width > 1 {
      let second = data[offset + 1].to_int()
      if (first == 224 && second < 160) ||
        (first == 237 && second > 159) ||
        (first == 240 && second < 144) ||
        (first == 244 && second > 143) {
        fail(
          "invalid-char", offset, "UTF-8 requires canonical Unicode scalar encoding",
        )
      }
    }
    count = count + 1
    offset = offset + width
  }
  count
}