//!
//! 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 axum::response::IntoResponse;
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");
#[serde_with::skip_serializing_none]
#[derive(Debug, Clone, PartialEq, Serialize, 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>,
}
#[serde_with::skip_serializing_none]
#[derive(Debug, Clone, PartialEq, Serialize, 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 serde::Serialize for Health {
  fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
  where
    S: serde::Serializer,
  {
    match self {
      Self::Allergies(v) => v.serialize(serializer),
      Self::Diet(v) => v.serialize(serializer),
    }
  }
}
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>>,
}
#[serde_with::skip_serializing_none]
#[derive(Debug, Clone, PartialEq, Serialize, 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>,
}
#[serde_with::skip_serializing_none]
#[derive(Debug, Clone, PartialEq, Serialize, 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, Serialize, oas3_gen_support::Default, bon::Builder)]
pub struct Error {
  pub code: i32,
  pub message: String,
}
#[derive(Debug, Clone, PartialEq, Deserialize, validator::Validate, oas3_gen_support::Default)]
pub struct ListPetsRequestPath {
  /// Which version of the API to use.
  #[validate(length(min = 1u64))]
  pub api_version: String,
}
#[derive(Debug, Clone, PartialEq, Deserialize, 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)
  }
}
impl core::convert::TryFrom<&http::HeaderMap> for ListPetsRequestHeader {
  type Error = http::header::InvalidHeaderValue;
  fn try_from(headers: &http::HeaderMap) -> core::result::Result<Self, Self::Error> {
    Ok(Self {
      x_sort_order: headers
        .get(X_SORT_ORDER)
        .and_then(|v| v.to_str().ok())
        .map(|value| value.parse().unwrap_or_default()),
      x_only: headers
        .get(X_ONLY)
        .and_then(|v| v.to_str().ok())
        .map(|value| value.split(',').map(str::trim).filter_map(|s| s.parse().ok()).collect()),
    })
  }
}
impl core::convert::TryFrom<http::HeaderMap> for ListPetsRequestHeader {
  type Error = http::header::InvalidHeaderValue;
  fn try_from(headers: http::HeaderMap) -> core::result::Result<Self, Self::Error> {
    Self::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 {}
/// Response types for listPets
#[derive(Debug, Clone)]
pub enum ListPetsResponse {
  ///200: A paged array of pets
  Ok(Pets),
  ///default: unexpected error
  Unknown(Error),
}
impl IntoResponse for ListPetsResponse {
  fn into_response(self) -> axum::response::Response {
    match self {
      Self::Ok(data) => (http::StatusCode::OK, axum::Json(data)).into_response(),
      Self::Unknown(data) => (http::StatusCode::OK, axum::Json(data)).into_response(),
    }
  }
}
#[derive(Debug, Clone, PartialEq, Deserialize, 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 {}
/// Response types for createPets
#[derive(Debug, Clone)]
pub enum CreatePetsResponse {
  ///201: Null response
  Created,
  ///default: unexpected error
  Unknown(Error),
}
impl IntoResponse for CreatePetsResponse {
  fn into_response(self) -> axum::response::Response {
    match self {
      Self::Created => http::StatusCode::CREATED.into_response(),
      Self::Unknown(data) => (http::StatusCode::OK, axum::Json(data)).into_response(),
    }
  }
}
#[derive(Debug, Clone, PartialEq, Deserialize, 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)
  }
}
impl core::convert::TryFrom<&http::HeaderMap> for ListCatsRequestHeader {
  type Error = http::header::InvalidHeaderValue;
  fn try_from(headers: &http::HeaderMap) -> core::result::Result<Self, Self::Error> {
    Ok(Self {
      x_sort_order: headers
        .get(X_SORT_ORDER)
        .and_then(|v| v.to_str().ok())
        .map(|value| value.parse().unwrap_or_default()),
    })
  }
}
impl core::convert::TryFrom<http::HeaderMap> for ListCatsRequestHeader {
  type Error = http::header::InvalidHeaderValue;
  fn try_from(headers: http::HeaderMap) -> core::result::Result<Self, Self::Error> {
    Self::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 {}
/// Response types for listCats
#[derive(Debug, Clone)]
pub enum ListCatsResponse {
  ///200: A paged array of cats
  Ok(Cats),
  ///default: unexpected error
  Unknown(Error),
}
impl IntoResponse for ListCatsResponse {
  fn into_response(self) -> axum::response::Response {
    match self {
      Self::Ok(data) => (http::StatusCode::OK, axum::Json(data)).into_response(),
      Self::Unknown(data) => (http::StatusCode::OK, axum::Json(data)).into_response(),
    }
  }
}
#[derive(Debug, Clone, PartialEq, Deserialize, 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)
  }
}
impl core::convert::TryFrom<&http::HeaderMap> for ShowPetByIdRequestHeader {
  type Error = http::header::InvalidHeaderValue;
  fn try_from(headers: &http::HeaderMap) -> core::result::Result<Self, Self::Error> {
    Ok(Self {
      x_api_version: headers
        .get(X_API_VERSION)
        .and_then(|v| v.to_str().ok())
        .map(std::string::ToString::to_string)
        .unwrap_or_default(),
    })
  }
}
impl core::convert::TryFrom<http::HeaderMap> for ShowPetByIdRequestHeader {
  type Error = http::header::InvalidHeaderValue;
  fn try_from(headers: http::HeaderMap) -> core::result::Result<Self, Self::Error> {
    Self::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 {}
/// Response types for showPetById
#[derive(Debug, Clone)]
pub enum ShowPetByIdResponse {
  ///200: Expected response to a valid request
  Ok(Pet),
  ///default: unexpected error
  Unknown(Error),
}
impl IntoResponse for ShowPetByIdResponse {
  fn into_response(self) -> axum::response::Response {
    match self {
      Self::Ok(data) => (http::StatusCode::OK, axum::Json(data)).into_response(),
      Self::Unknown(data) => (http::StatusCode::OK, axum::Json(data)).into_response(),
    }
  }
}
#[derive(Debug, Clone, PartialEq, Deserialize, 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, Deserialize, 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 {}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, 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"),
    }
  }
}
impl core::str::FromStr for ListPetsRequestHeaderXSortOrder {
  type Err = String;
  fn from_str(s: &str) -> core::result::Result<Self, Self::Err> {
    match s {
      "asc" => Ok(Self::Asc),
      "desc" => Ok(Self::Desc),
      _ => Err(format!("unknown variant '{}', expected one of: {}", s, "asc, desc")),
    }
  }
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Deserialize, 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"),
    }
  }
}
impl core::str::FromStr for ListPetsRequestHeaderXonly {
  type Err = String;
  fn from_str(s: &str) -> core::result::Result<Self, Self::Err> {
    match s {
      "cat" => Ok(Self::Cat),
      "dog" => Ok(Self::Dog),
      "fish" => Ok(Self::Fish),
      "bird" => Ok(Self::Bird),
      _ => Err(format!(
        "unknown variant '{}', expected one of: {}",
        s, "cat, dog, fish, bird"
      )),
    }
  }
}
