//!
//! AUTO-GENERATED CODE - DO NOT EDIT!
//!
//! Swagger Petstore
//! Source: crates/oas3-gen/fixtures/petstore.json
//! Version: 1.0.0
//! Generated by `oas3-gen v0.26.0`
//!

use serde::{Deserialize, Serialize};
use validator::Validate;
pub const X_SORT_ORDER: http::HeaderName = http::HeaderName::from_static("x-sort-order");
pub const X_ONLY: http::HeaderName = http::HeaderName::from_static("x-only");
pub const X_API_VERSION: http::HeaderName = http::HeaderName::from_static("x-api-version");
pub const X_API_KEY: http::HeaderName = http::HeaderName::from_static("x-api-key");
#[derive(Debug, Clone, PartialEq, Deserialize, oas3_gen_support::Default, bon::Builder)]
#[serde(default)]
pub struct Allergies {
  #[doc(hidden)]
  #[serde(default, rename = "type", skip_deserializing)]
  #[default(Some("allergies"))]
  #[builder(skip = Some("allergies"))]
  pub r#type: Option<&'static str>,
}
#[derive(Debug, Clone, PartialEq, Deserialize, oas3_gen_support::Default, bon::Builder)]
#[serde(default)]
pub struct Diet {
  #[doc(hidden)]
  #[serde(default, rename = "type", skip_deserializing)]
  #[default(Some("diet"))]
  #[builder(skip = Some("diet"))]
  pub r#type: Option<&'static str>,
}
#[derive(Debug, Clone, PartialEq)]
pub enum Health {
  Allergies(Allergies),
  Diet(Diet),
}
impl Health {
  pub const DISCRIMINATOR_FIELD: &'static str = "type";
}
impl Default for Health {
  fn default() -> Self {
    Self::Allergies(<Allergies>::default())
  }
}
impl<'de> serde::Deserialize<'de> for Health {
  fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
  where
    D: serde::Deserializer<'de>,
  {
    let value = serde_json::Value::deserialize(deserializer)?;
    match value.get(Self::DISCRIMINATOR_FIELD).and_then(|v| v.as_str()) {
      Some("allergies") => serde_json::from_value(value)
        .map(Self::Allergies)
        .map_err(serde::de::Error::custom),
      Some("diet") => serde_json::from_value(value)
        .map(Self::Diet)
        .map_err(serde::de::Error::custom),
      None => Err(serde::de::Error::missing_field(Self::DISCRIMINATOR_FIELD)),
      Some(other) => Err(serde::de::Error::custom(format!(
        "Unknown discriminator value '{}' for field '{}'",
        other, "type"
      ))),
    }
  }
}
impl Health {
  pub fn allergies() -> Self {
    Self::Allergies(Allergies::default())
  }
  pub fn diet() -> Self {
    Self::Diet(Diet::default())
  }
}
#[serde_with::skip_serializing_none]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, oas3_gen_support::Default, bon::Builder)]
pub struct VaccineRecord {
  pub date_administered: chrono::NaiveDate,
  pub veterinarian: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, oas3_gen_support::Default, bon::Builder)]
pub struct PetVaccinations {
  /// Additional properties not defined in the schema.
  #[serde(flatten)]
  pub additional_properties: indexmap::IndexMap<String, Vec<VaccineRecord>>,
}
#[derive(Debug, Clone, PartialEq, Deserialize, oas3_gen_support::Default, bon::Builder)]
pub struct Pet {
  pub id: i64,
  pub name: String,
  pub allergies: Option<Box<Health>>,
  pub vaccinations: Option<indexmap::IndexMap<String, Vec<VaccineRecord>>>,
  pub tag: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Deserialize, oas3_gen_support::Default, bon::Builder)]
pub struct Cat {
  pub id: i64,
  pub name: String,
  pub allergies: Option<Box<Health>>,
  pub vaccinations: Option<indexmap::IndexMap<String, Vec<VaccineRecord>>>,
  pub tag: Option<String>,
  pub lives: i32,
  #[serde(rename = "favoriteToy")]
  pub favorite_toy: Option<String>,
}
pub type Pets = Vec<Pet>;
pub type Cats = Vec<Cat>;
#[derive(Debug, Clone, PartialEq, Deserialize, oas3_gen_support::Default, bon::Builder)]
pub struct Error {
  pub code: i32,
  pub message: String,
}
#[derive(Debug, Clone, PartialEq, validator::Validate, oas3_gen_support::Default)]
pub struct ListPetsRequestPath {
  /// Which version of the API to use.
  #[validate(length(min = 1u64))]
  pub api_version: String,
}
#[serde_with::skip_serializing_none]
#[derive(Debug, Clone, PartialEq, Serialize, validator::Validate, oas3_gen_support::Default)]
pub struct ListPetsRequestQuery {
  /// How many items to return at one time (max 100)
  #[validate(range(min = 1i32, max = 100i32))]
  pub limit: Option<i32>,
}
#[derive(Debug, Clone, PartialEq, oas3_gen_support::Default)]
pub struct ListPetsRequestHeader {
  /// Sort order for the results
  pub x_sort_order: Option<ListPetsRequestHeaderXSortOrder>,
  /// Only include pets with a tag
  pub x_only: Option<Vec<ListPetsRequestHeaderXonly>>,
}
impl core::convert::TryFrom<&ListPetsRequestHeader> for http::HeaderMap {
  type Error = http::header::InvalidHeaderValue;
  fn try_from(headers: &ListPetsRequestHeader) -> core::result::Result<Self, Self::Error> {
    let mut map = http::HeaderMap::with_capacity(2usize);
    if let Some(value) = &headers.x_sort_order {
      let header_value = http::HeaderValue::try_from(value.to_string())?;
      map.insert(X_SORT_ORDER, header_value);
    }
    if let Some(value) = &headers.x_only {
      let header_value = http::HeaderValue::try_from(
        value
          .iter()
          .map(std::string::ToString::to_string)
          .collect::<Vec<_>>()
          .join(","),
      )?;
      map.insert(X_ONLY, header_value);
    }
    Ok(map)
  }
}
impl core::convert::TryFrom<ListPetsRequestHeader> for http::HeaderMap {
  type Error = http::header::InvalidHeaderValue;
  fn try_from(headers: ListPetsRequestHeader) -> core::result::Result<Self, Self::Error> {
    http::HeaderMap::try_from(&headers)
  }
}
/// List all pets
#[derive(Debug, Clone, validator::Validate, oas3_gen_support::Default)]
pub struct ListPetsRequest {
  #[validate(nested)]
  pub path: ListPetsRequestPath,
  #[validate(nested)]
  pub query: ListPetsRequestQuery,
  pub header: ListPetsRequestHeader,
}
#[bon::bon]
impl ListPetsRequest {
  /// Create a new request with the given parameters.
  #[builder]
  pub fn new(
    api_version: String,
    limit: Option<i32>,
    x_sort_order: Option<ListPetsRequestHeaderXSortOrder>,
    x_only: Option<Vec<ListPetsRequestHeaderXonly>>,
  ) -> anyhow::Result<Self> {
    let request = Self {
      path: ListPetsRequestPath { api_version },
      query: ListPetsRequestQuery { limit },
      header: ListPetsRequestHeader { x_sort_order, x_only },
    };
    request.validate()?;
    Ok(request)
  }
}
impl ListPetsRequest {
  /// Parse the HTTP response into the response enum.
  pub async fn parse_response(req: reqwest::Response) -> anyhow::Result<ListPetsResponse> {
    let status = req.status();
    if status == http::StatusCode::OK {
      let content_type_str = req
        .headers()
        .get(reqwest::header::CONTENT_TYPE)
        .and_then(|v| v.to_str().ok())
        .unwrap_or("application/json");
      if content_type_str.contains("json") {
        let data = oas3_gen_support::Diagnostics::<Pets>::json_with_diagnostics(req).await?;
        return Ok(ListPetsResponse::Ok(data));
      }
      if content_type_str.contains("xml") {
        let data = oas3_gen_support::Diagnostics::<Pets>::xml_with_diagnostics(req).await?;
        return Ok(ListPetsResponse::Ok(data));
      }
    }
    let data = oas3_gen_support::Diagnostics::<Error>::json_with_diagnostics(req).await?;
    Ok(ListPetsResponse::Unknown(data))
  }
}
/// Response types for listPets
#[derive(Debug, Clone)]
pub enum ListPetsResponse {
  ///200: A paged array of pets
  Ok(Pets),
  ///default: unexpected error
  Unknown(Error),
}
#[derive(Debug, Clone, PartialEq, validator::Validate, oas3_gen_support::Default)]
pub struct CreatePetsRequestPath {
  /// Which version of the API to use.
  #[validate(length(min = 1u64))]
  pub api_version: String,
}
/// Create a pet
#[derive(Debug, Clone, validator::Validate, oas3_gen_support::Default)]
pub struct CreatePetsRequest {
  #[validate(nested)]
  pub path: CreatePetsRequestPath,
}
#[bon::bon]
impl CreatePetsRequest {
  /// Create a new request with the given parameters.
  #[builder]
  pub fn new(api_version: String) -> anyhow::Result<Self> {
    let request = Self {
      path: CreatePetsRequestPath { api_version },
    };
    request.validate()?;
    Ok(request)
  }
}
impl CreatePetsRequest {
  /// Parse the HTTP response into the response enum.
  pub async fn parse_response(req: reqwest::Response) -> anyhow::Result<CreatePetsResponse> {
    let status = req.status();
    if status == http::StatusCode::CREATED {
      let _ = req.bytes().await?;
      return Ok(CreatePetsResponse::Created);
    }
    let data = oas3_gen_support::Diagnostics::<Error>::json_with_diagnostics(req).await?;
    Ok(CreatePetsResponse::Unknown(data))
  }
}
/// Response types for createPets
#[derive(Debug, Clone)]
pub enum CreatePetsResponse {
  ///201: Null response
  Created,
  ///default: unexpected error
  Unknown(Error),
}
#[serde_with::skip_serializing_none]
#[derive(Debug, Clone, PartialEq, Serialize, validator::Validate, oas3_gen_support::Default)]
pub struct ListCatsRequestQuery {
  /// How many items to return at one time (max 100)
  #[validate(range(min = 1i32, max = 100i32))]
  pub limit: Option<i32>,
}
#[derive(Debug, Clone, PartialEq, oas3_gen_support::Default)]
pub struct ListCatsRequestHeader {
  /// Sort order for the results
  pub x_sort_order: Option<ListPetsRequestHeaderXSortOrder>,
}
impl core::convert::TryFrom<&ListCatsRequestHeader> for http::HeaderMap {
  type Error = http::header::InvalidHeaderValue;
  fn try_from(headers: &ListCatsRequestHeader) -> core::result::Result<Self, Self::Error> {
    let mut map = http::HeaderMap::with_capacity(1usize);
    if let Some(value) = &headers.x_sort_order {
      let header_value = http::HeaderValue::try_from(value.to_string())?;
      map.insert(X_SORT_ORDER, header_value);
    }
    Ok(map)
  }
}
impl core::convert::TryFrom<ListCatsRequestHeader> for http::HeaderMap {
  type Error = http::header::InvalidHeaderValue;
  fn try_from(headers: ListCatsRequestHeader) -> core::result::Result<Self, Self::Error> {
    http::HeaderMap::try_from(&headers)
  }
}
/// List all cats
#[derive(Debug, Clone, validator::Validate, oas3_gen_support::Default)]
pub struct ListCatsRequest {
  #[validate(nested)]
  pub query: ListCatsRequestQuery,
  pub header: ListCatsRequestHeader,
}
#[bon::bon]
impl ListCatsRequest {
  /// Create a new request with the given parameters.
  #[builder]
  pub fn new(limit: Option<i32>, x_sort_order: Option<ListPetsRequestHeaderXSortOrder>) -> anyhow::Result<Self> {
    let request = Self {
      query: ListCatsRequestQuery { limit },
      header: ListCatsRequestHeader { x_sort_order },
    };
    request.validate()?;
    Ok(request)
  }
}
impl ListCatsRequest {
  /// Parse the HTTP response into the response enum.
  pub async fn parse_response(req: reqwest::Response) -> anyhow::Result<ListCatsResponse> {
    let status = req.status();
    if status == http::StatusCode::OK {
      let data = oas3_gen_support::Diagnostics::<Cats>::json_with_diagnostics(req).await?;
      return Ok(ListCatsResponse::Ok(data));
    }
    let data = oas3_gen_support::Diagnostics::<Error>::json_with_diagnostics(req).await?;
    Ok(ListCatsResponse::Unknown(data))
  }
}
/// Response types for listCats
#[derive(Debug, Clone)]
pub enum ListCatsResponse {
  ///200: A paged array of cats
  Ok(Cats),
  ///default: unexpected error
  Unknown(Error),
}
#[derive(Debug, Clone, PartialEq, validator::Validate, oas3_gen_support::Default)]
pub struct ShowPetByIdRequestPath {
  /// The id of the pet to retrieve
  #[validate(length(min = 1u64))]
  pub pet_id: String,
}
#[derive(Debug, Clone, PartialEq, validator::Validate, oas3_gen_support::Default)]
pub struct ShowPetByIdRequestHeader {
  /// API version to use for this request
  #[validate(length(min = 1u64))]
  pub x_api_version: String,
}
impl core::convert::TryFrom<&ShowPetByIdRequestHeader> for http::HeaderMap {
  type Error = http::header::InvalidHeaderValue;
  fn try_from(headers: &ShowPetByIdRequestHeader) -> core::result::Result<Self, Self::Error> {
    let mut map = http::HeaderMap::with_capacity(1usize);
    let header_value = http::HeaderValue::try_from(&headers.x_api_version)?;
    map.insert(X_API_VERSION, header_value);
    Ok(map)
  }
}
impl core::convert::TryFrom<ShowPetByIdRequestHeader> for http::HeaderMap {
  type Error = http::header::InvalidHeaderValue;
  fn try_from(headers: ShowPetByIdRequestHeader) -> core::result::Result<Self, Self::Error> {
    http::HeaderMap::try_from(&headers)
  }
}
/// Info for a specific pet
#[derive(Debug, Clone, validator::Validate, oas3_gen_support::Default)]
pub struct ShowPetByIdRequest {
  #[validate(nested)]
  pub path: ShowPetByIdRequestPath,
  #[validate(nested)]
  pub header: ShowPetByIdRequestHeader,
}
#[bon::bon]
impl ShowPetByIdRequest {
  /// Create a new request with the given parameters.
  #[builder]
  pub fn new(pet_id: String, x_api_version: String) -> anyhow::Result<Self> {
    let request = Self {
      path: ShowPetByIdRequestPath { pet_id },
      header: ShowPetByIdRequestHeader { x_api_version },
    };
    request.validate()?;
    Ok(request)
  }
}
impl ShowPetByIdRequest {
  /// Parse the HTTP response into the response enum.
  pub async fn parse_response(req: reqwest::Response) -> anyhow::Result<ShowPetByIdResponse> {
    let status = req.status();
    if status == http::StatusCode::OK {
      let data = oas3_gen_support::Diagnostics::<Pet>::json_with_diagnostics(req).await?;
      return Ok(ShowPetByIdResponse::Ok(data));
    }
    let data = oas3_gen_support::Diagnostics::<Error>::json_with_diagnostics(req).await?;
    Ok(ShowPetByIdResponse::Unknown(data))
  }
}
/// Response types for showPetById
#[derive(Debug, Clone)]
pub enum ShowPetByIdResponse {
  ///200: Expected response to a valid request
  Ok(Pet),
  ///default: unexpected error
  Unknown(Error),
}
#[derive(Debug, Clone, PartialEq, Serialize, validator::Validate, oas3_gen_support::Default, bon::Builder)]
pub struct UploadRequestBody {
  /// The pet's name
  #[validate(length(min = 1u64))]
  pub name: String,
  /// The pet's image file
  pub image: Vec<u8>,
}
#[derive(Debug, Clone, PartialEq, validator::Validate, oas3_gen_support::Default)]
pub struct UploadPetImageRequestPath {
  /// The id of the pet to update
  #[validate(length(min = 1u64))]
  pub pet_id: String,
}
/// Upload pet image and update name
#[derive(Debug, Clone, validator::Validate, oas3_gen_support::Default)]
pub struct UploadPetImageRequest {
  #[validate(nested)]
  pub path: UploadPetImageRequestPath,
  #[validate(nested)]
  pub body: UploadRequestBody,
}
#[bon::bon]
impl UploadPetImageRequest {
  /// Create a new request with the given parameters.
  #[builder]
  pub fn new(pet_id: String, body: UploadRequestBody) -> anyhow::Result<Self> {
    let request = Self {
      path: UploadPetImageRequestPath { pet_id },
      body,
    };
    request.validate()?;
    Ok(request)
  }
}
impl UploadPetImageRequest {
  /// Parse the HTTP response into the response enum.
  pub async fn parse_response(req: reqwest::Response) -> anyhow::Result<ShowPetByIdResponse> {
    let status = req.status();
    if status == http::StatusCode::OK {
      let data = oas3_gen_support::Diagnostics::<Pet>::json_with_diagnostics(req).await?;
      return Ok(ShowPetByIdResponse::Ok(data));
    }
    let data = oas3_gen_support::Diagnostics::<Error>::json_with_diagnostics(req).await?;
    Ok(ShowPetByIdResponse::Unknown(data))
  }
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, oas3_gen_support::Default)]
pub enum ListPetsRequestHeaderXSortOrder {
  #[serde(rename = "asc")]
  #[default]
  Asc,
  #[serde(rename = "desc")]
  Desc,
}
impl core::fmt::Display for ListPetsRequestHeaderXSortOrder {
  fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
    match self {
      Self::Asc => write!(f, "asc"),
      Self::Desc => write!(f, "desc"),
    }
  }
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, oas3_gen_support::Default)]
pub enum ListPetsRequestHeaderXonly {
  #[serde(rename = "cat")]
  #[default]
  Cat,
  #[serde(rename = "dog")]
  Dog,
  #[serde(rename = "fish")]
  Fish,
  #[serde(rename = "bird")]
  Bird,
}
impl core::fmt::Display for ListPetsRequestHeaderXonly {
  fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
    match self {
      Self::Cat => write!(f, "cat"),
      Self::Dog => write!(f, "dog"),
      Self::Fish => write!(f, "fish"),
      Self::Bird => write!(f, "bird"),
    }
  }
}
