///|
pub(all) struct Param {
  name : String
  value : String
} derive(Eq, @debug.Debug)

///|
pub(all) enum ParseError {
  EmptyItem(Int)
  MissingSlash(Int, String)
  InvalidToken(Int, String, String)
  InvalidParameter(Int, String)
  InvalidQ(Int, String)
  InvalidWildcard(Int, String)
  InvalidOffer(Int, String)
  InvalidLanguageTag(Int, String)
} derive(Eq, @debug.Debug)

///|
pub(all) struct MediaRange {
  top : String
  sub : String
  params : Array[Param]
  extensions : Array[Param]
  q : Int
  order : Int
  raw : String
} derive(Eq, @debug.Debug)

///|
pub(all) struct MediaOffer {
  value : String
  top : String
  sub : String
  params : Array[Param]
  index : Int
} derive(Eq, @debug.Debug)

///|
pub(all) struct MediaCandidate {
  offer : MediaOffer
  matched_range : MediaRange
  quality : Int
  specificity : Int
  parameter_matches : Int
  reason : String
} derive(Eq, @debug.Debug)

///|
pub(all) struct MediaDecision {
  selected : String?
  quality : Int
  candidate : MediaCandidate?
  matches : Array[MediaCandidate]
  explanation : String
} derive(Eq, @debug.Debug)

///|
pub(all) struct LanguageRange {
  primary : String
  subtags : Array[String]
  q : Int
  order : Int
  raw : String
} derive(Eq, @debug.Debug)

///|
pub(all) struct LanguageOffer {
  tag : String
  primary : String
  subtags : Array[String]
  index : Int
} derive(Eq, @debug.Debug)

///|
pub(all) struct LanguageCandidate {
  offer : LanguageOffer
  matched_range : LanguageRange
  quality : Int
  specificity : Int
  reason : String
} derive(Eq, @debug.Debug)

///|
pub(all) struct LanguageDecision {
  selected : String?
  quality : Int
  candidate : LanguageCandidate?
  matches : Array[LanguageCandidate]
  explanation : String
} derive(Eq, @debug.Debug)

///|
pub(all) struct EncodingRange {
  coding : String
  q : Int
  order : Int
  raw : String
} derive(Eq, @debug.Debug)

///|
pub(all) struct EncodingOffer {
  coding : String
  index : Int
} derive(Eq, @debug.Debug)

///|
pub(all) struct EncodingCandidate {
  offer : EncodingOffer
  matched_range : EncodingRange
  quality : Int
  specificity : Int
  reason : String
} derive(Eq, @debug.Debug)

///|
pub(all) struct EncodingDecision {
  selected : String?
  quality : Int
  candidate : EncodingCandidate?
  matches : Array[EncodingCandidate]
  explanation : String
} derive(Eq, @debug.Debug)

///|
pub(all) struct CharsetRange {
  charset : String
  q : Int
  order : Int
  raw : String
} derive(Eq, @debug.Debug)

///|
pub(all) struct CharsetOffer {
  charset : String
  canonical : String
  index : Int
} derive(Eq, @debug.Debug)

///|
pub(all) struct CharsetCandidate {
  offer : CharsetOffer
  matched_range : CharsetRange
  quality : Int
  specificity : Int
  reason : String
} derive(Eq, @debug.Debug)

///|
pub(all) struct CharsetDecision {
  selected : String?
  quality : Int
  candidate : CharsetCandidate?
  matches : Array[CharsetCandidate]
  explanation : String
} derive(Eq, @debug.Debug)

///|
pub(all) struct RequestPreferences {
  accept : String
  accept_language : String
  accept_encoding : String
  accept_charset : String
} derive(Eq, @debug.Debug)

///|
pub(all) struct ServerVariant {
  id : String
  media : String
  language : String?
  encoding : String?
  charset : String?
  server_weight : Int
  index : Int
} derive(Eq, @debug.Debug)

///|
pub(all) struct VariantCandidate {
  variant : ServerVariant
  media : MediaCandidate?
  language : LanguageCandidate?
  encoding : EncodingCandidate?
  charset : CharsetCandidate?
  quality : Int
  reason : String
} derive(Eq, @debug.Debug)

///|
pub(all) struct VariantDecision {
  selected : ServerVariant?
  quality : Int
  matches : Array[VariantCandidate]
  vary : Array[String]
  explanation : String
} derive(Eq, @debug.Debug)

///|
pub(all) struct ResponseSummary {
  status : Int
  content_type : String?
  content_language : String?
  content_encoding : String?
  charset : String?
  vary : Array[String]
  explanation : String
} derive(Eq, @debug.Debug)

///|
pub(all) struct ResponseNegotiation {
  decision : VariantDecision
  summary : ResponseSummary
  headers : Array[Param]
  header_block : String
} derive(Eq, @debug.Debug)

///|
pub(all) struct CacheDirective {
  name : String
  value : String?
  order : Int
  raw : String
} derive(Eq, @debug.Debug)

///|
pub(all) struct CachePolicySummary {
  no_store : Bool
  no_cache : Bool
  is_public : Bool
  is_private : Bool
  must_revalidate : Bool
  immutable : Bool
  max_age : Int?
  s_maxage : Int?
  stale_while_revalidate : Int?
  stale_if_error : Int?
  unknown : Array[CacheDirective]
} derive(Eq, @debug.Debug)

///|
pub(all) struct EntityTag {
  weak : Bool
  tag : String
  raw : String
} derive(Eq, @debug.Debug)

///|
pub(all) struct ConditionalDecision {
  matched : Bool
  status : Int
  reason : String
} derive(Eq, @debug.Debug)

///|
pub(all) struct HeaderAudit {
  ok : Bool
  warnings : Array[String]
  errors : Array[String]
} derive(Eq, @debug.Debug)