///|
pub struct TokenPath {
  segments : Array[String]
} derive(Debug, Eq)

///|
pub fn TokenPath::new(segments : Array[String]) -> TokenPath {
  { segments, }
}

///|
pub fn TokenPath::from_string(text : String) -> TokenPath {
  let parts : Array[String] = []
  let current = StringBuilder::new()
  let mut builder = current
  for ch in text {
    if ch == '/' || ch == '.' {
      let part = normalize_identifier(builder.to_string())
      if part != "" {
        parts.push(part)
      }
      builder = StringBuilder::new()
    } else {
      builder.write_char(ch)
    }
  }
  let final_part = normalize_identifier(builder.to_string())
  if final_part != "" {
    parts.push(final_part)
  }
  { segments: parts }
}

///|
pub fn TokenPath::canonical(self : TokenPath) -> String {
  self.segments.join(".")
}

///|
pub fn TokenPath::css_name(self : TokenPath, prefix : String) -> String {
  let name = self.segments.join("-")
  if name == "" {
    "--" + normalize_identifier(prefix)
  } else {
    "--" + normalize_identifier(prefix) + "-" + name
  }
}

///|
pub fn TokenPath::is_empty(self : TokenPath) -> Bool {
  self.segments.length() == 0
}