///|
// A conservative RFC 2822 addr-spec boundary. Quoted local parts, comments
// and domain literals can contain punctuation including '@'. Do not claim to
// recognize every obsolete/CFWS form; only diagnose unmistakable failures.
fn atom_email_syntax(raw : String) -> Bool {
  let chars = raw.to_array()
  let mut at_seen = false
  let mut segment = false
  let mut quote = false
  let mut bracket = false
  let mut comment_depth = 0
  let mut escape = false
  for c in chars {
    if escape {
      escape = false
      continue
    }
    if (quote || bracket || comment_depth > 0) && c == '\\' {
      escape = true
      continue
    }
    if comment_depth > 0 {
      if c == '(' {
        comment_depth = comment_depth + 1
      } else if c == ')' {
        comment_depth = comment_depth - 1
      }
      continue
    }
    if quote {
      if c == '"' {
        quote = false
      }
      continue
    }
    if bracket {
      if c == ']' {
        bracket = false
      }
      continue
    }
    if c == '(' {
      comment_depth = 1
    } else if c == '"' {
      if at_seen {
        return false
      }
      quote = true
      segment = true
    } else if c == '[' {
      if !at_seen {
        return false
      }
      bracket = true
      segment = true
    } else if c == '@' {
      if at_seen || !segment {
        return false
      }
      at_seen = true
      segment = false
    } else if c == '.' {
      if !segment {
        return false
      }
      segment = false
    } else if atom_email_atext(c) {
      segment = true
    } else if c == ' ' || c == '\t' || c == '\r' || c == '\n' {
      () // CFWS around a component is permitted; other forms remain opaque.
    } else {
      return false
    }
  }
  at_seen && segment && !quote && !bracket && comment_depth == 0 && !escape
}

///|
fn atom_email_atext(c : Char) -> Bool {
  let code = c.to_int()
  (c >= 'a' && c <= 'z') ||
  (c >= 'A' && c <= 'Z') ||
  (c >= '0' && c <= '9') ||
  (
    code >= 33 &&
    code <= 126 &&
    c != '(' &&
    c != ')' &&
    c != '<' &&
    c != '>' &&
    c != '[' &&
    c != ']' &&
    c != ':' &&
    c != ';' &&
    c != '@' &&
    c != '\\' &&
    c != ',' &&
    c != '.' &&
    c != '"'
  )
}