///|
/// Rewrite a Smithy `@pattern` (ECMA 262) into the syntax of core
/// `@string.Regex`.
///
/// - `\d` and `\w` become their ASCII classes.
/// - A literal dash in a class becomes `\-`. ECMA 262 reads a dash as a
///   literal at the start or end of a class, and after a range or a class
///   escape. Core 0.10.18 rejects these dashes as ambiguous. A literal
///   dash can start a range: `[--/]` is the range from `-` to `/`.
fn core_pattern(pattern : String) -> String {
  let pattern = pattern
    .replace_all(old="\\d", new="[0-9]")
    .replace_all(old="\\w", new="[a-zA-Z0-9_]")
  let out = StringBuilder()
  let length = pattern.length()
  let mut in_class = false
  // True when the last class item is a single character that can start a range.
  let mut range_start = false
  // True after a range dash, until the end character of the range.
  let mut range_end = false
  let mut i = 0
  while i < length {
    let c = pattern.code_unit_at(i)
    if c == '\\' && i + 1 < length {
      let next = pattern.code_unit_at(i + 1)
      // The escape and the code unit after it. That code unit can be the leading
      // surrogate of a pair (`\😀`), which `exact_view` refuses, so this keeps the
      // old raw code-unit view. `i + 1 < length` above checks the bounds.
      out.write_view(pattern.unsafe_view(start=i, end=i + 2))
      if in_class {
        let class_escape = next == 'd' ||
          next == 'D' ||
          next == 'w' ||
          next == 'W' ||
          next == 's' ||
          next == 'S'
        range_start = !range_end && !class_escape
        range_end = false
      }
      i += 2
      continue
    }
    if !in_class {
      out.write_char(c.unsafe_to_char())
      if c == '[' {
        in_class = true
        range_start = false
        range_end = false
        if i + 1 < length && pattern.code_unit_at(i + 1) == '^' {
          out.write_char('^')
          i += 1
        }
      }
    } else if c == ']' {
      out.write_char(']')
      in_class = false
    } else if c == '-' {
      let at_end = i + 1 >= length || pattern.code_unit_at(i + 1) == ']'
      if range_start && !at_end {
        out.write_char('-')
        range_start = false
        range_end = true
      } else {
        out.write_string("\\-")
        // A literal dash is a class atom, so it can start a range (`[--/]`).
        range_start = true
        range_end = false
      }
    } else {
      out.write_char(c.unsafe_to_char())
      range_start = !range_end
      range_end = false
    }
    i += 1
  }
  out.to_string()
}