///|
/// Parse a HTTP `Content-Disposition` header into a structured value.
///
/// The parser accepts common recovery cases and records them in
/// `Disposition.diagnostics`. Use `parse_header_strict` when diagnostics with
/// severity `Error` should fail the parse.
pub fn parse_header(header : String) -> Result[Disposition, ParseError] {
  parse_header_with_options(header, strict=false)
}

///|
/// Parse a header and reject any syntax or decoding error.
pub fn parse_header_strict(header : String) -> Result[Disposition, ParseError] {
  parse_header_with_options(header, strict=true)
}

///|
/// Build a safe `attachment` header for the supplied file name.
pub fn attachment(filename : String) -> Disposition {
  let report = sanitize_filename(filename)
  let params : Array[Parameter] = []
  params.push(Parameter::plain("filename", report.value))
  if needs_extended_filename(filename) {
    params.push(
      Parameter::extended("filename", filename, charset="UTF-8", language=""),
    )
  }
  { kind: Attachment, params, diagnostics: report.diagnostics }
}

///|
/// Build a minimal `inline` disposition.
pub fn inline() -> Disposition {
  { kind: Inline, params: [], diagnostics: [] }
}

///|
/// Build a `form-data` disposition for multipart form fields.
pub fn form_data(name : String, filename? : String) -> Disposition {
  let params : Array[Parameter] = []
  params.push(Parameter::plain("name", name))
  if filename is Some(value) {
    let report = sanitize_filename(value)
    params.push(Parameter::plain("filename", report.value))
    if needs_extended_filename(value) {
      params.push(
        Parameter::extended("filename", value, charset="UTF-8", language=""),
      )
    }
    { kind: FormData, params, diagnostics: report.diagnostics }
  } else {
    { kind: FormData, params, diagnostics: [] }
  }
}