Skip to main content

src/aws/services/rds.gleam

//// Generated from com.amazonaws.rds#AmazonRDSv19 (awsQuery).
//// DO NOT EDIT. Re-generate via the codegen subproject.

import aws/internal/client/runtime
import aws/internal/codec/json_float
import aws/internal/codec/json_timestamp
import aws/internal/uri
import gleam/bit_array
import gleam/dict
import gleam/dynamic/decode
import gleam/int
import gleam/json
import gleam/list
import gleam/option
import gleam/result
import gleam/string

// AWS form-urlencoded float formatting:
//   NaN -> "NaN", +Infinity -> "Infinity", -Infinity -> "-Infinity",
//   finite -> short-form decimal via aws_ffi:float_short/1.
// SmithyFloat already discriminates the three IEEE-754 specials,
// so the helper just dispatches on the sum.
fn format_smithy_float(v: json_float.SmithyFloat) -> String {
  case v {
    json_float.FloatValue(f) -> float_short(f)
    json_float.NaN -> "NaN"
    json_float.PosInfinity -> "Infinity"
    json_float.NegInfinity -> "-Infinity"
  }
}

@external(erlang, "aws_ffi", "float_short")
fn float_short(v: Float) -> String

pub type DatabaseInsightsMode {
  DatabaseInsightsModeAdvanced
  DatabaseInsightsModeStandard
}

pub fn database_insights_mode_to_wire(v: DatabaseInsightsMode) -> String {
  case v {
    DatabaseInsightsModeAdvanced -> "advanced"
    DatabaseInsightsModeStandard -> "standard"
  }
}

pub fn decode_database_insights_mode_enum() -> decode.Decoder(
  DatabaseInsightsMode,
) {
  decode.then(decode.string, fn(s) {
    case s {
      "advanced" -> decode.success(DatabaseInsightsModeAdvanced)
      "standard" -> decode.success(DatabaseInsightsModeStandard)
      _ -> decode.failure(DatabaseInsightsModeAdvanced, "unknown enum value")
    }
  })
}

pub type ClusterScalabilityType {
  ClusterScalabilityTypeLimitless
  ClusterScalabilityTypeStandard
}

pub fn cluster_scalability_type_to_wire(v: ClusterScalabilityType) -> String {
  case v {
    ClusterScalabilityTypeLimitless -> "limitless"
    ClusterScalabilityTypeStandard -> "standard"
  }
}

pub fn decode_cluster_scalability_type_enum() -> decode.Decoder(
  ClusterScalabilityType,
) {
  decode.then(decode.string, fn(s) {
    case s {
      "limitless" -> decode.success(ClusterScalabilityTypeLimitless)
      "standard" -> decode.success(ClusterScalabilityTypeStandard)
      _ -> decode.failure(ClusterScalabilityTypeLimitless, "unknown enum value")
    }
  })
}

pub type MasterUserAuthenticationType {
  MasterUserAuthenticationTypeIamDbAuth
  MasterUserAuthenticationTypePassword
}

pub fn master_user_authentication_type_to_wire(
  v: MasterUserAuthenticationType,
) -> String {
  case v {
    MasterUserAuthenticationTypeIamDbAuth -> "iam-db-auth"
    MasterUserAuthenticationTypePassword -> "password"
  }
}

pub fn decode_master_user_authentication_type_enum() -> decode.Decoder(
  MasterUserAuthenticationType,
) {
  decode.then(decode.string, fn(s) {
    case s {
      "iam-db-auth" -> decode.success(MasterUserAuthenticationTypeIamDbAuth)
      "password" -> decode.success(MasterUserAuthenticationTypePassword)
      _ ->
        decode.failure(
          MasterUserAuthenticationTypeIamDbAuth,
          "unknown enum value",
        )
    }
  })
}

pub type ReplicaMode {
  ReplicaModeMounted
  ReplicaModeOpenReadOnly
}

pub fn replica_mode_to_wire(v: ReplicaMode) -> String {
  case v {
    ReplicaModeMounted -> "mounted"
    ReplicaModeOpenReadOnly -> "open-read-only"
  }
}

pub fn decode_replica_mode_enum() -> decode.Decoder(ReplicaMode) {
  decode.then(decode.string, fn(s) {
    case s {
      "mounted" -> decode.success(ReplicaModeMounted)
      "open-read-only" -> decode.success(ReplicaModeOpenReadOnly)
      _ -> decode.failure(ReplicaModeMounted, "unknown enum value")
    }
  })
}

pub type EngineFamily {
  EngineFamilyMysql
  EngineFamilyPostgresql
  EngineFamilySqlserver
}

pub fn engine_family_to_wire(v: EngineFamily) -> String {
  case v {
    EngineFamilyMysql -> "MYSQL"
    EngineFamilyPostgresql -> "POSTGRESQL"
    EngineFamilySqlserver -> "SQLSERVER"
  }
}

pub fn decode_engine_family_enum() -> decode.Decoder(EngineFamily) {
  decode.then(decode.string, fn(s) {
    case s {
      "MYSQL" -> decode.success(EngineFamilyMysql)
      "POSTGRESQL" -> decode.success(EngineFamilyPostgresql)
      "SQLSERVER" -> decode.success(EngineFamilySqlserver)
      _ -> decode.failure(EngineFamilyMysql, "unknown enum value")
    }
  })
}

pub type DefaultAuthScheme {
  DefaultAuthSchemeIamAuth
  DefaultAuthSchemeNone
}

pub fn default_auth_scheme_to_wire(v: DefaultAuthScheme) -> String {
  case v {
    DefaultAuthSchemeIamAuth -> "IAM_AUTH"
    DefaultAuthSchemeNone -> "NONE"
  }
}

pub fn decode_default_auth_scheme_enum() -> decode.Decoder(DefaultAuthScheme) {
  decode.then(decode.string, fn(s) {
    case s {
      "IAM_AUTH" -> decode.success(DefaultAuthSchemeIamAuth)
      "NONE" -> decode.success(DefaultAuthSchemeNone)
      _ -> decode.failure(DefaultAuthSchemeIamAuth, "unknown enum value")
    }
  })
}

pub type EndpointNetworkType {
  EndpointNetworkTypeDual
  EndpointNetworkTypeIpv4
  EndpointNetworkTypeIpv6
}

pub fn endpoint_network_type_to_wire(v: EndpointNetworkType) -> String {
  case v {
    EndpointNetworkTypeDual -> "DUAL"
    EndpointNetworkTypeIpv4 -> "IPV4"
    EndpointNetworkTypeIpv6 -> "IPV6"
  }
}

pub fn decode_endpoint_network_type_enum() -> decode.Decoder(
  EndpointNetworkType,
) {
  decode.then(decode.string, fn(s) {
    case s {
      "DUAL" -> decode.success(EndpointNetworkTypeDual)
      "IPV4" -> decode.success(EndpointNetworkTypeIpv4)
      "IPV6" -> decode.success(EndpointNetworkTypeIpv6)
      _ -> decode.failure(EndpointNetworkTypeDual, "unknown enum value")
    }
  })
}

pub type TargetConnectionNetworkType {
  TargetConnectionNetworkTypeIpv4
  TargetConnectionNetworkTypeIpv6
}

pub fn target_connection_network_type_to_wire(
  v: TargetConnectionNetworkType,
) -> String {
  case v {
    TargetConnectionNetworkTypeIpv4 -> "IPV4"
    TargetConnectionNetworkTypeIpv6 -> "IPV6"
  }
}

pub fn decode_target_connection_network_type_enum() -> decode.Decoder(
  TargetConnectionNetworkType,
) {
  decode.then(decode.string, fn(s) {
    case s {
      "IPV4" -> decode.success(TargetConnectionNetworkTypeIpv4)
      "IPV6" -> decode.success(TargetConnectionNetworkTypeIpv6)
      _ -> decode.failure(TargetConnectionNetworkTypeIpv4, "unknown enum value")
    }
  })
}

pub type AuthScheme {
  AuthSchemeSecrets
}

pub fn auth_scheme_to_wire(v: AuthScheme) -> String {
  case v {
    AuthSchemeSecrets -> "SECRETS"
  }
}

pub fn decode_auth_scheme_enum() -> decode.Decoder(AuthScheme) {
  decode.then(decode.string, fn(s) {
    case s {
      "SECRETS" -> decode.success(AuthSchemeSecrets)
      _ -> decode.failure(AuthSchemeSecrets, "unknown enum value")
    }
  })
}

pub type ClientPasswordAuthType {
  ClientPasswordAuthTypeMysqlCachingSha2Password
  ClientPasswordAuthTypeMysqlNativePassword
  ClientPasswordAuthTypePostgresMd5
  ClientPasswordAuthTypePostgresScramSha256
  ClientPasswordAuthTypeSqlServerAuthentication
}

pub fn client_password_auth_type_to_wire(v: ClientPasswordAuthType) -> String {
  case v {
    ClientPasswordAuthTypeMysqlCachingSha2Password ->
      "MYSQL_CACHING_SHA2_PASSWORD"
    ClientPasswordAuthTypeMysqlNativePassword -> "MYSQL_NATIVE_PASSWORD"
    ClientPasswordAuthTypePostgresMd5 -> "POSTGRES_MD5"
    ClientPasswordAuthTypePostgresScramSha256 -> "POSTGRES_SCRAM_SHA_256"
    ClientPasswordAuthTypeSqlServerAuthentication -> "SQL_SERVER_AUTHENTICATION"
  }
}

pub fn decode_client_password_auth_type_enum() -> decode.Decoder(
  ClientPasswordAuthType,
) {
  decode.then(decode.string, fn(s) {
    case s {
      "MYSQL_CACHING_SHA2_PASSWORD" ->
        decode.success(ClientPasswordAuthTypeMysqlCachingSha2Password)
      "MYSQL_NATIVE_PASSWORD" ->
        decode.success(ClientPasswordAuthTypeMysqlNativePassword)
      "POSTGRES_MD5" -> decode.success(ClientPasswordAuthTypePostgresMd5)
      "POSTGRES_SCRAM_SHA_256" ->
        decode.success(ClientPasswordAuthTypePostgresScramSha256)
      "SQL_SERVER_AUTHENTICATION" ->
        decode.success(ClientPasswordAuthTypeSqlServerAuthentication)
      _ ->
        decode.failure(
          ClientPasswordAuthTypeMysqlCachingSha2Password,
          "unknown enum value",
        )
    }
  })
}

pub type IAMAuthMode {
  IAMAuthModeDisabled
  IAMAuthModeEnabled
  IAMAuthModeRequired
}

pub fn iam_auth_mode_to_wire(v: IAMAuthMode) -> String {
  case v {
    IAMAuthModeDisabled -> "DISABLED"
    IAMAuthModeEnabled -> "ENABLED"
    IAMAuthModeRequired -> "REQUIRED"
  }
}

pub fn decode_iam_auth_mode_enum() -> decode.Decoder(IAMAuthMode) {
  decode.then(decode.string, fn(s) {
    case s {
      "DISABLED" -> decode.success(IAMAuthModeDisabled)
      "ENABLED" -> decode.success(IAMAuthModeEnabled)
      "REQUIRED" -> decode.success(IAMAuthModeRequired)
      _ -> decode.failure(IAMAuthModeDisabled, "unknown enum value")
    }
  })
}

pub type DBProxyEndpointTargetRole {
  DBProxyEndpointTargetRoleReadOnly
  DBProxyEndpointTargetRoleReadWrite
}

pub fn db_proxy_endpoint_target_role_to_wire(
  v: DBProxyEndpointTargetRole,
) -> String {
  case v {
    DBProxyEndpointTargetRoleReadOnly -> "READ_ONLY"
    DBProxyEndpointTargetRoleReadWrite -> "READ_WRITE"
  }
}

pub fn decode_db_proxy_endpoint_target_role_enum() -> decode.Decoder(
  DBProxyEndpointTargetRole,
) {
  decode.then(decode.string, fn(s) {
    case s {
      "READ_ONLY" -> decode.success(DBProxyEndpointTargetRoleReadOnly)
      "READ_WRITE" -> decode.success(DBProxyEndpointTargetRoleReadWrite)
      _ ->
        decode.failure(DBProxyEndpointTargetRoleReadOnly, "unknown enum value")
    }
  })
}

pub type SourceType {
  SourceTypeBlueGreenDeployment
  SourceTypeCustomEngineVersion
  SourceTypeDbCluster
  SourceTypeDbClusterSnapshot
  SourceTypeDbInstance
  SourceTypeDbParameterGroup
  SourceTypeDbProxy
  SourceTypeDbSecurityGroup
  SourceTypeDbShardGroup
  SourceTypeDbSnapshot
  SourceTypeZeroEtl
}

pub fn source_type_to_wire(v: SourceType) -> String {
  case v {
    SourceTypeBlueGreenDeployment -> "blue-green-deployment"
    SourceTypeCustomEngineVersion -> "custom-engine-version"
    SourceTypeDbCluster -> "db-cluster"
    SourceTypeDbClusterSnapshot -> "db-cluster-snapshot"
    SourceTypeDbInstance -> "db-instance"
    SourceTypeDbParameterGroup -> "db-parameter-group"
    SourceTypeDbProxy -> "db-proxy"
    SourceTypeDbSecurityGroup -> "db-security-group"
    SourceTypeDbShardGroup -> "db-shard-group"
    SourceTypeDbSnapshot -> "db-snapshot"
    SourceTypeZeroEtl -> "zero-etl"
  }
}

pub fn decode_source_type_enum() -> decode.Decoder(SourceType) {
  decode.then(decode.string, fn(s) {
    case s {
      "blue-green-deployment" -> decode.success(SourceTypeBlueGreenDeployment)
      "custom-engine-version" -> decode.success(SourceTypeCustomEngineVersion)
      "db-cluster" -> decode.success(SourceTypeDbCluster)
      "db-cluster-snapshot" -> decode.success(SourceTypeDbClusterSnapshot)
      "db-instance" -> decode.success(SourceTypeDbInstance)
      "db-parameter-group" -> decode.success(SourceTypeDbParameterGroup)
      "db-proxy" -> decode.success(SourceTypeDbProxy)
      "db-security-group" -> decode.success(SourceTypeDbSecurityGroup)
      "db-shard-group" -> decode.success(SourceTypeDbShardGroup)
      "db-snapshot" -> decode.success(SourceTypeDbSnapshot)
      "zero-etl" -> decode.success(SourceTypeZeroEtl)
      _ -> decode.failure(SourceTypeBlueGreenDeployment, "unknown enum value")
    }
  })
}

pub type ExportSourceType {
  ExportSourceTypeCluster
  ExportSourceTypeSnapshot
}

pub fn export_source_type_to_wire(v: ExportSourceType) -> String {
  case v {
    ExportSourceTypeCluster -> "CLUSTER"
    ExportSourceTypeSnapshot -> "SNAPSHOT"
  }
}

pub fn decode_export_source_type_enum() -> decode.Decoder(ExportSourceType) {
  decode.then(decode.string, fn(s) {
    case s {
      "CLUSTER" -> decode.success(ExportSourceTypeCluster)
      "SNAPSHOT" -> decode.success(ExportSourceTypeSnapshot)
      _ -> decode.failure(ExportSourceTypeCluster, "unknown enum value")
    }
  })
}

pub type AuditPolicyState {
  AuditPolicyStateLockedPolicy
  AuditPolicyStateUnlockedPolicy
}

pub fn audit_policy_state_to_wire(v: AuditPolicyState) -> String {
  case v {
    AuditPolicyStateLockedPolicy -> "locked"
    AuditPolicyStateUnlockedPolicy -> "unlocked"
  }
}

pub fn decode_audit_policy_state_enum() -> decode.Decoder(AuditPolicyState) {
  decode.then(decode.string, fn(s) {
    case s {
      "locked" -> decode.success(AuditPolicyStateLockedPolicy)
      "unlocked" -> decode.success(AuditPolicyStateUnlockedPolicy)
      _ -> decode.failure(AuditPolicyStateLockedPolicy, "unknown enum value")
    }
  })
}

pub type CustomEngineVersionStatus {
  CustomEngineVersionStatusAvailable
  CustomEngineVersionStatusInactive
  CustomEngineVersionStatusInactiveExceptRestore
}

pub fn custom_engine_version_status_to_wire(
  v: CustomEngineVersionStatus,
) -> String {
  case v {
    CustomEngineVersionStatusAvailable -> "available"
    CustomEngineVersionStatusInactive -> "inactive"
    CustomEngineVersionStatusInactiveExceptRestore -> "inactive-except-restore"
  }
}

pub fn decode_custom_engine_version_status_enum() -> decode.Decoder(
  CustomEngineVersionStatus,
) {
  decode.then(decode.string, fn(s) {
    case s {
      "available" -> decode.success(CustomEngineVersionStatusAvailable)
      "inactive" -> decode.success(CustomEngineVersionStatusInactive)
      "inactive-except-restore" ->
        decode.success(CustomEngineVersionStatusInactiveExceptRestore)
      _ ->
        decode.failure(CustomEngineVersionStatusAvailable, "unknown enum value")
    }
  })
}

pub type ApplyMethod {
  ApplyMethodImmediate
  ApplyMethodPendingReboot
}

pub fn apply_method_to_wire(v: ApplyMethod) -> String {
  case v {
    ApplyMethodImmediate -> "immediate"
    ApplyMethodPendingReboot -> "pending-reboot"
  }
}

pub fn decode_apply_method_enum() -> decode.Decoder(ApplyMethod) {
  decode.then(decode.string, fn(s) {
    case s {
      "immediate" -> decode.success(ApplyMethodImmediate)
      "pending-reboot" -> decode.success(ApplyMethodPendingReboot)
      _ -> decode.failure(ApplyMethodImmediate, "unknown enum value")
    }
  })
}

pub type AutomationMode {
  AutomationModeAllPaused
  AutomationModeFull
}

pub fn automation_mode_to_wire(v: AutomationMode) -> String {
  case v {
    AutomationModeAllPaused -> "all-paused"
    AutomationModeFull -> "full"
  }
}

pub fn decode_automation_mode_enum() -> decode.Decoder(AutomationMode) {
  decode.then(decode.string, fn(s) {
    case s {
      "all-paused" -> decode.success(AutomationModeAllPaused)
      "full" -> decode.success(AutomationModeFull)
      _ -> decode.failure(AutomationModeAllPaused, "unknown enum value")
    }
  })
}

pub type ActivityStreamMode {
  ActivityStreamModeAsync
  ActivityStreamModeSync
}

pub fn activity_stream_mode_to_wire(v: ActivityStreamMode) -> String {
  case v {
    ActivityStreamModeAsync -> "async"
    ActivityStreamModeSync -> "sync"
  }
}

pub fn decode_activity_stream_mode_enum() -> decode.Decoder(ActivityStreamMode) {
  decode.then(decode.string, fn(s) {
    case s {
      "async" -> decode.success(ActivityStreamModeAsync)
      "sync" -> decode.success(ActivityStreamModeSync)
      _ -> decode.failure(ActivityStreamModeAsync, "unknown enum value")
    }
  })
}

pub type Tag {
  Tag(key: option.Option(String), value: option.Option(String))
}

pub fn tag_default() -> Tag {
  Tag(key: option.None, value: option.None)
}

pub fn encode_tag_at(prefix: String, s: Tag) -> String {
  let acc = ""
  let acc = case s.key {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".Key"]),
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let acc = case s.value {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".Value"]),
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  acc
}

pub fn decode_tag_struct_params() -> decode.Decoder(Tag) {
  use <- decode.recursive
  use key <- decode.optional_field(
    "Key",
    option.None,
    decode.optional(decode.string),
  )
  use value <- decode.optional_field(
    "Value",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(Tag(key: key, value: value))
}

pub type ScalingConfiguration {
  ScalingConfiguration(
    min_capacity: option.Option(Int),
    max_capacity: option.Option(Int),
    auto_pause: option.Option(Bool),
    seconds_until_auto_pause: option.Option(Int),
    timeout_action: option.Option(String),
    seconds_before_timeout: option.Option(Int),
  )
}

pub fn scaling_configuration_default() -> ScalingConfiguration {
  ScalingConfiguration(
    min_capacity: option.None,
    max_capacity: option.None,
    auto_pause: option.None,
    seconds_until_auto_pause: option.None,
    timeout_action: option.None,
    seconds_before_timeout: option.None,
  )
}

pub fn encode_scaling_configuration_at(
  prefix: String,
  s: ScalingConfiguration,
) -> String {
  let acc = ""
  let acc = case s.min_capacity {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".MinCapacity"]),
          "=",
          int.to_string(v),
        ]),
      ])
  }
  let acc = case s.max_capacity {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".MaxCapacity"]),
          "=",
          int.to_string(v),
        ]),
      ])
  }
  let acc = case s.auto_pause {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".AutoPause"]),
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let acc = case s.seconds_until_auto_pause {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".SecondsUntilAutoPause"]),
          "=",
          int.to_string(v),
        ]),
      ])
  }
  let acc = case s.timeout_action {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".TimeoutAction"]),
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let acc = case s.seconds_before_timeout {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".SecondsBeforeTimeout"]),
          "=",
          int.to_string(v),
        ]),
      ])
  }
  acc
}

pub fn decode_scaling_configuration_struct_params() -> decode.Decoder(
  ScalingConfiguration,
) {
  use <- decode.recursive
  use min_capacity <- decode.optional_field(
    "MinCapacity",
    option.None,
    decode.optional(decode.int),
  )
  use max_capacity <- decode.optional_field(
    "MaxCapacity",
    option.None,
    decode.optional(decode.int),
  )
  use auto_pause <- decode.optional_field(
    "AutoPause",
    option.None,
    decode.optional(decode.bool),
  )
  use seconds_until_auto_pause <- decode.optional_field(
    "SecondsUntilAutoPause",
    option.None,
    decode.optional(decode.int),
  )
  use timeout_action <- decode.optional_field(
    "TimeoutAction",
    option.None,
    decode.optional(decode.string),
  )
  use seconds_before_timeout <- decode.optional_field(
    "SecondsBeforeTimeout",
    option.None,
    decode.optional(decode.int),
  )
  decode.success(ScalingConfiguration(
    min_capacity: min_capacity,
    max_capacity: max_capacity,
    auto_pause: auto_pause,
    seconds_until_auto_pause: seconds_until_auto_pause,
    timeout_action: timeout_action,
    seconds_before_timeout: seconds_before_timeout,
  ))
}

pub type RdsCustomClusterConfiguration {
  RdsCustomClusterConfiguration(
    interconnect_subnet_id: option.Option(String),
    transit_gateway_multicast_domain_id: option.Option(String),
    replica_mode: option.Option(ReplicaMode),
  )
}

pub fn rds_custom_cluster_configuration_default() -> RdsCustomClusterConfiguration {
  RdsCustomClusterConfiguration(
    interconnect_subnet_id: option.None,
    transit_gateway_multicast_domain_id: option.None,
    replica_mode: option.None,
  )
}

pub fn encode_rds_custom_cluster_configuration_at(
  prefix: String,
  s: RdsCustomClusterConfiguration,
) -> String {
  let acc = ""
  let acc = case s.interconnect_subnet_id {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".InterconnectSubnetId"]),
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let acc = case s.transit_gateway_multicast_domain_id {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".TransitGatewayMulticastDomainId"]),
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let acc = case s.replica_mode {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".ReplicaMode"]),
          "=",
          uri.encode_component(replica_mode_to_wire(v)),
        ]),
      ])
  }
  acc
}

pub fn decode_rds_custom_cluster_configuration_struct_params() -> decode.Decoder(
  RdsCustomClusterConfiguration,
) {
  use <- decode.recursive
  use interconnect_subnet_id <- decode.optional_field(
    "InterconnectSubnetId",
    option.None,
    decode.optional(decode.string),
  )
  use transit_gateway_multicast_domain_id <- decode.optional_field(
    "TransitGatewayMulticastDomainId",
    option.None,
    decode.optional(decode.string),
  )
  use replica_mode <- decode.optional_field(
    "ReplicaMode",
    option.None,
    decode.optional(decode_replica_mode_enum()),
  )
  decode.success(RdsCustomClusterConfiguration(
    interconnect_subnet_id: interconnect_subnet_id,
    transit_gateway_multicast_domain_id: transit_gateway_multicast_domain_id,
    replica_mode: replica_mode,
  ))
}

pub type ServerlessV2ScalingConfiguration {
  ServerlessV2ScalingConfiguration(
    min_capacity: option.Option(json_float.SmithyFloat),
    max_capacity: option.Option(json_float.SmithyFloat),
    seconds_until_auto_pause: option.Option(Int),
  )
}

pub fn serverless_v2_scaling_configuration_default() -> ServerlessV2ScalingConfiguration {
  ServerlessV2ScalingConfiguration(
    min_capacity: option.None,
    max_capacity: option.None,
    seconds_until_auto_pause: option.None,
  )
}

pub fn encode_serverless_v2_scaling_configuration_at(
  prefix: String,
  s: ServerlessV2ScalingConfiguration,
) -> String {
  let acc = ""
  let acc = case s.min_capacity {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".MinCapacity"]),
          "=",
          format_smithy_float(v),
        ]),
      ])
  }
  let acc = case s.max_capacity {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".MaxCapacity"]),
          "=",
          format_smithy_float(v),
        ]),
      ])
  }
  let acc = case s.seconds_until_auto_pause {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".SecondsUntilAutoPause"]),
          "=",
          int.to_string(v),
        ]),
      ])
  }
  acc
}

pub fn decode_serverless_v2_scaling_configuration_struct_params() -> decode.Decoder(
  ServerlessV2ScalingConfiguration,
) {
  use <- decode.recursive
  use min_capacity <- decode.optional_field(
    "MinCapacity",
    option.None,
    decode.optional(json_float.decoder()),
  )
  use max_capacity <- decode.optional_field(
    "MaxCapacity",
    option.None,
    decode.optional(json_float.decoder()),
  )
  use seconds_until_auto_pause <- decode.optional_field(
    "SecondsUntilAutoPause",
    option.None,
    decode.optional(decode.int),
  )
  decode.success(ServerlessV2ScalingConfiguration(
    min_capacity: min_capacity,
    max_capacity: max_capacity,
    seconds_until_auto_pause: seconds_until_auto_pause,
  ))
}

pub type TagSpecification {
  TagSpecification(
    resource_type: option.Option(String),
    tags: option.Option(List(Tag)),
  )
}

pub fn tag_specification_default() -> TagSpecification {
  TagSpecification(resource_type: option.None, tags: option.None)
}

pub fn encode_tag_specification_at(
  prefix: String,
  s: TagSpecification,
) -> String {
  let acc = ""
  let acc = case s.resource_type {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".ResourceType"]),
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let acc = case s.tags {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        case v {
          [] -> string.concat(["&", string.concat([prefix, ".Tags"]), "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_tag_at(
                  string.concat([
                    string.concat([prefix, ".Tags"]),
                    ".Tag.",
                    int.to_string(idx + 1),
                  ]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  acc
}

pub fn decode_tag_specification_struct_params() -> decode.Decoder(
  TagSpecification,
) {
  use <- decode.recursive
  use resource_type <- decode.optional_field(
    "ResourceType",
    option.None,
    decode.optional(decode.string),
  )
  use tags <- decode.optional_field(
    "Tags",
    option.None,
    decode.optional(decode.list(decode_tag_struct_params())),
  )
  decode.success(TagSpecification(resource_type: resource_type, tags: tags))
}

pub type ProcessorFeature {
  ProcessorFeature(name: option.Option(String), value: option.Option(String))
}

pub fn processor_feature_default() -> ProcessorFeature {
  ProcessorFeature(name: option.None, value: option.None)
}

pub fn encode_processor_feature_at(
  prefix: String,
  s: ProcessorFeature,
) -> String {
  let acc = ""
  let acc = case s.name {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".Name"]),
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let acc = case s.value {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".Value"]),
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  acc
}

pub fn decode_processor_feature_struct_params() -> decode.Decoder(
  ProcessorFeature,
) {
  use <- decode.recursive
  use name <- decode.optional_field(
    "Name",
    option.None,
    decode.optional(decode.string),
  )
  use value <- decode.optional_field(
    "Value",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(ProcessorFeature(name: name, value: value))
}

pub type AdditionalStorageVolume {
  AdditionalStorageVolume(
    volume_name: String,
    allocated_storage: option.Option(Int),
    iops: option.Option(Int),
    max_allocated_storage: option.Option(Int),
    storage_throughput: option.Option(Int),
    storage_type: option.Option(String),
  )
}

pub fn additional_storage_volume_default(
  volume_name volume_name: String,
) -> AdditionalStorageVolume {
  AdditionalStorageVolume(
    volume_name: volume_name,
    allocated_storage: option.None,
    iops: option.None,
    max_allocated_storage: option.None,
    storage_throughput: option.None,
    storage_type: option.None,
  )
}

pub fn encode_additional_storage_volume_at(
  prefix: String,
  s: AdditionalStorageVolume,
) -> String {
  let acc = ""
  let v = s.volume_name
  let acc =
    string.concat([
      acc,
      string.concat([
        "&",
        string.concat([prefix, ".VolumeName"]),
        "=",
        uri.encode_component(v),
      ]),
    ])
  let acc = case s.allocated_storage {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".AllocatedStorage"]),
          "=",
          int.to_string(v),
        ]),
      ])
  }
  let acc = case s.iops {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".IOPS"]),
          "=",
          int.to_string(v),
        ]),
      ])
  }
  let acc = case s.max_allocated_storage {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".MaxAllocatedStorage"]),
          "=",
          int.to_string(v),
        ]),
      ])
  }
  let acc = case s.storage_throughput {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".StorageThroughput"]),
          "=",
          int.to_string(v),
        ]),
      ])
  }
  let acc = case s.storage_type {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".StorageType"]),
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  acc
}

pub fn decode_additional_storage_volume_struct_params() -> decode.Decoder(
  AdditionalStorageVolume,
) {
  use <- decode.recursive
  use volume_name <- decode.field("VolumeName", decode.string)
  use allocated_storage <- decode.optional_field(
    "AllocatedStorage",
    option.None,
    decode.optional(decode.int),
  )
  use iops <- decode.optional_field(
    "IOPS",
    option.None,
    decode.optional(decode.int),
  )
  use max_allocated_storage <- decode.optional_field(
    "MaxAllocatedStorage",
    option.None,
    decode.optional(decode.int),
  )
  use storage_throughput <- decode.optional_field(
    "StorageThroughput",
    option.None,
    decode.optional(decode.int),
  )
  use storage_type <- decode.optional_field(
    "StorageType",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(AdditionalStorageVolume(
    volume_name: volume_name,
    allocated_storage: allocated_storage,
    iops: iops,
    max_allocated_storage: max_allocated_storage,
    storage_throughput: storage_throughput,
    storage_type: storage_type,
  ))
}

pub type UserAuthConfig {
  UserAuthConfig(
    description: option.Option(String),
    user_name: option.Option(String),
    auth_scheme: option.Option(AuthScheme),
    secret_arn: option.Option(String),
    iam_auth: option.Option(IAMAuthMode),
    client_password_auth_type: option.Option(ClientPasswordAuthType),
  )
}

pub fn user_auth_config_default() -> UserAuthConfig {
  UserAuthConfig(
    description: option.None,
    user_name: option.None,
    auth_scheme: option.None,
    secret_arn: option.None,
    iam_auth: option.None,
    client_password_auth_type: option.None,
  )
}

pub fn encode_user_auth_config_at(prefix: String, s: UserAuthConfig) -> String {
  let acc = ""
  let acc = case s.description {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".Description"]),
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let acc = case s.user_name {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".UserName"]),
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let acc = case s.auth_scheme {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".AuthScheme"]),
          "=",
          uri.encode_component(auth_scheme_to_wire(v)),
        ]),
      ])
  }
  let acc = case s.secret_arn {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".SecretArn"]),
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let acc = case s.iam_auth {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".IAMAuth"]),
          "=",
          uri.encode_component(iam_auth_mode_to_wire(v)),
        ]),
      ])
  }
  let acc = case s.client_password_auth_type {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".ClientPasswordAuthType"]),
          "=",
          uri.encode_component(client_password_auth_type_to_wire(v)),
        ]),
      ])
  }
  acc
}

pub fn decode_user_auth_config_struct_params() -> decode.Decoder(UserAuthConfig) {
  use <- decode.recursive
  use description <- decode.optional_field(
    "Description",
    option.None,
    decode.optional(decode.string),
  )
  use user_name <- decode.optional_field(
    "UserName",
    option.None,
    decode.optional(decode.string),
  )
  use auth_scheme <- decode.optional_field(
    "AuthScheme",
    option.None,
    decode.optional(decode_auth_scheme_enum()),
  )
  use secret_arn <- decode.optional_field(
    "SecretArn",
    option.None,
    decode.optional(decode.string),
  )
  use iam_auth <- decode.optional_field(
    "IAMAuth",
    option.None,
    decode.optional(decode_iam_auth_mode_enum()),
  )
  use client_password_auth_type <- decode.optional_field(
    "ClientPasswordAuthType",
    option.None,
    decode.optional(decode_client_password_auth_type_enum()),
  )
  decode.success(UserAuthConfig(
    description: description,
    user_name: user_name,
    auth_scheme: auth_scheme,
    secret_arn: secret_arn,
    iam_auth: iam_auth,
    client_password_auth_type: client_password_auth_type,
  ))
}

pub type Filter {
  Filter(name: String, values: List(String))
}

pub fn filter_default(
  name name: String,
  values values: List(String),
) -> Filter {
  Filter(name: name, values: values)
}

pub fn encode_filter_at(prefix: String, s: Filter) -> String {
  let acc = ""
  let v = s.name
  let acc =
    string.concat([
      acc,
      string.concat([
        "&",
        string.concat([prefix, ".Name"]),
        "=",
        uri.encode_component(v),
      ]),
    ])
  let v = s.values
  let acc =
    string.concat([
      acc,
      case v {
        [] -> string.concat(["&", string.concat([prefix, ".Values"]), "=", ""])
        _ ->
          list.index_fold(v, "", fn(acc, item, idx) {
            string.concat([
              acc,
              string.concat([
                "&",
                string.concat([
                  string.concat([prefix, ".Values"]),
                  ".Value.",
                  int.to_string(idx + 1),
                ]),
                "=",
                uri.encode_component(item),
              ]),
            ])
          })
      },
    ])
  acc
}

pub fn decode_filter_struct_params() -> decode.Decoder(Filter) {
  use <- decode.recursive
  use name <- decode.field("Name", decode.string)
  use values <- decode.field("Values", decode.list(decode.string))
  decode.success(Filter(name: name, values: values))
}

pub type CloudwatchLogsExportConfiguration {
  CloudwatchLogsExportConfiguration(
    enable_log_types: option.Option(List(String)),
    disable_log_types: option.Option(List(String)),
  )
}

pub fn cloudwatch_logs_export_configuration_default() -> CloudwatchLogsExportConfiguration {
  CloudwatchLogsExportConfiguration(
    enable_log_types: option.None,
    disable_log_types: option.None,
  )
}

pub fn encode_cloudwatch_logs_export_configuration_at(
  prefix: String,
  s: CloudwatchLogsExportConfiguration,
) -> String {
  let acc = ""
  let acc = case s.enable_log_types {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        case v {
          [] ->
            string.concat([
              "&",
              string.concat([prefix, ".EnableLogTypes"]),
              "=",
              "",
            ])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    string.concat([prefix, ".EnableLogTypes"]),
                    ".member.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let acc = case s.disable_log_types {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        case v {
          [] ->
            string.concat([
              "&",
              string.concat([prefix, ".DisableLogTypes"]),
              "=",
              "",
            ])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    string.concat([prefix, ".DisableLogTypes"]),
                    ".member.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  acc
}

pub fn decode_cloudwatch_logs_export_configuration_struct_params() -> decode.Decoder(
  CloudwatchLogsExportConfiguration,
) {
  use <- decode.recursive
  use enable_log_types <- decode.optional_field(
    "EnableLogTypes",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use disable_log_types <- decode.optional_field(
    "DisableLogTypes",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  decode.success(CloudwatchLogsExportConfiguration(
    enable_log_types: enable_log_types,
    disable_log_types: disable_log_types,
  ))
}

pub type Parameter {
  Parameter(
    parameter_name: option.Option(String),
    parameter_value: option.Option(String),
    description: option.Option(String),
    source: option.Option(String),
    apply_type: option.Option(String),
    data_type: option.Option(String),
    allowed_values: option.Option(String),
    is_modifiable: option.Option(Bool),
    minimum_engine_version: option.Option(String),
    apply_method: option.Option(ApplyMethod),
    supported_engine_modes: option.Option(List(String)),
  )
}

pub fn parameter_default() -> Parameter {
  Parameter(
    parameter_name: option.None,
    parameter_value: option.None,
    description: option.None,
    source: option.None,
    apply_type: option.None,
    data_type: option.None,
    allowed_values: option.None,
    is_modifiable: option.None,
    minimum_engine_version: option.None,
    apply_method: option.None,
    supported_engine_modes: option.None,
  )
}

pub fn encode_parameter_at(prefix: String, s: Parameter) -> String {
  let acc = ""
  let acc = case s.parameter_name {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".ParameterName"]),
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let acc = case s.parameter_value {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".ParameterValue"]),
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let acc = case s.description {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".Description"]),
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let acc = case s.source {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".Source"]),
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let acc = case s.apply_type {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".ApplyType"]),
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let acc = case s.data_type {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".DataType"]),
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let acc = case s.allowed_values {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".AllowedValues"]),
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let acc = case s.is_modifiable {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".IsModifiable"]),
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let acc = case s.minimum_engine_version {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".MinimumEngineVersion"]),
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let acc = case s.apply_method {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".ApplyMethod"]),
          "=",
          uri.encode_component(apply_method_to_wire(v)),
        ]),
      ])
  }
  let acc = case s.supported_engine_modes {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        case v {
          [] ->
            string.concat([
              "&",
              string.concat([prefix, ".SupportedEngineModes"]),
              "=",
              "",
            ])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    string.concat([prefix, ".SupportedEngineModes"]),
                    ".member.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  acc
}

pub fn decode_parameter_struct_params() -> decode.Decoder(Parameter) {
  use <- decode.recursive
  use parameter_name <- decode.optional_field(
    "ParameterName",
    option.None,
    decode.optional(decode.string),
  )
  use parameter_value <- decode.optional_field(
    "ParameterValue",
    option.None,
    decode.optional(decode.string),
  )
  use description <- decode.optional_field(
    "Description",
    option.None,
    decode.optional(decode.string),
  )
  use source <- decode.optional_field(
    "Source",
    option.None,
    decode.optional(decode.string),
  )
  use apply_type <- decode.optional_field(
    "ApplyType",
    option.None,
    decode.optional(decode.string),
  )
  use data_type <- decode.optional_field(
    "DataType",
    option.None,
    decode.optional(decode.string),
  )
  use allowed_values <- decode.optional_field(
    "AllowedValues",
    option.None,
    decode.optional(decode.string),
  )
  use is_modifiable <- decode.optional_field(
    "IsModifiable",
    option.None,
    decode.optional(decode.bool),
  )
  use minimum_engine_version <- decode.optional_field(
    "MinimumEngineVersion",
    option.None,
    decode.optional(decode.string),
  )
  use apply_method <- decode.optional_field(
    "ApplyMethod",
    option.None,
    decode.optional(decode_apply_method_enum()),
  )
  use supported_engine_modes <- decode.optional_field(
    "SupportedEngineModes",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  decode.success(Parameter(
    parameter_name: parameter_name,
    parameter_value: parameter_value,
    description: description,
    source: source,
    apply_type: apply_type,
    data_type: data_type,
    allowed_values: allowed_values,
    is_modifiable: is_modifiable,
    minimum_engine_version: minimum_engine_version,
    apply_method: apply_method,
    supported_engine_modes: supported_engine_modes,
  ))
}

pub type ModifyAdditionalStorageVolume {
  ModifyAdditionalStorageVolume(
    volume_name: String,
    allocated_storage: option.Option(Int),
    iops: option.Option(Int),
    max_allocated_storage: option.Option(Int),
    storage_throughput: option.Option(Int),
    storage_type: option.Option(String),
    set_for_delete: option.Option(Bool),
  )
}

pub fn modify_additional_storage_volume_default(
  volume_name volume_name: String,
) -> ModifyAdditionalStorageVolume {
  ModifyAdditionalStorageVolume(
    volume_name: volume_name,
    allocated_storage: option.None,
    iops: option.None,
    max_allocated_storage: option.None,
    storage_throughput: option.None,
    storage_type: option.None,
    set_for_delete: option.None,
  )
}

pub fn encode_modify_additional_storage_volume_at(
  prefix: String,
  s: ModifyAdditionalStorageVolume,
) -> String {
  let acc = ""
  let v = s.volume_name
  let acc =
    string.concat([
      acc,
      string.concat([
        "&",
        string.concat([prefix, ".VolumeName"]),
        "=",
        uri.encode_component(v),
      ]),
    ])
  let acc = case s.allocated_storage {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".AllocatedStorage"]),
          "=",
          int.to_string(v),
        ]),
      ])
  }
  let acc = case s.iops {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".IOPS"]),
          "=",
          int.to_string(v),
        ]),
      ])
  }
  let acc = case s.max_allocated_storage {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".MaxAllocatedStorage"]),
          "=",
          int.to_string(v),
        ]),
      ])
  }
  let acc = case s.storage_throughput {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".StorageThroughput"]),
          "=",
          int.to_string(v),
        ]),
      ])
  }
  let acc = case s.storage_type {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".StorageType"]),
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let acc = case s.set_for_delete {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".SetForDelete"]),
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  acc
}

pub fn decode_modify_additional_storage_volume_struct_params() -> decode.Decoder(
  ModifyAdditionalStorageVolume,
) {
  use <- decode.recursive
  use volume_name <- decode.field("VolumeName", decode.string)
  use allocated_storage <- decode.optional_field(
    "AllocatedStorage",
    option.None,
    decode.optional(decode.int),
  )
  use iops <- decode.optional_field(
    "IOPS",
    option.None,
    decode.optional(decode.int),
  )
  use max_allocated_storage <- decode.optional_field(
    "MaxAllocatedStorage",
    option.None,
    decode.optional(decode.int),
  )
  use storage_throughput <- decode.optional_field(
    "StorageThroughput",
    option.None,
    decode.optional(decode.int),
  )
  use storage_type <- decode.optional_field(
    "StorageType",
    option.None,
    decode.optional(decode.string),
  )
  use set_for_delete <- decode.optional_field(
    "SetForDelete",
    option.None,
    decode.optional(decode.bool),
  )
  decode.success(ModifyAdditionalStorageVolume(
    volume_name: volume_name,
    allocated_storage: allocated_storage,
    iops: iops,
    max_allocated_storage: max_allocated_storage,
    storage_throughput: storage_throughput,
    storage_type: storage_type,
    set_for_delete: set_for_delete,
  ))
}

pub type ConnectionPoolConfiguration {
  ConnectionPoolConfiguration(
    max_connections_percent: option.Option(Int),
    max_idle_connections_percent: option.Option(Int),
    connection_borrow_timeout: option.Option(Int),
    session_pinning_filters: option.Option(List(String)),
    init_query: option.Option(String),
  )
}

pub fn connection_pool_configuration_default() -> ConnectionPoolConfiguration {
  ConnectionPoolConfiguration(
    max_connections_percent: option.None,
    max_idle_connections_percent: option.None,
    connection_borrow_timeout: option.None,
    session_pinning_filters: option.None,
    init_query: option.None,
  )
}

pub fn encode_connection_pool_configuration_at(
  prefix: String,
  s: ConnectionPoolConfiguration,
) -> String {
  let acc = ""
  let acc = case s.max_connections_percent {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".MaxConnectionsPercent"]),
          "=",
          int.to_string(v),
        ]),
      ])
  }
  let acc = case s.max_idle_connections_percent {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".MaxIdleConnectionsPercent"]),
          "=",
          int.to_string(v),
        ]),
      ])
  }
  let acc = case s.connection_borrow_timeout {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".ConnectionBorrowTimeout"]),
          "=",
          int.to_string(v),
        ]),
      ])
  }
  let acc = case s.session_pinning_filters {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        case v {
          [] ->
            string.concat([
              "&",
              string.concat([prefix, ".SessionPinningFilters"]),
              "=",
              "",
            ])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    string.concat([prefix, ".SessionPinningFilters"]),
                    ".member.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let acc = case s.init_query {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".InitQuery"]),
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  acc
}

pub fn decode_connection_pool_configuration_struct_params() -> decode.Decoder(
  ConnectionPoolConfiguration,
) {
  use <- decode.recursive
  use max_connections_percent <- decode.optional_field(
    "MaxConnectionsPercent",
    option.None,
    decode.optional(decode.int),
  )
  use max_idle_connections_percent <- decode.optional_field(
    "MaxIdleConnectionsPercent",
    option.None,
    decode.optional(decode.int),
  )
  use connection_borrow_timeout <- decode.optional_field(
    "ConnectionBorrowTimeout",
    option.None,
    decode.optional(decode.int),
  )
  use session_pinning_filters <- decode.optional_field(
    "SessionPinningFilters",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use init_query <- decode.optional_field(
    "InitQuery",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(ConnectionPoolConfiguration(
    max_connections_percent: max_connections_percent,
    max_idle_connections_percent: max_idle_connections_percent,
    connection_borrow_timeout: connection_borrow_timeout,
    session_pinning_filters: session_pinning_filters,
    init_query: init_query,
  ))
}

pub type RecommendedActionUpdate {
  RecommendedActionUpdate(action_id: String, status: String)
}

pub fn recommended_action_update_default(
  action_id action_id: String,
  status status: String,
) -> RecommendedActionUpdate {
  RecommendedActionUpdate(action_id: action_id, status: status)
}

pub fn encode_recommended_action_update_at(
  prefix: String,
  s: RecommendedActionUpdate,
) -> String {
  let acc = ""
  let v = s.action_id
  let acc =
    string.concat([
      acc,
      string.concat([
        "&",
        string.concat([prefix, ".ActionId"]),
        "=",
        uri.encode_component(v),
      ]),
    ])
  let v = s.status
  let acc =
    string.concat([
      acc,
      string.concat([
        "&",
        string.concat([prefix, ".Status"]),
        "=",
        uri.encode_component(v),
      ]),
    ])
  acc
}

pub fn decode_recommended_action_update_struct_params() -> decode.Decoder(
  RecommendedActionUpdate,
) {
  use <- decode.recursive
  use action_id <- decode.field("ActionId", decode.string)
  use status <- decode.field("Status", decode.string)
  decode.success(RecommendedActionUpdate(action_id: action_id, status: status))
}

pub type OptionConfiguration {
  OptionConfiguration(
    option_name: String,
    port: option.Option(Int),
    option_version: option.Option(String),
    db_security_group_memberships: option.Option(List(String)),
    vpc_security_group_memberships: option.Option(List(String)),
    option_settings: option.Option(List(OptionSetting)),
  )
}

pub fn option_configuration_default(
  option_name option_name: String,
) -> OptionConfiguration {
  OptionConfiguration(
    option_name: option_name,
    port: option.None,
    option_version: option.None,
    db_security_group_memberships: option.None,
    vpc_security_group_memberships: option.None,
    option_settings: option.None,
  )
}

pub fn encode_option_configuration_at(
  prefix: String,
  s: OptionConfiguration,
) -> String {
  let acc = ""
  let v = s.option_name
  let acc =
    string.concat([
      acc,
      string.concat([
        "&",
        string.concat([prefix, ".OptionName"]),
        "=",
        uri.encode_component(v),
      ]),
    ])
  let acc = case s.port {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".Port"]),
          "=",
          int.to_string(v),
        ]),
      ])
  }
  let acc = case s.option_version {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".OptionVersion"]),
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let acc = case s.db_security_group_memberships {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        case v {
          [] ->
            string.concat([
              "&",
              string.concat([prefix, ".DBSecurityGroupMemberships"]),
              "=",
              "",
            ])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    string.concat([prefix, ".DBSecurityGroupMemberships"]),
                    ".DBSecurityGroupName.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let acc = case s.vpc_security_group_memberships {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        case v {
          [] ->
            string.concat([
              "&",
              string.concat([prefix, ".VpcSecurityGroupMemberships"]),
              "=",
              "",
            ])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    string.concat([prefix, ".VpcSecurityGroupMemberships"]),
                    ".VpcSecurityGroupId.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let acc = case s.option_settings {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        case v {
          [] ->
            string.concat([
              "&",
              string.concat([prefix, ".OptionSettings"]),
              "=",
              "",
            ])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_option_setting_at(
                  string.concat([
                    string.concat([prefix, ".OptionSettings"]),
                    ".OptionSetting.",
                    int.to_string(idx + 1),
                  ]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  acc
}

pub fn decode_option_configuration_struct_params() -> decode.Decoder(
  OptionConfiguration,
) {
  use <- decode.recursive
  use option_name <- decode.field("OptionName", decode.string)
  use port <- decode.optional_field(
    "Port",
    option.None,
    decode.optional(decode.int),
  )
  use option_version <- decode.optional_field(
    "OptionVersion",
    option.None,
    decode.optional(decode.string),
  )
  use db_security_group_memberships <- decode.optional_field(
    "DBSecurityGroupMemberships",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use vpc_security_group_memberships <- decode.optional_field(
    "VpcSecurityGroupMemberships",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use option_settings <- decode.optional_field(
    "OptionSettings",
    option.None,
    decode.optional(decode.list(decode_option_setting_struct_params())),
  )
  decode.success(OptionConfiguration(
    option_name: option_name,
    port: port,
    option_version: option_version,
    db_security_group_memberships: db_security_group_memberships,
    vpc_security_group_memberships: vpc_security_group_memberships,
    option_settings: option_settings,
  ))
}

pub type OptionSetting {
  OptionSetting(
    name: option.Option(String),
    value: option.Option(String),
    default_value: option.Option(String),
    description: option.Option(String),
    apply_type: option.Option(String),
    data_type: option.Option(String),
    allowed_values: option.Option(String),
    is_modifiable: option.Option(Bool),
    is_collection: option.Option(Bool),
  )
}

pub fn option_setting_default() -> OptionSetting {
  OptionSetting(
    name: option.None,
    value: option.None,
    default_value: option.None,
    description: option.None,
    apply_type: option.None,
    data_type: option.None,
    allowed_values: option.None,
    is_modifiable: option.None,
    is_collection: option.None,
  )
}

pub fn encode_option_setting_at(prefix: String, s: OptionSetting) -> String {
  let acc = ""
  let acc = case s.name {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".Name"]),
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let acc = case s.value {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".Value"]),
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let acc = case s.default_value {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".DefaultValue"]),
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let acc = case s.description {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".Description"]),
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let acc = case s.apply_type {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".ApplyType"]),
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let acc = case s.data_type {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".DataType"]),
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let acc = case s.allowed_values {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".AllowedValues"]),
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let acc = case s.is_modifiable {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".IsModifiable"]),
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let acc = case s.is_collection {
    option.None -> acc
    option.Some(v) ->
      string.concat([
        acc,
        string.concat([
          "&",
          string.concat([prefix, ".IsCollection"]),
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  acc
}

pub fn decode_option_setting_struct_params() -> decode.Decoder(OptionSetting) {
  use <- decode.recursive
  use name <- decode.optional_field(
    "Name",
    option.None,
    decode.optional(decode.string),
  )
  use value <- decode.optional_field(
    "Value",
    option.None,
    decode.optional(decode.string),
  )
  use default_value <- decode.optional_field(
    "DefaultValue",
    option.None,
    decode.optional(decode.string),
  )
  use description <- decode.optional_field(
    "Description",
    option.None,
    decode.optional(decode.string),
  )
  use apply_type <- decode.optional_field(
    "ApplyType",
    option.None,
    decode.optional(decode.string),
  )
  use data_type <- decode.optional_field(
    "DataType",
    option.None,
    decode.optional(decode.string),
  )
  use allowed_values <- decode.optional_field(
    "AllowedValues",
    option.None,
    decode.optional(decode.string),
  )
  use is_modifiable <- decode.optional_field(
    "IsModifiable",
    option.None,
    decode.optional(decode.bool),
  )
  use is_collection <- decode.optional_field(
    "IsCollection",
    option.None,
    decode.optional(decode.bool),
  )
  decode.success(OptionSetting(
    name: name,
    value: value,
    default_value: default_value,
    description: description,
    apply_type: apply_type,
    data_type: data_type,
    allowed_values: allowed_values,
    is_modifiable: is_modifiable,
    is_collection: is_collection,
  ))
}

pub type AddRoleToDBClusterInput {
  AddRoleToDBClusterInput(
    db_cluster_identifier: String,
    role_arn: String,
    feature_name: option.Option(String),
  )
}

pub fn add_role_to_db_cluster_input_default(
  db_cluster_identifier db_cluster_identifier: String,
  role_arn role_arn: String,
) -> AddRoleToDBClusterInput {
  AddRoleToDBClusterInput(
    db_cluster_identifier: db_cluster_identifier,
    role_arn: role_arn,
    feature_name: option.None,
  )
}

pub type AddRoleToDBClusterOutput {
  AddRoleToDBClusterOutput
}

pub fn decode_add_role_to_db_cluster_input_struct() -> decode.Decoder(
  AddRoleToDBClusterInput,
) {
  use <- decode.recursive
  use db_cluster_identifier <- decode.field(
    "DBClusterIdentifier",
    decode.string,
  )
  use role_arn <- decode.field("RoleArn", decode.string)
  use feature_name <- decode.optional_field(
    "FeatureName",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(AddRoleToDBClusterInput(
    db_cluster_identifier: db_cluster_identifier,
    role_arn: role_arn,
    feature_name: feature_name,
  ))
}

pub fn decode_add_role_to_db_cluster_input(
  json_string: String,
) -> Result(AddRoleToDBClusterInput, String) {
  result.map_error(
    json.parse(json_string, decode_add_role_to_db_cluster_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_add_role_to_db_cluster_request(
  input: AddRoleToDBClusterInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=AddRoleToDBCluster&Version=2014-10-31"
  let body = {
    let v = input.db_cluster_identifier
    string.concat([
      body,
      string.concat(["&", "DBClusterIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.role_arn
    string.concat([
      body,
      string.concat(["&", "RoleArn", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.feature_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "FeatureName", "=", uri.encode_component(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_add_role_to_db_cluster_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(AddRoleToDBClusterOutput, String) {
  Ok(AddRoleToDBClusterOutput)
}

pub type AddRoleToDBInstanceInput {
  AddRoleToDBInstanceInput(
    db_instance_identifier: String,
    role_arn: String,
    feature_name: String,
  )
}

pub fn add_role_to_db_instance_input_default(
  db_instance_identifier db_instance_identifier: String,
  role_arn role_arn: String,
  feature_name feature_name: String,
) -> AddRoleToDBInstanceInput {
  AddRoleToDBInstanceInput(
    db_instance_identifier: db_instance_identifier,
    role_arn: role_arn,
    feature_name: feature_name,
  )
}

pub type AddRoleToDBInstanceOutput {
  AddRoleToDBInstanceOutput
}

pub fn decode_add_role_to_db_instance_input_struct() -> decode.Decoder(
  AddRoleToDBInstanceInput,
) {
  use <- decode.recursive
  use db_instance_identifier <- decode.field(
    "DBInstanceIdentifier",
    decode.string,
  )
  use role_arn <- decode.field("RoleArn", decode.string)
  use feature_name <- decode.field("FeatureName", decode.string)
  decode.success(AddRoleToDBInstanceInput(
    db_instance_identifier: db_instance_identifier,
    role_arn: role_arn,
    feature_name: feature_name,
  ))
}

pub fn decode_add_role_to_db_instance_input(
  json_string: String,
) -> Result(AddRoleToDBInstanceInput, String) {
  result.map_error(
    json.parse(json_string, decode_add_role_to_db_instance_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_add_role_to_db_instance_request(
  input: AddRoleToDBInstanceInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=AddRoleToDBInstance&Version=2014-10-31"
  let body = {
    let v = input.db_instance_identifier
    string.concat([
      body,
      string.concat(["&", "DBInstanceIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.role_arn
    string.concat([
      body,
      string.concat(["&", "RoleArn", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.feature_name
    string.concat([
      body,
      string.concat(["&", "FeatureName", "=", uri.encode_component(v)]),
    ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_add_role_to_db_instance_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(AddRoleToDBInstanceOutput, String) {
  Ok(AddRoleToDBInstanceOutput)
}

pub type AddSourceIdentifierToSubscriptionInput {
  AddSourceIdentifierToSubscriptionInput(
    subscription_name: String,
    source_identifier: String,
  )
}

pub fn add_source_identifier_to_subscription_input_default(
  subscription_name subscription_name: String,
  source_identifier source_identifier: String,
) -> AddSourceIdentifierToSubscriptionInput {
  AddSourceIdentifierToSubscriptionInput(
    subscription_name: subscription_name,
    source_identifier: source_identifier,
  )
}

pub type AddSourceIdentifierToSubscriptionOutput {
  AddSourceIdentifierToSubscriptionOutput
}

pub fn decode_add_source_identifier_to_subscription_input_struct() -> decode.Decoder(
  AddSourceIdentifierToSubscriptionInput,
) {
  use <- decode.recursive
  use subscription_name <- decode.field("SubscriptionName", decode.string)
  use source_identifier <- decode.field("SourceIdentifier", decode.string)
  decode.success(AddSourceIdentifierToSubscriptionInput(
    subscription_name: subscription_name,
    source_identifier: source_identifier,
  ))
}

pub fn decode_add_source_identifier_to_subscription_input(
  json_string: String,
) -> Result(AddSourceIdentifierToSubscriptionInput, String) {
  result.map_error(
    json.parse(
      json_string,
      decode_add_source_identifier_to_subscription_input_struct(),
    ),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_add_source_identifier_to_subscription_request(
  input: AddSourceIdentifierToSubscriptionInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=AddSourceIdentifierToSubscription&Version=2014-10-31"
  let body = {
    let v = input.subscription_name
    string.concat([
      body,
      string.concat(["&", "SubscriptionName", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.source_identifier
    string.concat([
      body,
      string.concat(["&", "SourceIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_add_source_identifier_to_subscription_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(AddSourceIdentifierToSubscriptionOutput, String) {
  Ok(AddSourceIdentifierToSubscriptionOutput)
}

pub type AddTagsToResourceInput {
  AddTagsToResourceInput(resource_name: String, tags: List(Tag))
}

pub fn add_tags_to_resource_input_default(
  resource_name resource_name: String,
  tags tags: List(Tag),
) -> AddTagsToResourceInput {
  AddTagsToResourceInput(resource_name: resource_name, tags: tags)
}

pub type AddTagsToResourceOutput {
  AddTagsToResourceOutput
}

pub fn decode_add_tags_to_resource_input_struct() -> decode.Decoder(
  AddTagsToResourceInput,
) {
  use <- decode.recursive
  use resource_name <- decode.field("ResourceName", decode.string)
  use tags <- decode.field("Tags", decode.list(decode_tag_struct_params()))
  decode.success(AddTagsToResourceInput(
    resource_name: resource_name,
    tags: tags,
  ))
}

pub fn decode_add_tags_to_resource_input(
  json_string: String,
) -> Result(AddTagsToResourceInput, String) {
  result.map_error(
    json.parse(json_string, decode_add_tags_to_resource_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_add_tags_to_resource_request(
  input: AddTagsToResourceInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=AddTagsToResource&Version=2014-10-31"
  let body = {
    let v = input.resource_name
    string.concat([
      body,
      string.concat(["&", "ResourceName", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.tags
    string.concat([
      body,
      case v {
        [] -> string.concat(["&", "Tags", "=", ""])
        _ ->
          list.index_fold(v, "", fn(acc, item, idx) {
            string.concat([
              acc,
              encode_tag_at(
                string.concat(["Tags", ".Tag.", int.to_string(idx + 1)]),
                item,
              ),
            ])
          })
      },
    ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_add_tags_to_resource_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(AddTagsToResourceOutput, String) {
  Ok(AddTagsToResourceOutput)
}

pub type ApplyPendingMaintenanceActionInput {
  ApplyPendingMaintenanceActionInput(
    resource_identifier: String,
    apply_action: String,
    opt_in_type: String,
  )
}

pub fn apply_pending_maintenance_action_input_default(
  resource_identifier resource_identifier: String,
  apply_action apply_action: String,
  opt_in_type opt_in_type: String,
) -> ApplyPendingMaintenanceActionInput {
  ApplyPendingMaintenanceActionInput(
    resource_identifier: resource_identifier,
    apply_action: apply_action,
    opt_in_type: opt_in_type,
  )
}

pub type ApplyPendingMaintenanceActionOutput {
  ApplyPendingMaintenanceActionOutput
}

pub fn decode_apply_pending_maintenance_action_input_struct() -> decode.Decoder(
  ApplyPendingMaintenanceActionInput,
) {
  use <- decode.recursive
  use resource_identifier <- decode.field("ResourceIdentifier", decode.string)
  use apply_action <- decode.field("ApplyAction", decode.string)
  use opt_in_type <- decode.field("OptInType", decode.string)
  decode.success(ApplyPendingMaintenanceActionInput(
    resource_identifier: resource_identifier,
    apply_action: apply_action,
    opt_in_type: opt_in_type,
  ))
}

pub fn decode_apply_pending_maintenance_action_input(
  json_string: String,
) -> Result(ApplyPendingMaintenanceActionInput, String) {
  result.map_error(
    json.parse(
      json_string,
      decode_apply_pending_maintenance_action_input_struct(),
    ),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_apply_pending_maintenance_action_request(
  input: ApplyPendingMaintenanceActionInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=ApplyPendingMaintenanceAction&Version=2014-10-31"
  let body = {
    let v = input.resource_identifier
    string.concat([
      body,
      string.concat(["&", "ResourceIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.apply_action
    string.concat([
      body,
      string.concat(["&", "ApplyAction", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.opt_in_type
    string.concat([
      body,
      string.concat(["&", "OptInType", "=", uri.encode_component(v)]),
    ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_apply_pending_maintenance_action_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(ApplyPendingMaintenanceActionOutput, String) {
  Ok(ApplyPendingMaintenanceActionOutput)
}

pub type AuthorizeDBSecurityGroupIngressInput {
  AuthorizeDBSecurityGroupIngressInput(
    db_security_group_name: String,
    cidrip: option.Option(String),
    ec2_security_group_name: option.Option(String),
    ec2_security_group_id: option.Option(String),
    ec2_security_group_owner_id: option.Option(String),
  )
}

pub fn authorize_db_security_group_ingress_input_default(
  db_security_group_name db_security_group_name: String,
) -> AuthorizeDBSecurityGroupIngressInput {
  AuthorizeDBSecurityGroupIngressInput(
    db_security_group_name: db_security_group_name,
    cidrip: option.None,
    ec2_security_group_name: option.None,
    ec2_security_group_id: option.None,
    ec2_security_group_owner_id: option.None,
  )
}

pub type AuthorizeDBSecurityGroupIngressOutput {
  AuthorizeDBSecurityGroupIngressOutput
}

pub fn decode_authorize_db_security_group_ingress_input_struct() -> decode.Decoder(
  AuthorizeDBSecurityGroupIngressInput,
) {
  use <- decode.recursive
  use db_security_group_name <- decode.field(
    "DBSecurityGroupName",
    decode.string,
  )
  use cidrip <- decode.optional_field(
    "CIDRIP",
    option.None,
    decode.optional(decode.string),
  )
  use ec2_security_group_name <- decode.optional_field(
    "EC2SecurityGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use ec2_security_group_id <- decode.optional_field(
    "EC2SecurityGroupId",
    option.None,
    decode.optional(decode.string),
  )
  use ec2_security_group_owner_id <- decode.optional_field(
    "EC2SecurityGroupOwnerId",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(AuthorizeDBSecurityGroupIngressInput(
    db_security_group_name: db_security_group_name,
    cidrip: cidrip,
    ec2_security_group_name: ec2_security_group_name,
    ec2_security_group_id: ec2_security_group_id,
    ec2_security_group_owner_id: ec2_security_group_owner_id,
  ))
}

pub fn decode_authorize_db_security_group_ingress_input(
  json_string: String,
) -> Result(AuthorizeDBSecurityGroupIngressInput, String) {
  result.map_error(
    json.parse(
      json_string,
      decode_authorize_db_security_group_ingress_input_struct(),
    ),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_authorize_db_security_group_ingress_request(
  input: AuthorizeDBSecurityGroupIngressInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=AuthorizeDBSecurityGroupIngress&Version=2014-10-31"
  let body = {
    let v = input.db_security_group_name
    string.concat([
      body,
      string.concat(["&", "DBSecurityGroupName", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.cidrip {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "CIDRIP", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.ec2_security_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EC2SecurityGroupName",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.ec2_security_group_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "EC2SecurityGroupId", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.ec2_security_group_owner_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EC2SecurityGroupOwnerId",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_authorize_db_security_group_ingress_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(AuthorizeDBSecurityGroupIngressOutput, String) {
  Ok(AuthorizeDBSecurityGroupIngressOutput)
}

pub type BacktrackDBClusterInput {
  BacktrackDBClusterInput(
    db_cluster_identifier: String,
    backtrack_to: json_timestamp.Timestamp,
    force: option.Option(Bool),
    use_earliest_time_on_point_in_time_unavailable: option.Option(Bool),
  )
}

pub fn backtrack_db_cluster_input_default(
  db_cluster_identifier db_cluster_identifier: String,
  backtrack_to backtrack_to: json_timestamp.Timestamp,
) -> BacktrackDBClusterInput {
  BacktrackDBClusterInput(
    db_cluster_identifier: db_cluster_identifier,
    backtrack_to: backtrack_to,
    force: option.None,
    use_earliest_time_on_point_in_time_unavailable: option.None,
  )
}

pub type BacktrackDBClusterOutput {
  BacktrackDBClusterOutput
}

pub fn decode_backtrack_db_cluster_input_struct() -> decode.Decoder(
  BacktrackDBClusterInput,
) {
  use <- decode.recursive
  use db_cluster_identifier <- decode.field(
    "DBClusterIdentifier",
    decode.string,
  )
  use backtrack_to <- decode.field(
    "BacktrackTo",
    json_timestamp.decoder_precise(),
  )
  use force <- decode.optional_field(
    "Force",
    option.None,
    decode.optional(decode.bool),
  )
  use use_earliest_time_on_point_in_time_unavailable <- decode.optional_field(
    "UseEarliestTimeOnPointInTimeUnavailable",
    option.None,
    decode.optional(decode.bool),
  )
  decode.success(BacktrackDBClusterInput(
    db_cluster_identifier: db_cluster_identifier,
    backtrack_to: backtrack_to,
    force: force,
    use_earliest_time_on_point_in_time_unavailable: use_earliest_time_on_point_in_time_unavailable,
  ))
}

pub fn decode_backtrack_db_cluster_input(
  json_string: String,
) -> Result(BacktrackDBClusterInput, String) {
  result.map_error(
    json.parse(json_string, decode_backtrack_db_cluster_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_backtrack_db_cluster_request(
  input: BacktrackDBClusterInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=BacktrackDBCluster&Version=2014-10-31"
  let body = {
    let v = input.db_cluster_identifier
    string.concat([
      body,
      string.concat(["&", "DBClusterIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.backtrack_to
    string.concat([
      body,
      string.concat([
        "&",
        "BacktrackTo",
        "=",
        uri.encode_component(json_timestamp.format_iso8601_precise(v)),
      ]),
    ])
  }
  let body = case input.force {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "Force",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.use_earliest_time_on_point_in_time_unavailable {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "UseEarliestTimeOnPointInTimeUnavailable",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_backtrack_db_cluster_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(BacktrackDBClusterOutput, String) {
  Ok(BacktrackDBClusterOutput)
}

pub type CancelExportTaskInput {
  CancelExportTaskInput(export_task_identifier: String)
}

pub fn cancel_export_task_input_default(
  export_task_identifier export_task_identifier: String,
) -> CancelExportTaskInput {
  CancelExportTaskInput(export_task_identifier: export_task_identifier)
}

pub type CancelExportTaskOutput {
  CancelExportTaskOutput
}

pub fn decode_cancel_export_task_input_struct() -> decode.Decoder(
  CancelExportTaskInput,
) {
  use <- decode.recursive
  use export_task_identifier <- decode.field(
    "ExportTaskIdentifier",
    decode.string,
  )
  decode.success(CancelExportTaskInput(
    export_task_identifier: export_task_identifier,
  ))
}

pub fn decode_cancel_export_task_input(
  json_string: String,
) -> Result(CancelExportTaskInput, String) {
  result.map_error(
    json.parse(json_string, decode_cancel_export_task_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_cancel_export_task_request(
  input: CancelExportTaskInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=CancelExportTask&Version=2014-10-31"
  let body = {
    let v = input.export_task_identifier
    string.concat([
      body,
      string.concat(["&", "ExportTaskIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_cancel_export_task_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(CancelExportTaskOutput, String) {
  Ok(CancelExportTaskOutput)
}

pub type CopyDBClusterParameterGroupInput {
  CopyDBClusterParameterGroupInput(
    source_db_cluster_parameter_group_identifier: String,
    target_db_cluster_parameter_group_identifier: String,
    target_db_cluster_parameter_group_description: String,
    tags: option.Option(List(Tag)),
  )
}

pub fn copy_db_cluster_parameter_group_input_default(
  source_db_cluster_parameter_group_identifier source_db_cluster_parameter_group_identifier: String,
  target_db_cluster_parameter_group_identifier target_db_cluster_parameter_group_identifier: String,
  target_db_cluster_parameter_group_description target_db_cluster_parameter_group_description: String,
) -> CopyDBClusterParameterGroupInput {
  CopyDBClusterParameterGroupInput(
    source_db_cluster_parameter_group_identifier: source_db_cluster_parameter_group_identifier,
    target_db_cluster_parameter_group_identifier: target_db_cluster_parameter_group_identifier,
    target_db_cluster_parameter_group_description: target_db_cluster_parameter_group_description,
    tags: option.None,
  )
}

pub type CopyDBClusterParameterGroupOutput {
  CopyDBClusterParameterGroupOutput
}

pub fn decode_copy_db_cluster_parameter_group_input_struct() -> decode.Decoder(
  CopyDBClusterParameterGroupInput,
) {
  use <- decode.recursive
  use source_db_cluster_parameter_group_identifier <- decode.field(
    "SourceDBClusterParameterGroupIdentifier",
    decode.string,
  )
  use target_db_cluster_parameter_group_identifier <- decode.field(
    "TargetDBClusterParameterGroupIdentifier",
    decode.string,
  )
  use target_db_cluster_parameter_group_description <- decode.field(
    "TargetDBClusterParameterGroupDescription",
    decode.string,
  )
  use tags <- decode.optional_field(
    "Tags",
    option.None,
    decode.optional(decode.list(decode_tag_struct_params())),
  )
  decode.success(CopyDBClusterParameterGroupInput(
    source_db_cluster_parameter_group_identifier: source_db_cluster_parameter_group_identifier,
    target_db_cluster_parameter_group_identifier: target_db_cluster_parameter_group_identifier,
    target_db_cluster_parameter_group_description: target_db_cluster_parameter_group_description,
    tags: tags,
  ))
}

pub fn decode_copy_db_cluster_parameter_group_input(
  json_string: String,
) -> Result(CopyDBClusterParameterGroupInput, String) {
  result.map_error(
    json.parse(
      json_string,
      decode_copy_db_cluster_parameter_group_input_struct(),
    ),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_copy_db_cluster_parameter_group_request(
  input: CopyDBClusterParameterGroupInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=CopyDBClusterParameterGroup&Version=2014-10-31"
  let body = {
    let v = input.source_db_cluster_parameter_group_identifier
    string.concat([
      body,
      string.concat([
        "&",
        "SourceDBClusterParameterGroupIdentifier",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body = {
    let v = input.target_db_cluster_parameter_group_identifier
    string.concat([
      body,
      string.concat([
        "&",
        "TargetDBClusterParameterGroupIdentifier",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body = {
    let v = input.target_db_cluster_parameter_group_description
    string.concat([
      body,
      string.concat([
        "&",
        "TargetDBClusterParameterGroupDescription",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body = case input.tags {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Tags", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_tag_at(
                  string.concat(["Tags", ".Tag.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_copy_db_cluster_parameter_group_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(CopyDBClusterParameterGroupOutput, String) {
  Ok(CopyDBClusterParameterGroupOutput)
}

pub type CopyDBClusterSnapshotInput {
  CopyDBClusterSnapshotInput(
    source_db_cluster_snapshot_identifier: String,
    target_db_cluster_snapshot_identifier: String,
    kms_key_id: option.Option(String),
    pre_signed_url: option.Option(String),
    copy_tags: option.Option(Bool),
    tags: option.Option(List(Tag)),
  )
}

pub fn copy_db_cluster_snapshot_input_default(
  source_db_cluster_snapshot_identifier source_db_cluster_snapshot_identifier: String,
  target_db_cluster_snapshot_identifier target_db_cluster_snapshot_identifier: String,
) -> CopyDBClusterSnapshotInput {
  CopyDBClusterSnapshotInput(
    source_db_cluster_snapshot_identifier: source_db_cluster_snapshot_identifier,
    target_db_cluster_snapshot_identifier: target_db_cluster_snapshot_identifier,
    kms_key_id: option.None,
    pre_signed_url: option.None,
    copy_tags: option.None,
    tags: option.None,
  )
}

pub type CopyDBClusterSnapshotOutput {
  CopyDBClusterSnapshotOutput
}

pub fn decode_copy_db_cluster_snapshot_input_struct() -> decode.Decoder(
  CopyDBClusterSnapshotInput,
) {
  use <- decode.recursive
  use source_db_cluster_snapshot_identifier <- decode.field(
    "SourceDBClusterSnapshotIdentifier",
    decode.string,
  )
  use target_db_cluster_snapshot_identifier <- decode.field(
    "TargetDBClusterSnapshotIdentifier",
    decode.string,
  )
  use kms_key_id <- decode.optional_field(
    "KmsKeyId",
    option.None,
    decode.optional(decode.string),
  )
  use pre_signed_url <- decode.optional_field(
    "PreSignedUrl",
    option.None,
    decode.optional(decode.string),
  )
  use copy_tags <- decode.optional_field(
    "CopyTags",
    option.None,
    decode.optional(decode.bool),
  )
  use tags <- decode.optional_field(
    "Tags",
    option.None,
    decode.optional(decode.list(decode_tag_struct_params())),
  )
  decode.success(CopyDBClusterSnapshotInput(
    source_db_cluster_snapshot_identifier: source_db_cluster_snapshot_identifier,
    target_db_cluster_snapshot_identifier: target_db_cluster_snapshot_identifier,
    kms_key_id: kms_key_id,
    pre_signed_url: pre_signed_url,
    copy_tags: copy_tags,
    tags: tags,
  ))
}

pub fn decode_copy_db_cluster_snapshot_input(
  json_string: String,
) -> Result(CopyDBClusterSnapshotInput, String) {
  result.map_error(
    json.parse(json_string, decode_copy_db_cluster_snapshot_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_copy_db_cluster_snapshot_request(
  input: CopyDBClusterSnapshotInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=CopyDBClusterSnapshot&Version=2014-10-31"
  let body = {
    let v = input.source_db_cluster_snapshot_identifier
    string.concat([
      body,
      string.concat([
        "&",
        "SourceDBClusterSnapshotIdentifier",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body = {
    let v = input.target_db_cluster_snapshot_identifier
    string.concat([
      body,
      string.concat([
        "&",
        "TargetDBClusterSnapshotIdentifier",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body = case input.kms_key_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "KmsKeyId", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.pre_signed_url {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "PreSignedUrl", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.copy_tags {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "CopyTags",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.tags {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Tags", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_tag_at(
                  string.concat(["Tags", ".Tag.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_copy_db_cluster_snapshot_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(CopyDBClusterSnapshotOutput, String) {
  Ok(CopyDBClusterSnapshotOutput)
}

pub type CopyDBParameterGroupInput {
  CopyDBParameterGroupInput(
    source_db_parameter_group_identifier: String,
    target_db_parameter_group_identifier: String,
    target_db_parameter_group_description: String,
    tags: option.Option(List(Tag)),
  )
}

pub fn copy_db_parameter_group_input_default(
  source_db_parameter_group_identifier source_db_parameter_group_identifier: String,
  target_db_parameter_group_identifier target_db_parameter_group_identifier: String,
  target_db_parameter_group_description target_db_parameter_group_description: String,
) -> CopyDBParameterGroupInput {
  CopyDBParameterGroupInput(
    source_db_parameter_group_identifier: source_db_parameter_group_identifier,
    target_db_parameter_group_identifier: target_db_parameter_group_identifier,
    target_db_parameter_group_description: target_db_parameter_group_description,
    tags: option.None,
  )
}

pub type CopyDBParameterGroupOutput {
  CopyDBParameterGroupOutput
}

pub fn decode_copy_db_parameter_group_input_struct() -> decode.Decoder(
  CopyDBParameterGroupInput,
) {
  use <- decode.recursive
  use source_db_parameter_group_identifier <- decode.field(
    "SourceDBParameterGroupIdentifier",
    decode.string,
  )
  use target_db_parameter_group_identifier <- decode.field(
    "TargetDBParameterGroupIdentifier",
    decode.string,
  )
  use target_db_parameter_group_description <- decode.field(
    "TargetDBParameterGroupDescription",
    decode.string,
  )
  use tags <- decode.optional_field(
    "Tags",
    option.None,
    decode.optional(decode.list(decode_tag_struct_params())),
  )
  decode.success(CopyDBParameterGroupInput(
    source_db_parameter_group_identifier: source_db_parameter_group_identifier,
    target_db_parameter_group_identifier: target_db_parameter_group_identifier,
    target_db_parameter_group_description: target_db_parameter_group_description,
    tags: tags,
  ))
}

pub fn decode_copy_db_parameter_group_input(
  json_string: String,
) -> Result(CopyDBParameterGroupInput, String) {
  result.map_error(
    json.parse(json_string, decode_copy_db_parameter_group_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_copy_db_parameter_group_request(
  input: CopyDBParameterGroupInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=CopyDBParameterGroup&Version=2014-10-31"
  let body = {
    let v = input.source_db_parameter_group_identifier
    string.concat([
      body,
      string.concat([
        "&",
        "SourceDBParameterGroupIdentifier",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body = {
    let v = input.target_db_parameter_group_identifier
    string.concat([
      body,
      string.concat([
        "&",
        "TargetDBParameterGroupIdentifier",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body = {
    let v = input.target_db_parameter_group_description
    string.concat([
      body,
      string.concat([
        "&",
        "TargetDBParameterGroupDescription",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body = case input.tags {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Tags", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_tag_at(
                  string.concat(["Tags", ".Tag.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_copy_db_parameter_group_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(CopyDBParameterGroupOutput, String) {
  Ok(CopyDBParameterGroupOutput)
}

pub type CopyDBSnapshotInput {
  CopyDBSnapshotInput(
    source_db_snapshot_identifier: String,
    target_db_snapshot_identifier: String,
    kms_key_id: option.Option(String),
    tags: option.Option(List(Tag)),
    copy_tags: option.Option(Bool),
    pre_signed_url: option.Option(String),
    option_group_name: option.Option(String),
    target_custom_availability_zone: option.Option(String),
    snapshot_target: option.Option(String),
    copy_option_group: option.Option(Bool),
    snapshot_availability_zone: option.Option(String),
  )
}

pub fn copy_db_snapshot_input_default(
  source_db_snapshot_identifier source_db_snapshot_identifier: String,
  target_db_snapshot_identifier target_db_snapshot_identifier: String,
) -> CopyDBSnapshotInput {
  CopyDBSnapshotInput(
    source_db_snapshot_identifier: source_db_snapshot_identifier,
    target_db_snapshot_identifier: target_db_snapshot_identifier,
    kms_key_id: option.None,
    tags: option.None,
    copy_tags: option.None,
    pre_signed_url: option.None,
    option_group_name: option.None,
    target_custom_availability_zone: option.None,
    snapshot_target: option.None,
    copy_option_group: option.None,
    snapshot_availability_zone: option.None,
  )
}

pub type CopyDBSnapshotOutput {
  CopyDBSnapshotOutput
}

pub fn decode_copy_db_snapshot_input_struct() -> decode.Decoder(
  CopyDBSnapshotInput,
) {
  use <- decode.recursive
  use source_db_snapshot_identifier <- decode.field(
    "SourceDBSnapshotIdentifier",
    decode.string,
  )
  use target_db_snapshot_identifier <- decode.field(
    "TargetDBSnapshotIdentifier",
    decode.string,
  )
  use kms_key_id <- decode.optional_field(
    "KmsKeyId",
    option.None,
    decode.optional(decode.string),
  )
  use tags <- decode.optional_field(
    "Tags",
    option.None,
    decode.optional(decode.list(decode_tag_struct_params())),
  )
  use copy_tags <- decode.optional_field(
    "CopyTags",
    option.None,
    decode.optional(decode.bool),
  )
  use pre_signed_url <- decode.optional_field(
    "PreSignedUrl",
    option.None,
    decode.optional(decode.string),
  )
  use option_group_name <- decode.optional_field(
    "OptionGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use target_custom_availability_zone <- decode.optional_field(
    "TargetCustomAvailabilityZone",
    option.None,
    decode.optional(decode.string),
  )
  use snapshot_target <- decode.optional_field(
    "SnapshotTarget",
    option.None,
    decode.optional(decode.string),
  )
  use copy_option_group <- decode.optional_field(
    "CopyOptionGroup",
    option.None,
    decode.optional(decode.bool),
  )
  use snapshot_availability_zone <- decode.optional_field(
    "SnapshotAvailabilityZone",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(CopyDBSnapshotInput(
    source_db_snapshot_identifier: source_db_snapshot_identifier,
    target_db_snapshot_identifier: target_db_snapshot_identifier,
    kms_key_id: kms_key_id,
    tags: tags,
    copy_tags: copy_tags,
    pre_signed_url: pre_signed_url,
    option_group_name: option_group_name,
    target_custom_availability_zone: target_custom_availability_zone,
    snapshot_target: snapshot_target,
    copy_option_group: copy_option_group,
    snapshot_availability_zone: snapshot_availability_zone,
  ))
}

pub fn decode_copy_db_snapshot_input(
  json_string: String,
) -> Result(CopyDBSnapshotInput, String) {
  result.map_error(
    json.parse(json_string, decode_copy_db_snapshot_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_copy_db_snapshot_request(
  input: CopyDBSnapshotInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=CopyDBSnapshot&Version=2014-10-31"
  let body = {
    let v = input.source_db_snapshot_identifier
    string.concat([
      body,
      string.concat([
        "&",
        "SourceDBSnapshotIdentifier",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body = {
    let v = input.target_db_snapshot_identifier
    string.concat([
      body,
      string.concat([
        "&",
        "TargetDBSnapshotIdentifier",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body = case input.kms_key_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "KmsKeyId", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.tags {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Tags", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_tag_at(
                  string.concat(["Tags", ".Tag.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.copy_tags {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "CopyTags",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.pre_signed_url {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "PreSignedUrl", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.option_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "OptionGroupName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.target_custom_availability_zone {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "TargetCustomAvailabilityZone",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.snapshot_target {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "SnapshotTarget", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.copy_option_group {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "CopyOptionGroup",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.snapshot_availability_zone {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "SnapshotAvailabilityZone",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_copy_db_snapshot_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(CopyDBSnapshotOutput, String) {
  Ok(CopyDBSnapshotOutput)
}

pub type CopyOptionGroupInput {
  CopyOptionGroupInput(
    source_option_group_identifier: String,
    target_option_group_identifier: String,
    target_option_group_description: String,
    tags: option.Option(List(Tag)),
  )
}

pub fn copy_option_group_input_default(
  source_option_group_identifier source_option_group_identifier: String,
  target_option_group_identifier target_option_group_identifier: String,
  target_option_group_description target_option_group_description: String,
) -> CopyOptionGroupInput {
  CopyOptionGroupInput(
    source_option_group_identifier: source_option_group_identifier,
    target_option_group_identifier: target_option_group_identifier,
    target_option_group_description: target_option_group_description,
    tags: option.None,
  )
}

pub type CopyOptionGroupOutput {
  CopyOptionGroupOutput
}

pub fn decode_copy_option_group_input_struct() -> decode.Decoder(
  CopyOptionGroupInput,
) {
  use <- decode.recursive
  use source_option_group_identifier <- decode.field(
    "SourceOptionGroupIdentifier",
    decode.string,
  )
  use target_option_group_identifier <- decode.field(
    "TargetOptionGroupIdentifier",
    decode.string,
  )
  use target_option_group_description <- decode.field(
    "TargetOptionGroupDescription",
    decode.string,
  )
  use tags <- decode.optional_field(
    "Tags",
    option.None,
    decode.optional(decode.list(decode_tag_struct_params())),
  )
  decode.success(CopyOptionGroupInput(
    source_option_group_identifier: source_option_group_identifier,
    target_option_group_identifier: target_option_group_identifier,
    target_option_group_description: target_option_group_description,
    tags: tags,
  ))
}

pub fn decode_copy_option_group_input(
  json_string: String,
) -> Result(CopyOptionGroupInput, String) {
  result.map_error(
    json.parse(json_string, decode_copy_option_group_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_copy_option_group_request(
  input: CopyOptionGroupInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=CopyOptionGroup&Version=2014-10-31"
  let body = {
    let v = input.source_option_group_identifier
    string.concat([
      body,
      string.concat([
        "&",
        "SourceOptionGroupIdentifier",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body = {
    let v = input.target_option_group_identifier
    string.concat([
      body,
      string.concat([
        "&",
        "TargetOptionGroupIdentifier",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body = {
    let v = input.target_option_group_description
    string.concat([
      body,
      string.concat([
        "&",
        "TargetOptionGroupDescription",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body = case input.tags {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Tags", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_tag_at(
                  string.concat(["Tags", ".Tag.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_copy_option_group_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(CopyOptionGroupOutput, String) {
  Ok(CopyOptionGroupOutput)
}

pub type CreateBlueGreenDeploymentInput {
  CreateBlueGreenDeploymentInput(
    blue_green_deployment_name: String,
    source: String,
    target_engine_version: option.Option(String),
    target_db_parameter_group_name: option.Option(String),
    target_db_cluster_parameter_group_name: option.Option(String),
    tags: option.Option(List(Tag)),
    target_db_instance_class: option.Option(String),
    upgrade_target_storage_config: option.Option(Bool),
    target_iops: option.Option(Int),
    target_storage_type: option.Option(String),
    target_allocated_storage: option.Option(Int),
    target_storage_throughput: option.Option(Int),
  )
}

pub fn create_blue_green_deployment_input_default(
  blue_green_deployment_name blue_green_deployment_name: String,
  source source: String,
) -> CreateBlueGreenDeploymentInput {
  CreateBlueGreenDeploymentInput(
    blue_green_deployment_name: blue_green_deployment_name,
    source: source,
    target_engine_version: option.None,
    target_db_parameter_group_name: option.None,
    target_db_cluster_parameter_group_name: option.None,
    tags: option.None,
    target_db_instance_class: option.None,
    upgrade_target_storage_config: option.None,
    target_iops: option.None,
    target_storage_type: option.None,
    target_allocated_storage: option.None,
    target_storage_throughput: option.None,
  )
}

pub type CreateBlueGreenDeploymentOutput {
  CreateBlueGreenDeploymentOutput
}

pub fn decode_create_blue_green_deployment_input_struct() -> decode.Decoder(
  CreateBlueGreenDeploymentInput,
) {
  use <- decode.recursive
  use blue_green_deployment_name <- decode.field(
    "BlueGreenDeploymentName",
    decode.string,
  )
  use source <- decode.field("Source", decode.string)
  use target_engine_version <- decode.optional_field(
    "TargetEngineVersion",
    option.None,
    decode.optional(decode.string),
  )
  use target_db_parameter_group_name <- decode.optional_field(
    "TargetDBParameterGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use target_db_cluster_parameter_group_name <- decode.optional_field(
    "TargetDBClusterParameterGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use tags <- decode.optional_field(
    "Tags",
    option.None,
    decode.optional(decode.list(decode_tag_struct_params())),
  )
  use target_db_instance_class <- decode.optional_field(
    "TargetDBInstanceClass",
    option.None,
    decode.optional(decode.string),
  )
  use upgrade_target_storage_config <- decode.optional_field(
    "UpgradeTargetStorageConfig",
    option.None,
    decode.optional(decode.bool),
  )
  use target_iops <- decode.optional_field(
    "TargetIops",
    option.None,
    decode.optional(decode.int),
  )
  use target_storage_type <- decode.optional_field(
    "TargetStorageType",
    option.None,
    decode.optional(decode.string),
  )
  use target_allocated_storage <- decode.optional_field(
    "TargetAllocatedStorage",
    option.None,
    decode.optional(decode.int),
  )
  use target_storage_throughput <- decode.optional_field(
    "TargetStorageThroughput",
    option.None,
    decode.optional(decode.int),
  )
  decode.success(CreateBlueGreenDeploymentInput(
    blue_green_deployment_name: blue_green_deployment_name,
    source: source,
    target_engine_version: target_engine_version,
    target_db_parameter_group_name: target_db_parameter_group_name,
    target_db_cluster_parameter_group_name: target_db_cluster_parameter_group_name,
    tags: tags,
    target_db_instance_class: target_db_instance_class,
    upgrade_target_storage_config: upgrade_target_storage_config,
    target_iops: target_iops,
    target_storage_type: target_storage_type,
    target_allocated_storage: target_allocated_storage,
    target_storage_throughput: target_storage_throughput,
  ))
}

pub fn decode_create_blue_green_deployment_input(
  json_string: String,
) -> Result(CreateBlueGreenDeploymentInput, String) {
  result.map_error(
    json.parse(json_string, decode_create_blue_green_deployment_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_create_blue_green_deployment_request(
  input: CreateBlueGreenDeploymentInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=CreateBlueGreenDeployment&Version=2014-10-31"
  let body = {
    let v = input.blue_green_deployment_name
    string.concat([
      body,
      string.concat([
        "&",
        "BlueGreenDeploymentName",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body = {
    let v = input.source
    string.concat([
      body,
      string.concat(["&", "Source", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.target_engine_version {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "TargetEngineVersion", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.target_db_parameter_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "TargetDBParameterGroupName",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.target_db_cluster_parameter_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "TargetDBClusterParameterGroupName",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.tags {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Tags", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_tag_at(
                  string.concat(["Tags", ".Tag.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.target_db_instance_class {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "TargetDBInstanceClass",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.upgrade_target_storage_config {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "UpgradeTargetStorageConfig",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.target_iops {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "TargetIops", "=", int.to_string(v)]),
      ])
  }
  let body = case input.target_storage_type {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "TargetStorageType", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.target_allocated_storage {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "TargetAllocatedStorage", "=", int.to_string(v)]),
      ])
  }
  let body = case input.target_storage_throughput {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "TargetStorageThroughput", "=", int.to_string(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_create_blue_green_deployment_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(CreateBlueGreenDeploymentOutput, String) {
  Ok(CreateBlueGreenDeploymentOutput)
}

pub type CreateCustomDBEngineVersionInput {
  CreateCustomDBEngineVersionInput(
    engine: String,
    engine_version: String,
    database_installation_files_s3_bucket_name: option.Option(String),
    database_installation_files_s3_prefix: option.Option(String),
    database_installation_files: option.Option(List(String)),
    image_id: option.Option(String),
    kms_key_id: option.Option(String),
    source_custom_db_engine_version_identifier: option.Option(String),
    use_aws_provided_latest_image: option.Option(Bool),
    description: option.Option(String),
    manifest: option.Option(String),
    tags: option.Option(List(Tag)),
  )
}

pub fn create_custom_db_engine_version_input_default(
  engine engine: String,
  engine_version engine_version: String,
) -> CreateCustomDBEngineVersionInput {
  CreateCustomDBEngineVersionInput(
    engine: engine,
    engine_version: engine_version,
    database_installation_files_s3_bucket_name: option.None,
    database_installation_files_s3_prefix: option.None,
    database_installation_files: option.None,
    image_id: option.None,
    kms_key_id: option.None,
    source_custom_db_engine_version_identifier: option.None,
    use_aws_provided_latest_image: option.None,
    description: option.None,
    manifest: option.None,
    tags: option.None,
  )
}

pub type CreateCustomDBEngineVersionOutput {
  CreateCustomDBEngineVersionOutput
}

pub fn decode_create_custom_db_engine_version_input_struct() -> decode.Decoder(
  CreateCustomDBEngineVersionInput,
) {
  use <- decode.recursive
  use engine <- decode.field("Engine", decode.string)
  use engine_version <- decode.field("EngineVersion", decode.string)
  use database_installation_files_s3_bucket_name <- decode.optional_field(
    "DatabaseInstallationFilesS3BucketName",
    option.None,
    decode.optional(decode.string),
  )
  use database_installation_files_s3_prefix <- decode.optional_field(
    "DatabaseInstallationFilesS3Prefix",
    option.None,
    decode.optional(decode.string),
  )
  use database_installation_files <- decode.optional_field(
    "DatabaseInstallationFiles",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use image_id <- decode.optional_field(
    "ImageId",
    option.None,
    decode.optional(decode.string),
  )
  use kms_key_id <- decode.optional_field(
    "KMSKeyId",
    option.None,
    decode.optional(decode.string),
  )
  use source_custom_db_engine_version_identifier <- decode.optional_field(
    "SourceCustomDbEngineVersionIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use use_aws_provided_latest_image <- decode.optional_field(
    "UseAwsProvidedLatestImage",
    option.None,
    decode.optional(decode.bool),
  )
  use description <- decode.optional_field(
    "Description",
    option.None,
    decode.optional(decode.string),
  )
  use manifest <- decode.optional_field(
    "Manifest",
    option.None,
    decode.optional(decode.string),
  )
  use tags <- decode.optional_field(
    "Tags",
    option.None,
    decode.optional(decode.list(decode_tag_struct_params())),
  )
  decode.success(CreateCustomDBEngineVersionInput(
    engine: engine,
    engine_version: engine_version,
    database_installation_files_s3_bucket_name: database_installation_files_s3_bucket_name,
    database_installation_files_s3_prefix: database_installation_files_s3_prefix,
    database_installation_files: database_installation_files,
    image_id: image_id,
    kms_key_id: kms_key_id,
    source_custom_db_engine_version_identifier: source_custom_db_engine_version_identifier,
    use_aws_provided_latest_image: use_aws_provided_latest_image,
    description: description,
    manifest: manifest,
    tags: tags,
  ))
}

pub fn decode_create_custom_db_engine_version_input(
  json_string: String,
) -> Result(CreateCustomDBEngineVersionInput, String) {
  result.map_error(
    json.parse(
      json_string,
      decode_create_custom_db_engine_version_input_struct(),
    ),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_create_custom_db_engine_version_request(
  input: CreateCustomDBEngineVersionInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=CreateCustomDBEngineVersion&Version=2014-10-31"
  let body = {
    let v = input.engine
    string.concat([
      body,
      string.concat(["&", "Engine", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.engine_version
    string.concat([
      body,
      string.concat(["&", "EngineVersion", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.database_installation_files_s3_bucket_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DatabaseInstallationFilesS3BucketName",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.database_installation_files_s3_prefix {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DatabaseInstallationFilesS3Prefix",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.database_installation_files {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "DatabaseInstallationFiles", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "DatabaseInstallationFiles",
                    ".member.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body = case input.image_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "ImageId", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.kms_key_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "KMSKeyId", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.source_custom_db_engine_version_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "SourceCustomDbEngineVersionIdentifier",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.use_aws_provided_latest_image {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "UseAwsProvidedLatestImage",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.description {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Description", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.manifest {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Manifest", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.tags {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Tags", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_tag_at(
                  string.concat(["Tags", ".Tag.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_create_custom_db_engine_version_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(CreateCustomDBEngineVersionOutput, String) {
  Ok(CreateCustomDBEngineVersionOutput)
}

pub type CreateDBClusterInput {
  CreateDBClusterInput(
    availability_zones: option.Option(List(String)),
    backup_retention_period: option.Option(Int),
    character_set_name: option.Option(String),
    database_name: option.Option(String),
    db_cluster_identifier: String,
    db_cluster_parameter_group_name: option.Option(String),
    vpc_security_group_ids: option.Option(List(String)),
    db_subnet_group_name: option.Option(String),
    engine: String,
    engine_version: option.Option(String),
    port: option.Option(Int),
    master_username: option.Option(String),
    master_user_password: option.Option(String),
    option_group_name: option.Option(String),
    preferred_backup_window: option.Option(String),
    preferred_maintenance_window: option.Option(String),
    replication_source_identifier: option.Option(String),
    tags: option.Option(List(Tag)),
    storage_encrypted: option.Option(Bool),
    kms_key_id: option.Option(String),
    pre_signed_url: option.Option(String),
    enable_iam_database_authentication: option.Option(Bool),
    backtrack_window: option.Option(Int),
    enable_cloudwatch_logs_exports: option.Option(List(String)),
    engine_mode: option.Option(String),
    scaling_configuration: option.Option(ScalingConfiguration),
    rds_custom_cluster_configuration: option.Option(
      RdsCustomClusterConfiguration,
    ),
    db_cluster_instance_class: option.Option(String),
    allocated_storage: option.Option(Int),
    storage_type: option.Option(String),
    iops: option.Option(Int),
    publicly_accessible: option.Option(Bool),
    auto_minor_version_upgrade: option.Option(Bool),
    deletion_protection: option.Option(Bool),
    global_cluster_identifier: option.Option(String),
    enable_http_endpoint: option.Option(Bool),
    copy_tags_to_snapshot: option.Option(Bool),
    domain: option.Option(String),
    domain_iam_role_name: option.Option(String),
    enable_global_write_forwarding: option.Option(Bool),
    network_type: option.Option(String),
    serverless_v2_scaling_configuration: option.Option(
      ServerlessV2ScalingConfiguration,
    ),
    monitoring_interval: option.Option(Int),
    monitoring_role_arn: option.Option(String),
    database_insights_mode: option.Option(DatabaseInsightsMode),
    enable_performance_insights: option.Option(Bool),
    performance_insights_kms_key_id: option.Option(String),
    performance_insights_retention_period: option.Option(Int),
    enable_limitless_database: option.Option(Bool),
    cluster_scalability_type: option.Option(ClusterScalabilityType),
    db_system_id: option.Option(String),
    manage_master_user_password: option.Option(Bool),
    enable_local_write_forwarding: option.Option(Bool),
    master_user_secret_kms_key_id: option.Option(String),
    ca_certificate_identifier: option.Option(String),
    engine_lifecycle_support: option.Option(String),
    tag_specifications: option.Option(List(TagSpecification)),
    master_user_authentication_type: option.Option(MasterUserAuthenticationType),
    with_express_configuration: option.Option(Bool),
  )
}

pub fn create_db_cluster_input_default(
  db_cluster_identifier db_cluster_identifier: String,
  engine engine: String,
) -> CreateDBClusterInput {
  CreateDBClusterInput(
    availability_zones: option.None,
    backup_retention_period: option.None,
    character_set_name: option.None,
    database_name: option.None,
    db_cluster_identifier: db_cluster_identifier,
    db_cluster_parameter_group_name: option.None,
    vpc_security_group_ids: option.None,
    db_subnet_group_name: option.None,
    engine: engine,
    engine_version: option.None,
    port: option.None,
    master_username: option.None,
    master_user_password: option.None,
    option_group_name: option.None,
    preferred_backup_window: option.None,
    preferred_maintenance_window: option.None,
    replication_source_identifier: option.None,
    tags: option.None,
    storage_encrypted: option.None,
    kms_key_id: option.None,
    pre_signed_url: option.None,
    enable_iam_database_authentication: option.None,
    backtrack_window: option.None,
    enable_cloudwatch_logs_exports: option.None,
    engine_mode: option.None,
    scaling_configuration: option.None,
    rds_custom_cluster_configuration: option.None,
    db_cluster_instance_class: option.None,
    allocated_storage: option.None,
    storage_type: option.None,
    iops: option.None,
    publicly_accessible: option.None,
    auto_minor_version_upgrade: option.None,
    deletion_protection: option.None,
    global_cluster_identifier: option.None,
    enable_http_endpoint: option.None,
    copy_tags_to_snapshot: option.None,
    domain: option.None,
    domain_iam_role_name: option.None,
    enable_global_write_forwarding: option.None,
    network_type: option.None,
    serverless_v2_scaling_configuration: option.None,
    monitoring_interval: option.None,
    monitoring_role_arn: option.None,
    database_insights_mode: option.None,
    enable_performance_insights: option.None,
    performance_insights_kms_key_id: option.None,
    performance_insights_retention_period: option.None,
    enable_limitless_database: option.None,
    cluster_scalability_type: option.None,
    db_system_id: option.None,
    manage_master_user_password: option.None,
    enable_local_write_forwarding: option.None,
    master_user_secret_kms_key_id: option.None,
    ca_certificate_identifier: option.None,
    engine_lifecycle_support: option.None,
    tag_specifications: option.None,
    master_user_authentication_type: option.None,
    with_express_configuration: option.None,
  )
}

pub type CreateDBClusterOutput {
  CreateDBClusterOutput
}

pub fn decode_create_db_cluster_input_struct() -> decode.Decoder(
  CreateDBClusterInput,
) {
  use <- decode.recursive
  use availability_zones <- decode.optional_field(
    "AvailabilityZones",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use backup_retention_period <- decode.optional_field(
    "BackupRetentionPeriod",
    option.None,
    decode.optional(decode.int),
  )
  use character_set_name <- decode.optional_field(
    "CharacterSetName",
    option.None,
    decode.optional(decode.string),
  )
  use database_name <- decode.optional_field(
    "DatabaseName",
    option.None,
    decode.optional(decode.string),
  )
  use db_cluster_identifier <- decode.field(
    "DBClusterIdentifier",
    decode.string,
  )
  use db_cluster_parameter_group_name <- decode.optional_field(
    "DBClusterParameterGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use vpc_security_group_ids <- decode.optional_field(
    "VpcSecurityGroupIds",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use db_subnet_group_name <- decode.optional_field(
    "DBSubnetGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use engine <- decode.field("Engine", decode.string)
  use engine_version <- decode.optional_field(
    "EngineVersion",
    option.None,
    decode.optional(decode.string),
  )
  use port <- decode.optional_field(
    "Port",
    option.None,
    decode.optional(decode.int),
  )
  use master_username <- decode.optional_field(
    "MasterUsername",
    option.None,
    decode.optional(decode.string),
  )
  use master_user_password <- decode.optional_field(
    "MasterUserPassword",
    option.None,
    decode.optional(decode.string),
  )
  use option_group_name <- decode.optional_field(
    "OptionGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use preferred_backup_window <- decode.optional_field(
    "PreferredBackupWindow",
    option.None,
    decode.optional(decode.string),
  )
  use preferred_maintenance_window <- decode.optional_field(
    "PreferredMaintenanceWindow",
    option.None,
    decode.optional(decode.string),
  )
  use replication_source_identifier <- decode.optional_field(
    "ReplicationSourceIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use tags <- decode.optional_field(
    "Tags",
    option.None,
    decode.optional(decode.list(decode_tag_struct_params())),
  )
  use storage_encrypted <- decode.optional_field(
    "StorageEncrypted",
    option.None,
    decode.optional(decode.bool),
  )
  use kms_key_id <- decode.optional_field(
    "KmsKeyId",
    option.None,
    decode.optional(decode.string),
  )
  use pre_signed_url <- decode.optional_field(
    "PreSignedUrl",
    option.None,
    decode.optional(decode.string),
  )
  use enable_iam_database_authentication <- decode.optional_field(
    "EnableIAMDatabaseAuthentication",
    option.None,
    decode.optional(decode.bool),
  )
  use backtrack_window <- decode.optional_field(
    "BacktrackWindow",
    option.None,
    decode.optional(decode.int),
  )
  use enable_cloudwatch_logs_exports <- decode.optional_field(
    "EnableCloudwatchLogsExports",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use engine_mode <- decode.optional_field(
    "EngineMode",
    option.None,
    decode.optional(decode.string),
  )
  use scaling_configuration <- decode.optional_field(
    "ScalingConfiguration",
    option.None,
    decode.optional(decode_scaling_configuration_struct_params()),
  )
  use rds_custom_cluster_configuration <- decode.optional_field(
    "RdsCustomClusterConfiguration",
    option.None,
    decode.optional(decode_rds_custom_cluster_configuration_struct_params()),
  )
  use db_cluster_instance_class <- decode.optional_field(
    "DBClusterInstanceClass",
    option.None,
    decode.optional(decode.string),
  )
  use allocated_storage <- decode.optional_field(
    "AllocatedStorage",
    option.None,
    decode.optional(decode.int),
  )
  use storage_type <- decode.optional_field(
    "StorageType",
    option.None,
    decode.optional(decode.string),
  )
  use iops <- decode.optional_field(
    "Iops",
    option.None,
    decode.optional(decode.int),
  )
  use publicly_accessible <- decode.optional_field(
    "PubliclyAccessible",
    option.None,
    decode.optional(decode.bool),
  )
  use auto_minor_version_upgrade <- decode.optional_field(
    "AutoMinorVersionUpgrade",
    option.None,
    decode.optional(decode.bool),
  )
  use deletion_protection <- decode.optional_field(
    "DeletionProtection",
    option.None,
    decode.optional(decode.bool),
  )
  use global_cluster_identifier <- decode.optional_field(
    "GlobalClusterIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use enable_http_endpoint <- decode.optional_field(
    "EnableHttpEndpoint",
    option.None,
    decode.optional(decode.bool),
  )
  use copy_tags_to_snapshot <- decode.optional_field(
    "CopyTagsToSnapshot",
    option.None,
    decode.optional(decode.bool),
  )
  use domain <- decode.optional_field(
    "Domain",
    option.None,
    decode.optional(decode.string),
  )
  use domain_iam_role_name <- decode.optional_field(
    "DomainIAMRoleName",
    option.None,
    decode.optional(decode.string),
  )
  use enable_global_write_forwarding <- decode.optional_field(
    "EnableGlobalWriteForwarding",
    option.None,
    decode.optional(decode.bool),
  )
  use network_type <- decode.optional_field(
    "NetworkType",
    option.None,
    decode.optional(decode.string),
  )
  use serverless_v2_scaling_configuration <- decode.optional_field(
    "ServerlessV2ScalingConfiguration",
    option.None,
    decode.optional(decode_serverless_v2_scaling_configuration_struct_params()),
  )
  use monitoring_interval <- decode.optional_field(
    "MonitoringInterval",
    option.None,
    decode.optional(decode.int),
  )
  use monitoring_role_arn <- decode.optional_field(
    "MonitoringRoleArn",
    option.None,
    decode.optional(decode.string),
  )
  use database_insights_mode <- decode.optional_field(
    "DatabaseInsightsMode",
    option.None,
    decode.optional(decode_database_insights_mode_enum()),
  )
  use enable_performance_insights <- decode.optional_field(
    "EnablePerformanceInsights",
    option.None,
    decode.optional(decode.bool),
  )
  use performance_insights_kms_key_id <- decode.optional_field(
    "PerformanceInsightsKMSKeyId",
    option.None,
    decode.optional(decode.string),
  )
  use performance_insights_retention_period <- decode.optional_field(
    "PerformanceInsightsRetentionPeriod",
    option.None,
    decode.optional(decode.int),
  )
  use enable_limitless_database <- decode.optional_field(
    "EnableLimitlessDatabase",
    option.None,
    decode.optional(decode.bool),
  )
  use cluster_scalability_type <- decode.optional_field(
    "ClusterScalabilityType",
    option.None,
    decode.optional(decode_cluster_scalability_type_enum()),
  )
  use db_system_id <- decode.optional_field(
    "DBSystemId",
    option.None,
    decode.optional(decode.string),
  )
  use manage_master_user_password <- decode.optional_field(
    "ManageMasterUserPassword",
    option.None,
    decode.optional(decode.bool),
  )
  use enable_local_write_forwarding <- decode.optional_field(
    "EnableLocalWriteForwarding",
    option.None,
    decode.optional(decode.bool),
  )
  use master_user_secret_kms_key_id <- decode.optional_field(
    "MasterUserSecretKmsKeyId",
    option.None,
    decode.optional(decode.string),
  )
  use ca_certificate_identifier <- decode.optional_field(
    "CACertificateIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use engine_lifecycle_support <- decode.optional_field(
    "EngineLifecycleSupport",
    option.None,
    decode.optional(decode.string),
  )
  use tag_specifications <- decode.optional_field(
    "TagSpecifications",
    option.None,
    decode.optional(decode.list(decode_tag_specification_struct_params())),
  )
  use master_user_authentication_type <- decode.optional_field(
    "MasterUserAuthenticationType",
    option.None,
    decode.optional(decode_master_user_authentication_type_enum()),
  )
  use with_express_configuration <- decode.optional_field(
    "WithExpressConfiguration",
    option.None,
    decode.optional(decode.bool),
  )
  decode.success(CreateDBClusterInput(
    availability_zones: availability_zones,
    backup_retention_period: backup_retention_period,
    character_set_name: character_set_name,
    database_name: database_name,
    db_cluster_identifier: db_cluster_identifier,
    db_cluster_parameter_group_name: db_cluster_parameter_group_name,
    vpc_security_group_ids: vpc_security_group_ids,
    db_subnet_group_name: db_subnet_group_name,
    engine: engine,
    engine_version: engine_version,
    port: port,
    master_username: master_username,
    master_user_password: master_user_password,
    option_group_name: option_group_name,
    preferred_backup_window: preferred_backup_window,
    preferred_maintenance_window: preferred_maintenance_window,
    replication_source_identifier: replication_source_identifier,
    tags: tags,
    storage_encrypted: storage_encrypted,
    kms_key_id: kms_key_id,
    pre_signed_url: pre_signed_url,
    enable_iam_database_authentication: enable_iam_database_authentication,
    backtrack_window: backtrack_window,
    enable_cloudwatch_logs_exports: enable_cloudwatch_logs_exports,
    engine_mode: engine_mode,
    scaling_configuration: scaling_configuration,
    rds_custom_cluster_configuration: rds_custom_cluster_configuration,
    db_cluster_instance_class: db_cluster_instance_class,
    allocated_storage: allocated_storage,
    storage_type: storage_type,
    iops: iops,
    publicly_accessible: publicly_accessible,
    auto_minor_version_upgrade: auto_minor_version_upgrade,
    deletion_protection: deletion_protection,
    global_cluster_identifier: global_cluster_identifier,
    enable_http_endpoint: enable_http_endpoint,
    copy_tags_to_snapshot: copy_tags_to_snapshot,
    domain: domain,
    domain_iam_role_name: domain_iam_role_name,
    enable_global_write_forwarding: enable_global_write_forwarding,
    network_type: network_type,
    serverless_v2_scaling_configuration: serverless_v2_scaling_configuration,
    monitoring_interval: monitoring_interval,
    monitoring_role_arn: monitoring_role_arn,
    database_insights_mode: database_insights_mode,
    enable_performance_insights: enable_performance_insights,
    performance_insights_kms_key_id: performance_insights_kms_key_id,
    performance_insights_retention_period: performance_insights_retention_period,
    enable_limitless_database: enable_limitless_database,
    cluster_scalability_type: cluster_scalability_type,
    db_system_id: db_system_id,
    manage_master_user_password: manage_master_user_password,
    enable_local_write_forwarding: enable_local_write_forwarding,
    master_user_secret_kms_key_id: master_user_secret_kms_key_id,
    ca_certificate_identifier: ca_certificate_identifier,
    engine_lifecycle_support: engine_lifecycle_support,
    tag_specifications: tag_specifications,
    master_user_authentication_type: master_user_authentication_type,
    with_express_configuration: with_express_configuration,
  ))
}

pub fn decode_create_db_cluster_input(
  json_string: String,
) -> Result(CreateDBClusterInput, String) {
  result.map_error(
    json.parse(json_string, decode_create_db_cluster_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_create_db_cluster_request(
  input: CreateDBClusterInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=CreateDBCluster&Version=2014-10-31"
  let body = case input.availability_zones {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "AvailabilityZones", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "AvailabilityZones",
                    ".AvailabilityZone.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body = case input.backup_retention_period {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "BackupRetentionPeriod", "=", int.to_string(v)]),
      ])
  }
  let body = case input.character_set_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "CharacterSetName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.database_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DatabaseName", "=", uri.encode_component(v)]),
      ])
  }
  let body = {
    let v = input.db_cluster_identifier
    string.concat([
      body,
      string.concat(["&", "DBClusterIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.db_cluster_parameter_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DBClusterParameterGroupName",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.vpc_security_group_ids {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "VpcSecurityGroupIds", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "VpcSecurityGroupIds",
                    ".VpcSecurityGroupId.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body = case input.db_subnet_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DBSubnetGroupName", "=", uri.encode_component(v)]),
      ])
  }
  let body = {
    let v = input.engine
    string.concat([
      body,
      string.concat(["&", "Engine", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.engine_version {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "EngineVersion", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.port {
    option.None -> body
    option.Some(v) ->
      string.concat([body, string.concat(["&", "Port", "=", int.to_string(v)])])
  }
  let body = case input.master_username {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MasterUsername", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.master_user_password {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MasterUserPassword", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.option_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "OptionGroupName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.preferred_backup_window {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "PreferredBackupWindow",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.preferred_maintenance_window {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "PreferredMaintenanceWindow",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.replication_source_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "ReplicationSourceIdentifier",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.tags {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Tags", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_tag_at(
                  string.concat(["Tags", ".Tag.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.storage_encrypted {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "StorageEncrypted",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.kms_key_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "KmsKeyId", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.pre_signed_url {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "PreSignedUrl", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.enable_iam_database_authentication {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EnableIAMDatabaseAuthentication",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.backtrack_window {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "BacktrackWindow", "=", int.to_string(v)]),
      ])
  }
  let body = case input.enable_cloudwatch_logs_exports {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "EnableCloudwatchLogsExports", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "EnableCloudwatchLogsExports",
                    ".member.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body = case input.engine_mode {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "EngineMode", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.scaling_configuration {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        encode_scaling_configuration_at("ScalingConfiguration", v),
      ])
  }
  let body = case input.rds_custom_cluster_configuration {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        encode_rds_custom_cluster_configuration_at(
          "RdsCustomClusterConfiguration",
          v,
        ),
      ])
  }
  let body = case input.db_cluster_instance_class {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DBClusterInstanceClass",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.allocated_storage {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "AllocatedStorage", "=", int.to_string(v)]),
      ])
  }
  let body = case input.storage_type {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "StorageType", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.iops {
    option.None -> body
    option.Some(v) ->
      string.concat([body, string.concat(["&", "Iops", "=", int.to_string(v)])])
  }
  let body = case input.publicly_accessible {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "PubliclyAccessible",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.auto_minor_version_upgrade {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "AutoMinorVersionUpgrade",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.deletion_protection {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DeletionProtection",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.global_cluster_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "GlobalClusterIdentifier",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.enable_http_endpoint {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EnableHttpEndpoint",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.copy_tags_to_snapshot {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "CopyTagsToSnapshot",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.domain {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Domain", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.domain_iam_role_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DomainIAMRoleName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.enable_global_write_forwarding {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EnableGlobalWriteForwarding",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.network_type {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "NetworkType", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.serverless_v2_scaling_configuration {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        encode_serverless_v2_scaling_configuration_at(
          "ServerlessV2ScalingConfiguration",
          v,
        ),
      ])
  }
  let body = case input.monitoring_interval {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MonitoringInterval", "=", int.to_string(v)]),
      ])
  }
  let body = case input.monitoring_role_arn {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MonitoringRoleArn", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.database_insights_mode {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DatabaseInsightsMode",
          "=",
          uri.encode_component(database_insights_mode_to_wire(v)),
        ]),
      ])
  }
  let body = case input.enable_performance_insights {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EnablePerformanceInsights",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.performance_insights_kms_key_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "PerformanceInsightsKMSKeyId",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.performance_insights_retention_period {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "PerformanceInsightsRetentionPeriod",
          "=",
          int.to_string(v),
        ]),
      ])
  }
  let body = case input.enable_limitless_database {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EnableLimitlessDatabase",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.cluster_scalability_type {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "ClusterScalabilityType",
          "=",
          uri.encode_component(cluster_scalability_type_to_wire(v)),
        ]),
      ])
  }
  let body = case input.db_system_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DBSystemId", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.manage_master_user_password {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "ManageMasterUserPassword",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.enable_local_write_forwarding {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EnableLocalWriteForwarding",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.master_user_secret_kms_key_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "MasterUserSecretKmsKeyId",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.ca_certificate_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "CACertificateIdentifier",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.engine_lifecycle_support {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EngineLifecycleSupport",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.tag_specifications {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "TagSpecifications", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_tag_specification_at(
                  string.concat([
                    "TagSpecifications",
                    ".item.",
                    int.to_string(idx + 1),
                  ]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.master_user_authentication_type {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "MasterUserAuthenticationType",
          "=",
          uri.encode_component(master_user_authentication_type_to_wire(v)),
        ]),
      ])
  }
  let body = case input.with_express_configuration {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "WithExpressConfiguration",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_create_db_cluster_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(CreateDBClusterOutput, String) {
  Ok(CreateDBClusterOutput)
}

pub type CreateDBClusterEndpointInput {
  CreateDBClusterEndpointInput(
    db_cluster_identifier: String,
    db_cluster_endpoint_identifier: String,
    endpoint_type: String,
    static_members: option.Option(List(String)),
    excluded_members: option.Option(List(String)),
    tags: option.Option(List(Tag)),
  )
}

pub fn create_db_cluster_endpoint_input_default(
  db_cluster_identifier db_cluster_identifier: String,
  db_cluster_endpoint_identifier db_cluster_endpoint_identifier: String,
  endpoint_type endpoint_type: String,
) -> CreateDBClusterEndpointInput {
  CreateDBClusterEndpointInput(
    db_cluster_identifier: db_cluster_identifier,
    db_cluster_endpoint_identifier: db_cluster_endpoint_identifier,
    endpoint_type: endpoint_type,
    static_members: option.None,
    excluded_members: option.None,
    tags: option.None,
  )
}

pub type CreateDBClusterEndpointOutput {
  CreateDBClusterEndpointOutput
}

pub fn decode_create_db_cluster_endpoint_input_struct() -> decode.Decoder(
  CreateDBClusterEndpointInput,
) {
  use <- decode.recursive
  use db_cluster_identifier <- decode.field(
    "DBClusterIdentifier",
    decode.string,
  )
  use db_cluster_endpoint_identifier <- decode.field(
    "DBClusterEndpointIdentifier",
    decode.string,
  )
  use endpoint_type <- decode.field("EndpointType", decode.string)
  use static_members <- decode.optional_field(
    "StaticMembers",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use excluded_members <- decode.optional_field(
    "ExcludedMembers",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use tags <- decode.optional_field(
    "Tags",
    option.None,
    decode.optional(decode.list(decode_tag_struct_params())),
  )
  decode.success(CreateDBClusterEndpointInput(
    db_cluster_identifier: db_cluster_identifier,
    db_cluster_endpoint_identifier: db_cluster_endpoint_identifier,
    endpoint_type: endpoint_type,
    static_members: static_members,
    excluded_members: excluded_members,
    tags: tags,
  ))
}

pub fn decode_create_db_cluster_endpoint_input(
  json_string: String,
) -> Result(CreateDBClusterEndpointInput, String) {
  result.map_error(
    json.parse(json_string, decode_create_db_cluster_endpoint_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_create_db_cluster_endpoint_request(
  input: CreateDBClusterEndpointInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=CreateDBClusterEndpoint&Version=2014-10-31"
  let body = {
    let v = input.db_cluster_identifier
    string.concat([
      body,
      string.concat(["&", "DBClusterIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.db_cluster_endpoint_identifier
    string.concat([
      body,
      string.concat([
        "&",
        "DBClusterEndpointIdentifier",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body = {
    let v = input.endpoint_type
    string.concat([
      body,
      string.concat(["&", "EndpointType", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.static_members {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "StaticMembers", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "StaticMembers",
                    ".member.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body = case input.excluded_members {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "ExcludedMembers", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "ExcludedMembers",
                    ".member.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body = case input.tags {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Tags", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_tag_at(
                  string.concat(["Tags", ".Tag.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_create_db_cluster_endpoint_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(CreateDBClusterEndpointOutput, String) {
  Ok(CreateDBClusterEndpointOutput)
}

pub type CreateDBClusterParameterGroupInput {
  CreateDBClusterParameterGroupInput(
    db_cluster_parameter_group_name: String,
    db_parameter_group_family: String,
    description: String,
    tags: option.Option(List(Tag)),
  )
}

pub fn create_db_cluster_parameter_group_input_default(
  db_cluster_parameter_group_name db_cluster_parameter_group_name: String,
  db_parameter_group_family db_parameter_group_family: String,
  description description: String,
) -> CreateDBClusterParameterGroupInput {
  CreateDBClusterParameterGroupInput(
    db_cluster_parameter_group_name: db_cluster_parameter_group_name,
    db_parameter_group_family: db_parameter_group_family,
    description: description,
    tags: option.None,
  )
}

pub type CreateDBClusterParameterGroupOutput {
  CreateDBClusterParameterGroupOutput
}

pub fn decode_create_db_cluster_parameter_group_input_struct() -> decode.Decoder(
  CreateDBClusterParameterGroupInput,
) {
  use <- decode.recursive
  use db_cluster_parameter_group_name <- decode.field(
    "DBClusterParameterGroupName",
    decode.string,
  )
  use db_parameter_group_family <- decode.field(
    "DBParameterGroupFamily",
    decode.string,
  )
  use description <- decode.field("Description", decode.string)
  use tags <- decode.optional_field(
    "Tags",
    option.None,
    decode.optional(decode.list(decode_tag_struct_params())),
  )
  decode.success(CreateDBClusterParameterGroupInput(
    db_cluster_parameter_group_name: db_cluster_parameter_group_name,
    db_parameter_group_family: db_parameter_group_family,
    description: description,
    tags: tags,
  ))
}

pub fn decode_create_db_cluster_parameter_group_input(
  json_string: String,
) -> Result(CreateDBClusterParameterGroupInput, String) {
  result.map_error(
    json.parse(
      json_string,
      decode_create_db_cluster_parameter_group_input_struct(),
    ),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_create_db_cluster_parameter_group_request(
  input: CreateDBClusterParameterGroupInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=CreateDBClusterParameterGroup&Version=2014-10-31"
  let body = {
    let v = input.db_cluster_parameter_group_name
    string.concat([
      body,
      string.concat([
        "&",
        "DBClusterParameterGroupName",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body = {
    let v = input.db_parameter_group_family
    string.concat([
      body,
      string.concat([
        "&",
        "DBParameterGroupFamily",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body = {
    let v = input.description
    string.concat([
      body,
      string.concat(["&", "Description", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.tags {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Tags", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_tag_at(
                  string.concat(["Tags", ".Tag.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_create_db_cluster_parameter_group_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(CreateDBClusterParameterGroupOutput, String) {
  Ok(CreateDBClusterParameterGroupOutput)
}

pub type CreateDBClusterSnapshotInput {
  CreateDBClusterSnapshotInput(
    db_cluster_snapshot_identifier: String,
    db_cluster_identifier: String,
    tags: option.Option(List(Tag)),
  )
}

pub fn create_db_cluster_snapshot_input_default(
  db_cluster_snapshot_identifier db_cluster_snapshot_identifier: String,
  db_cluster_identifier db_cluster_identifier: String,
) -> CreateDBClusterSnapshotInput {
  CreateDBClusterSnapshotInput(
    db_cluster_snapshot_identifier: db_cluster_snapshot_identifier,
    db_cluster_identifier: db_cluster_identifier,
    tags: option.None,
  )
}

pub type CreateDBClusterSnapshotOutput {
  CreateDBClusterSnapshotOutput
}

pub fn decode_create_db_cluster_snapshot_input_struct() -> decode.Decoder(
  CreateDBClusterSnapshotInput,
) {
  use <- decode.recursive
  use db_cluster_snapshot_identifier <- decode.field(
    "DBClusterSnapshotIdentifier",
    decode.string,
  )
  use db_cluster_identifier <- decode.field(
    "DBClusterIdentifier",
    decode.string,
  )
  use tags <- decode.optional_field(
    "Tags",
    option.None,
    decode.optional(decode.list(decode_tag_struct_params())),
  )
  decode.success(CreateDBClusterSnapshotInput(
    db_cluster_snapshot_identifier: db_cluster_snapshot_identifier,
    db_cluster_identifier: db_cluster_identifier,
    tags: tags,
  ))
}

pub fn decode_create_db_cluster_snapshot_input(
  json_string: String,
) -> Result(CreateDBClusterSnapshotInput, String) {
  result.map_error(
    json.parse(json_string, decode_create_db_cluster_snapshot_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_create_db_cluster_snapshot_request(
  input: CreateDBClusterSnapshotInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=CreateDBClusterSnapshot&Version=2014-10-31"
  let body = {
    let v = input.db_cluster_snapshot_identifier
    string.concat([
      body,
      string.concat([
        "&",
        "DBClusterSnapshotIdentifier",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body = {
    let v = input.db_cluster_identifier
    string.concat([
      body,
      string.concat(["&", "DBClusterIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.tags {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Tags", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_tag_at(
                  string.concat(["Tags", ".Tag.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_create_db_cluster_snapshot_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(CreateDBClusterSnapshotOutput, String) {
  Ok(CreateDBClusterSnapshotOutput)
}

pub type CreateDBInstanceInput {
  CreateDBInstanceInput(
    db_name: option.Option(String),
    db_instance_identifier: String,
    allocated_storage: option.Option(Int),
    db_instance_class: String,
    engine: String,
    master_username: option.Option(String),
    master_user_password: option.Option(String),
    db_security_groups: option.Option(List(String)),
    vpc_security_group_ids: option.Option(List(String)),
    availability_zone: option.Option(String),
    db_subnet_group_name: option.Option(String),
    preferred_maintenance_window: option.Option(String),
    db_parameter_group_name: option.Option(String),
    backup_retention_period: option.Option(Int),
    preferred_backup_window: option.Option(String),
    port: option.Option(Int),
    multi_az: option.Option(Bool),
    engine_version: option.Option(String),
    auto_minor_version_upgrade: option.Option(Bool),
    license_model: option.Option(String),
    iops: option.Option(Int),
    storage_throughput: option.Option(Int),
    option_group_name: option.Option(String),
    character_set_name: option.Option(String),
    nchar_character_set_name: option.Option(String),
    publicly_accessible: option.Option(Bool),
    tags: option.Option(List(Tag)),
    db_cluster_identifier: option.Option(String),
    storage_type: option.Option(String),
    tde_credential_arn: option.Option(String),
    tde_credential_password: option.Option(String),
    storage_encrypted: option.Option(Bool),
    kms_key_id: option.Option(String),
    domain: option.Option(String),
    domain_fqdn: option.Option(String),
    domain_ou: option.Option(String),
    domain_auth_secret_arn: option.Option(String),
    domain_dns_ips: option.Option(List(String)),
    copy_tags_to_snapshot: option.Option(Bool),
    monitoring_interval: option.Option(Int),
    monitoring_role_arn: option.Option(String),
    domain_iam_role_name: option.Option(String),
    promotion_tier: option.Option(Int),
    timezone: option.Option(String),
    enable_iam_database_authentication: option.Option(Bool),
    database_insights_mode: option.Option(DatabaseInsightsMode),
    enable_performance_insights: option.Option(Bool),
    performance_insights_kms_key_id: option.Option(String),
    performance_insights_retention_period: option.Option(Int),
    enable_cloudwatch_logs_exports: option.Option(List(String)),
    processor_features: option.Option(List(ProcessorFeature)),
    deletion_protection: option.Option(Bool),
    max_allocated_storage: option.Option(Int),
    enable_customer_owned_ip: option.Option(Bool),
    network_type: option.Option(String),
    backup_target: option.Option(String),
    custom_iam_instance_profile: option.Option(String),
    db_system_id: option.Option(String),
    ca_certificate_identifier: option.Option(String),
    manage_master_user_password: option.Option(Bool),
    master_user_secret_kms_key_id: option.Option(String),
    multi_tenant: option.Option(Bool),
    dedicated_log_volume: option.Option(Bool),
    engine_lifecycle_support: option.Option(String),
    additional_storage_volumes: option.Option(List(AdditionalStorageVolume)),
    tag_specifications: option.Option(List(TagSpecification)),
    master_user_authentication_type: option.Option(MasterUserAuthenticationType),
  )
}

pub fn create_db_instance_input_default(
  db_instance_identifier db_instance_identifier: String,
  db_instance_class db_instance_class: String,
  engine engine: String,
) -> CreateDBInstanceInput {
  CreateDBInstanceInput(
    db_name: option.None,
    db_instance_identifier: db_instance_identifier,
    allocated_storage: option.None,
    db_instance_class: db_instance_class,
    engine: engine,
    master_username: option.None,
    master_user_password: option.None,
    db_security_groups: option.None,
    vpc_security_group_ids: option.None,
    availability_zone: option.None,
    db_subnet_group_name: option.None,
    preferred_maintenance_window: option.None,
    db_parameter_group_name: option.None,
    backup_retention_period: option.None,
    preferred_backup_window: option.None,
    port: option.None,
    multi_az: option.None,
    engine_version: option.None,
    auto_minor_version_upgrade: option.None,
    license_model: option.None,
    iops: option.None,
    storage_throughput: option.None,
    option_group_name: option.None,
    character_set_name: option.None,
    nchar_character_set_name: option.None,
    publicly_accessible: option.None,
    tags: option.None,
    db_cluster_identifier: option.None,
    storage_type: option.None,
    tde_credential_arn: option.None,
    tde_credential_password: option.None,
    storage_encrypted: option.None,
    kms_key_id: option.None,
    domain: option.None,
    domain_fqdn: option.None,
    domain_ou: option.None,
    domain_auth_secret_arn: option.None,
    domain_dns_ips: option.None,
    copy_tags_to_snapshot: option.None,
    monitoring_interval: option.None,
    monitoring_role_arn: option.None,
    domain_iam_role_name: option.None,
    promotion_tier: option.None,
    timezone: option.None,
    enable_iam_database_authentication: option.None,
    database_insights_mode: option.None,
    enable_performance_insights: option.None,
    performance_insights_kms_key_id: option.None,
    performance_insights_retention_period: option.None,
    enable_cloudwatch_logs_exports: option.None,
    processor_features: option.None,
    deletion_protection: option.None,
    max_allocated_storage: option.None,
    enable_customer_owned_ip: option.None,
    network_type: option.None,
    backup_target: option.None,
    custom_iam_instance_profile: option.None,
    db_system_id: option.None,
    ca_certificate_identifier: option.None,
    manage_master_user_password: option.None,
    master_user_secret_kms_key_id: option.None,
    multi_tenant: option.None,
    dedicated_log_volume: option.None,
    engine_lifecycle_support: option.None,
    additional_storage_volumes: option.None,
    tag_specifications: option.None,
    master_user_authentication_type: option.None,
  )
}

pub type CreateDBInstanceOutput {
  CreateDBInstanceOutput
}

pub fn decode_create_db_instance_input_struct() -> decode.Decoder(
  CreateDBInstanceInput,
) {
  use <- decode.recursive
  use db_name <- decode.optional_field(
    "DBName",
    option.None,
    decode.optional(decode.string),
  )
  use db_instance_identifier <- decode.field(
    "DBInstanceIdentifier",
    decode.string,
  )
  use allocated_storage <- decode.optional_field(
    "AllocatedStorage",
    option.None,
    decode.optional(decode.int),
  )
  use db_instance_class <- decode.field("DBInstanceClass", decode.string)
  use engine <- decode.field("Engine", decode.string)
  use master_username <- decode.optional_field(
    "MasterUsername",
    option.None,
    decode.optional(decode.string),
  )
  use master_user_password <- decode.optional_field(
    "MasterUserPassword",
    option.None,
    decode.optional(decode.string),
  )
  use db_security_groups <- decode.optional_field(
    "DBSecurityGroups",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use vpc_security_group_ids <- decode.optional_field(
    "VpcSecurityGroupIds",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use availability_zone <- decode.optional_field(
    "AvailabilityZone",
    option.None,
    decode.optional(decode.string),
  )
  use db_subnet_group_name <- decode.optional_field(
    "DBSubnetGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use preferred_maintenance_window <- decode.optional_field(
    "PreferredMaintenanceWindow",
    option.None,
    decode.optional(decode.string),
  )
  use db_parameter_group_name <- decode.optional_field(
    "DBParameterGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use backup_retention_period <- decode.optional_field(
    "BackupRetentionPeriod",
    option.None,
    decode.optional(decode.int),
  )
  use preferred_backup_window <- decode.optional_field(
    "PreferredBackupWindow",
    option.None,
    decode.optional(decode.string),
  )
  use port <- decode.optional_field(
    "Port",
    option.None,
    decode.optional(decode.int),
  )
  use multi_az <- decode.optional_field(
    "MultiAZ",
    option.None,
    decode.optional(decode.bool),
  )
  use engine_version <- decode.optional_field(
    "EngineVersion",
    option.None,
    decode.optional(decode.string),
  )
  use auto_minor_version_upgrade <- decode.optional_field(
    "AutoMinorVersionUpgrade",
    option.None,
    decode.optional(decode.bool),
  )
  use license_model <- decode.optional_field(
    "LicenseModel",
    option.None,
    decode.optional(decode.string),
  )
  use iops <- decode.optional_field(
    "Iops",
    option.None,
    decode.optional(decode.int),
  )
  use storage_throughput <- decode.optional_field(
    "StorageThroughput",
    option.None,
    decode.optional(decode.int),
  )
  use option_group_name <- decode.optional_field(
    "OptionGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use character_set_name <- decode.optional_field(
    "CharacterSetName",
    option.None,
    decode.optional(decode.string),
  )
  use nchar_character_set_name <- decode.optional_field(
    "NcharCharacterSetName",
    option.None,
    decode.optional(decode.string),
  )
  use publicly_accessible <- decode.optional_field(
    "PubliclyAccessible",
    option.None,
    decode.optional(decode.bool),
  )
  use tags <- decode.optional_field(
    "Tags",
    option.None,
    decode.optional(decode.list(decode_tag_struct_params())),
  )
  use db_cluster_identifier <- decode.optional_field(
    "DBClusterIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use storage_type <- decode.optional_field(
    "StorageType",
    option.None,
    decode.optional(decode.string),
  )
  use tde_credential_arn <- decode.optional_field(
    "TdeCredentialArn",
    option.None,
    decode.optional(decode.string),
  )
  use tde_credential_password <- decode.optional_field(
    "TdeCredentialPassword",
    option.None,
    decode.optional(decode.string),
  )
  use storage_encrypted <- decode.optional_field(
    "StorageEncrypted",
    option.None,
    decode.optional(decode.bool),
  )
  use kms_key_id <- decode.optional_field(
    "KmsKeyId",
    option.None,
    decode.optional(decode.string),
  )
  use domain <- decode.optional_field(
    "Domain",
    option.None,
    decode.optional(decode.string),
  )
  use domain_fqdn <- decode.optional_field(
    "DomainFqdn",
    option.None,
    decode.optional(decode.string),
  )
  use domain_ou <- decode.optional_field(
    "DomainOu",
    option.None,
    decode.optional(decode.string),
  )
  use domain_auth_secret_arn <- decode.optional_field(
    "DomainAuthSecretArn",
    option.None,
    decode.optional(decode.string),
  )
  use domain_dns_ips <- decode.optional_field(
    "DomainDnsIps",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use copy_tags_to_snapshot <- decode.optional_field(
    "CopyTagsToSnapshot",
    option.None,
    decode.optional(decode.bool),
  )
  use monitoring_interval <- decode.optional_field(
    "MonitoringInterval",
    option.None,
    decode.optional(decode.int),
  )
  use monitoring_role_arn <- decode.optional_field(
    "MonitoringRoleArn",
    option.None,
    decode.optional(decode.string),
  )
  use domain_iam_role_name <- decode.optional_field(
    "DomainIAMRoleName",
    option.None,
    decode.optional(decode.string),
  )
  use promotion_tier <- decode.optional_field(
    "PromotionTier",
    option.None,
    decode.optional(decode.int),
  )
  use timezone <- decode.optional_field(
    "Timezone",
    option.None,
    decode.optional(decode.string),
  )
  use enable_iam_database_authentication <- decode.optional_field(
    "EnableIAMDatabaseAuthentication",
    option.None,
    decode.optional(decode.bool),
  )
  use database_insights_mode <- decode.optional_field(
    "DatabaseInsightsMode",
    option.None,
    decode.optional(decode_database_insights_mode_enum()),
  )
  use enable_performance_insights <- decode.optional_field(
    "EnablePerformanceInsights",
    option.None,
    decode.optional(decode.bool),
  )
  use performance_insights_kms_key_id <- decode.optional_field(
    "PerformanceInsightsKMSKeyId",
    option.None,
    decode.optional(decode.string),
  )
  use performance_insights_retention_period <- decode.optional_field(
    "PerformanceInsightsRetentionPeriod",
    option.None,
    decode.optional(decode.int),
  )
  use enable_cloudwatch_logs_exports <- decode.optional_field(
    "EnableCloudwatchLogsExports",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use processor_features <- decode.optional_field(
    "ProcessorFeatures",
    option.None,
    decode.optional(decode.list(decode_processor_feature_struct_params())),
  )
  use deletion_protection <- decode.optional_field(
    "DeletionProtection",
    option.None,
    decode.optional(decode.bool),
  )
  use max_allocated_storage <- decode.optional_field(
    "MaxAllocatedStorage",
    option.None,
    decode.optional(decode.int),
  )
  use enable_customer_owned_ip <- decode.optional_field(
    "EnableCustomerOwnedIp",
    option.None,
    decode.optional(decode.bool),
  )
  use network_type <- decode.optional_field(
    "NetworkType",
    option.None,
    decode.optional(decode.string),
  )
  use backup_target <- decode.optional_field(
    "BackupTarget",
    option.None,
    decode.optional(decode.string),
  )
  use custom_iam_instance_profile <- decode.optional_field(
    "CustomIamInstanceProfile",
    option.None,
    decode.optional(decode.string),
  )
  use db_system_id <- decode.optional_field(
    "DBSystemId",
    option.None,
    decode.optional(decode.string),
  )
  use ca_certificate_identifier <- decode.optional_field(
    "CACertificateIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use manage_master_user_password <- decode.optional_field(
    "ManageMasterUserPassword",
    option.None,
    decode.optional(decode.bool),
  )
  use master_user_secret_kms_key_id <- decode.optional_field(
    "MasterUserSecretKmsKeyId",
    option.None,
    decode.optional(decode.string),
  )
  use multi_tenant <- decode.optional_field(
    "MultiTenant",
    option.None,
    decode.optional(decode.bool),
  )
  use dedicated_log_volume <- decode.optional_field(
    "DedicatedLogVolume",
    option.None,
    decode.optional(decode.bool),
  )
  use engine_lifecycle_support <- decode.optional_field(
    "EngineLifecycleSupport",
    option.None,
    decode.optional(decode.string),
  )
  use additional_storage_volumes <- decode.optional_field(
    "AdditionalStorageVolumes",
    option.None,
    decode.optional(
      decode.list(decode_additional_storage_volume_struct_params()),
    ),
  )
  use tag_specifications <- decode.optional_field(
    "TagSpecifications",
    option.None,
    decode.optional(decode.list(decode_tag_specification_struct_params())),
  )
  use master_user_authentication_type <- decode.optional_field(
    "MasterUserAuthenticationType",
    option.None,
    decode.optional(decode_master_user_authentication_type_enum()),
  )
  decode.success(CreateDBInstanceInput(
    db_name: db_name,
    db_instance_identifier: db_instance_identifier,
    allocated_storage: allocated_storage,
    db_instance_class: db_instance_class,
    engine: engine,
    master_username: master_username,
    master_user_password: master_user_password,
    db_security_groups: db_security_groups,
    vpc_security_group_ids: vpc_security_group_ids,
    availability_zone: availability_zone,
    db_subnet_group_name: db_subnet_group_name,
    preferred_maintenance_window: preferred_maintenance_window,
    db_parameter_group_name: db_parameter_group_name,
    backup_retention_period: backup_retention_period,
    preferred_backup_window: preferred_backup_window,
    port: port,
    multi_az: multi_az,
    engine_version: engine_version,
    auto_minor_version_upgrade: auto_minor_version_upgrade,
    license_model: license_model,
    iops: iops,
    storage_throughput: storage_throughput,
    option_group_name: option_group_name,
    character_set_name: character_set_name,
    nchar_character_set_name: nchar_character_set_name,
    publicly_accessible: publicly_accessible,
    tags: tags,
    db_cluster_identifier: db_cluster_identifier,
    storage_type: storage_type,
    tde_credential_arn: tde_credential_arn,
    tde_credential_password: tde_credential_password,
    storage_encrypted: storage_encrypted,
    kms_key_id: kms_key_id,
    domain: domain,
    domain_fqdn: domain_fqdn,
    domain_ou: domain_ou,
    domain_auth_secret_arn: domain_auth_secret_arn,
    domain_dns_ips: domain_dns_ips,
    copy_tags_to_snapshot: copy_tags_to_snapshot,
    monitoring_interval: monitoring_interval,
    monitoring_role_arn: monitoring_role_arn,
    domain_iam_role_name: domain_iam_role_name,
    promotion_tier: promotion_tier,
    timezone: timezone,
    enable_iam_database_authentication: enable_iam_database_authentication,
    database_insights_mode: database_insights_mode,
    enable_performance_insights: enable_performance_insights,
    performance_insights_kms_key_id: performance_insights_kms_key_id,
    performance_insights_retention_period: performance_insights_retention_period,
    enable_cloudwatch_logs_exports: enable_cloudwatch_logs_exports,
    processor_features: processor_features,
    deletion_protection: deletion_protection,
    max_allocated_storage: max_allocated_storage,
    enable_customer_owned_ip: enable_customer_owned_ip,
    network_type: network_type,
    backup_target: backup_target,
    custom_iam_instance_profile: custom_iam_instance_profile,
    db_system_id: db_system_id,
    ca_certificate_identifier: ca_certificate_identifier,
    manage_master_user_password: manage_master_user_password,
    master_user_secret_kms_key_id: master_user_secret_kms_key_id,
    multi_tenant: multi_tenant,
    dedicated_log_volume: dedicated_log_volume,
    engine_lifecycle_support: engine_lifecycle_support,
    additional_storage_volumes: additional_storage_volumes,
    tag_specifications: tag_specifications,
    master_user_authentication_type: master_user_authentication_type,
  ))
}

pub fn decode_create_db_instance_input(
  json_string: String,
) -> Result(CreateDBInstanceInput, String) {
  result.map_error(
    json.parse(json_string, decode_create_db_instance_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_create_db_instance_request(
  input: CreateDBInstanceInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=CreateDBInstance&Version=2014-10-31"
  let body = case input.db_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DBName", "=", uri.encode_component(v)]),
      ])
  }
  let body = {
    let v = input.db_instance_identifier
    string.concat([
      body,
      string.concat(["&", "DBInstanceIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.allocated_storage {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "AllocatedStorage", "=", int.to_string(v)]),
      ])
  }
  let body = {
    let v = input.db_instance_class
    string.concat([
      body,
      string.concat(["&", "DBInstanceClass", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.engine
    string.concat([
      body,
      string.concat(["&", "Engine", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.master_username {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MasterUsername", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.master_user_password {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MasterUserPassword", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.db_security_groups {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "DBSecurityGroups", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "DBSecurityGroups",
                    ".DBSecurityGroupName.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body = case input.vpc_security_group_ids {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "VpcSecurityGroupIds", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "VpcSecurityGroupIds",
                    ".VpcSecurityGroupId.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body = case input.availability_zone {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "AvailabilityZone", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.db_subnet_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DBSubnetGroupName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.preferred_maintenance_window {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "PreferredMaintenanceWindow",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.db_parameter_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DBParameterGroupName",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.backup_retention_period {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "BackupRetentionPeriod", "=", int.to_string(v)]),
      ])
  }
  let body = case input.preferred_backup_window {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "PreferredBackupWindow",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.port {
    option.None -> body
    option.Some(v) ->
      string.concat([body, string.concat(["&", "Port", "=", int.to_string(v)])])
  }
  let body = case input.multi_az {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "MultiAZ",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.engine_version {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "EngineVersion", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.auto_minor_version_upgrade {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "AutoMinorVersionUpgrade",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.license_model {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "LicenseModel", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.iops {
    option.None -> body
    option.Some(v) ->
      string.concat([body, string.concat(["&", "Iops", "=", int.to_string(v)])])
  }
  let body = case input.storage_throughput {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "StorageThroughput", "=", int.to_string(v)]),
      ])
  }
  let body = case input.option_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "OptionGroupName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.character_set_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "CharacterSetName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.nchar_character_set_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "NcharCharacterSetName",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.publicly_accessible {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "PubliclyAccessible",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.tags {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Tags", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_tag_at(
                  string.concat(["Tags", ".Tag.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.db_cluster_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DBClusterIdentifier", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.storage_type {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "StorageType", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.tde_credential_arn {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "TdeCredentialArn", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.tde_credential_password {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "TdeCredentialPassword",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.storage_encrypted {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "StorageEncrypted",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.kms_key_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "KmsKeyId", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.domain {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Domain", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.domain_fqdn {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DomainFqdn", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.domain_ou {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DomainOu", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.domain_auth_secret_arn {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DomainAuthSecretArn", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.domain_dns_ips {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "DomainDnsIps", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "DomainDnsIps",
                    ".member.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body = case input.copy_tags_to_snapshot {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "CopyTagsToSnapshot",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.monitoring_interval {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MonitoringInterval", "=", int.to_string(v)]),
      ])
  }
  let body = case input.monitoring_role_arn {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MonitoringRoleArn", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.domain_iam_role_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DomainIAMRoleName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.promotion_tier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "PromotionTier", "=", int.to_string(v)]),
      ])
  }
  let body = case input.timezone {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Timezone", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.enable_iam_database_authentication {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EnableIAMDatabaseAuthentication",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.database_insights_mode {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DatabaseInsightsMode",
          "=",
          uri.encode_component(database_insights_mode_to_wire(v)),
        ]),
      ])
  }
  let body = case input.enable_performance_insights {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EnablePerformanceInsights",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.performance_insights_kms_key_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "PerformanceInsightsKMSKeyId",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.performance_insights_retention_period {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "PerformanceInsightsRetentionPeriod",
          "=",
          int.to_string(v),
        ]),
      ])
  }
  let body = case input.enable_cloudwatch_logs_exports {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "EnableCloudwatchLogsExports", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "EnableCloudwatchLogsExports",
                    ".member.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body = case input.processor_features {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "ProcessorFeatures", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_processor_feature_at(
                  string.concat([
                    "ProcessorFeatures",
                    ".ProcessorFeature.",
                    int.to_string(idx + 1),
                  ]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.deletion_protection {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DeletionProtection",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.max_allocated_storage {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxAllocatedStorage", "=", int.to_string(v)]),
      ])
  }
  let body = case input.enable_customer_owned_ip {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EnableCustomerOwnedIp",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.network_type {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "NetworkType", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.backup_target {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "BackupTarget", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.custom_iam_instance_profile {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "CustomIamInstanceProfile",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.db_system_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DBSystemId", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.ca_certificate_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "CACertificateIdentifier",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.manage_master_user_password {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "ManageMasterUserPassword",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.master_user_secret_kms_key_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "MasterUserSecretKmsKeyId",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.multi_tenant {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "MultiTenant",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.dedicated_log_volume {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DedicatedLogVolume",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.engine_lifecycle_support {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EngineLifecycleSupport",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.additional_storage_volumes {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "AdditionalStorageVolumes", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_additional_storage_volume_at(
                  string.concat([
                    "AdditionalStorageVolumes",
                    ".member.",
                    int.to_string(idx + 1),
                  ]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.tag_specifications {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "TagSpecifications", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_tag_specification_at(
                  string.concat([
                    "TagSpecifications",
                    ".item.",
                    int.to_string(idx + 1),
                  ]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.master_user_authentication_type {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "MasterUserAuthenticationType",
          "=",
          uri.encode_component(master_user_authentication_type_to_wire(v)),
        ]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_create_db_instance_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(CreateDBInstanceOutput, String) {
  Ok(CreateDBInstanceOutput)
}

pub type CreateDBInstanceReadReplicaInput {
  CreateDBInstanceReadReplicaInput(
    db_instance_identifier: String,
    source_db_instance_identifier: option.Option(String),
    db_instance_class: option.Option(String),
    availability_zone: option.Option(String),
    port: option.Option(Int),
    multi_az: option.Option(Bool),
    auto_minor_version_upgrade: option.Option(Bool),
    iops: option.Option(Int),
    storage_throughput: option.Option(Int),
    option_group_name: option.Option(String),
    db_parameter_group_name: option.Option(String),
    publicly_accessible: option.Option(Bool),
    tags: option.Option(List(Tag)),
    db_subnet_group_name: option.Option(String),
    vpc_security_group_ids: option.Option(List(String)),
    storage_type: option.Option(String),
    copy_tags_to_snapshot: option.Option(Bool),
    monitoring_interval: option.Option(Int),
    monitoring_role_arn: option.Option(String),
    kms_key_id: option.Option(String),
    pre_signed_url: option.Option(String),
    enable_iam_database_authentication: option.Option(Bool),
    database_insights_mode: option.Option(DatabaseInsightsMode),
    enable_performance_insights: option.Option(Bool),
    performance_insights_kms_key_id: option.Option(String),
    performance_insights_retention_period: option.Option(Int),
    enable_cloudwatch_logs_exports: option.Option(List(String)),
    processor_features: option.Option(List(ProcessorFeature)),
    use_default_processor_features: option.Option(Bool),
    deletion_protection: option.Option(Bool),
    domain: option.Option(String),
    domain_iam_role_name: option.Option(String),
    domain_fqdn: option.Option(String),
    domain_ou: option.Option(String),
    domain_auth_secret_arn: option.Option(String),
    domain_dns_ips: option.Option(List(String)),
    replica_mode: option.Option(ReplicaMode),
    enable_customer_owned_ip: option.Option(Bool),
    network_type: option.Option(String),
    max_allocated_storage: option.Option(Int),
    backup_target: option.Option(String),
    custom_iam_instance_profile: option.Option(String),
    allocated_storage: option.Option(Int),
    source_db_cluster_identifier: option.Option(String),
    dedicated_log_volume: option.Option(Bool),
    upgrade_storage_config: option.Option(Bool),
    ca_certificate_identifier: option.Option(String),
    additional_storage_volumes: option.Option(List(AdditionalStorageVolume)),
    tag_specifications: option.Option(List(TagSpecification)),
  )
}

pub fn create_db_instance_read_replica_input_default(
  db_instance_identifier db_instance_identifier: String,
) -> CreateDBInstanceReadReplicaInput {
  CreateDBInstanceReadReplicaInput(
    db_instance_identifier: db_instance_identifier,
    source_db_instance_identifier: option.None,
    db_instance_class: option.None,
    availability_zone: option.None,
    port: option.None,
    multi_az: option.None,
    auto_minor_version_upgrade: option.None,
    iops: option.None,
    storage_throughput: option.None,
    option_group_name: option.None,
    db_parameter_group_name: option.None,
    publicly_accessible: option.None,
    tags: option.None,
    db_subnet_group_name: option.None,
    vpc_security_group_ids: option.None,
    storage_type: option.None,
    copy_tags_to_snapshot: option.None,
    monitoring_interval: option.None,
    monitoring_role_arn: option.None,
    kms_key_id: option.None,
    pre_signed_url: option.None,
    enable_iam_database_authentication: option.None,
    database_insights_mode: option.None,
    enable_performance_insights: option.None,
    performance_insights_kms_key_id: option.None,
    performance_insights_retention_period: option.None,
    enable_cloudwatch_logs_exports: option.None,
    processor_features: option.None,
    use_default_processor_features: option.None,
    deletion_protection: option.None,
    domain: option.None,
    domain_iam_role_name: option.None,
    domain_fqdn: option.None,
    domain_ou: option.None,
    domain_auth_secret_arn: option.None,
    domain_dns_ips: option.None,
    replica_mode: option.None,
    enable_customer_owned_ip: option.None,
    network_type: option.None,
    max_allocated_storage: option.None,
    backup_target: option.None,
    custom_iam_instance_profile: option.None,
    allocated_storage: option.None,
    source_db_cluster_identifier: option.None,
    dedicated_log_volume: option.None,
    upgrade_storage_config: option.None,
    ca_certificate_identifier: option.None,
    additional_storage_volumes: option.None,
    tag_specifications: option.None,
  )
}

pub type CreateDBInstanceReadReplicaOutput {
  CreateDBInstanceReadReplicaOutput
}

pub fn decode_create_db_instance_read_replica_input_struct() -> decode.Decoder(
  CreateDBInstanceReadReplicaInput,
) {
  use <- decode.recursive
  use db_instance_identifier <- decode.field(
    "DBInstanceIdentifier",
    decode.string,
  )
  use source_db_instance_identifier <- decode.optional_field(
    "SourceDBInstanceIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use db_instance_class <- decode.optional_field(
    "DBInstanceClass",
    option.None,
    decode.optional(decode.string),
  )
  use availability_zone <- decode.optional_field(
    "AvailabilityZone",
    option.None,
    decode.optional(decode.string),
  )
  use port <- decode.optional_field(
    "Port",
    option.None,
    decode.optional(decode.int),
  )
  use multi_az <- decode.optional_field(
    "MultiAZ",
    option.None,
    decode.optional(decode.bool),
  )
  use auto_minor_version_upgrade <- decode.optional_field(
    "AutoMinorVersionUpgrade",
    option.None,
    decode.optional(decode.bool),
  )
  use iops <- decode.optional_field(
    "Iops",
    option.None,
    decode.optional(decode.int),
  )
  use storage_throughput <- decode.optional_field(
    "StorageThroughput",
    option.None,
    decode.optional(decode.int),
  )
  use option_group_name <- decode.optional_field(
    "OptionGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use db_parameter_group_name <- decode.optional_field(
    "DBParameterGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use publicly_accessible <- decode.optional_field(
    "PubliclyAccessible",
    option.None,
    decode.optional(decode.bool),
  )
  use tags <- decode.optional_field(
    "Tags",
    option.None,
    decode.optional(decode.list(decode_tag_struct_params())),
  )
  use db_subnet_group_name <- decode.optional_field(
    "DBSubnetGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use vpc_security_group_ids <- decode.optional_field(
    "VpcSecurityGroupIds",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use storage_type <- decode.optional_field(
    "StorageType",
    option.None,
    decode.optional(decode.string),
  )
  use copy_tags_to_snapshot <- decode.optional_field(
    "CopyTagsToSnapshot",
    option.None,
    decode.optional(decode.bool),
  )
  use monitoring_interval <- decode.optional_field(
    "MonitoringInterval",
    option.None,
    decode.optional(decode.int),
  )
  use monitoring_role_arn <- decode.optional_field(
    "MonitoringRoleArn",
    option.None,
    decode.optional(decode.string),
  )
  use kms_key_id <- decode.optional_field(
    "KmsKeyId",
    option.None,
    decode.optional(decode.string),
  )
  use pre_signed_url <- decode.optional_field(
    "PreSignedUrl",
    option.None,
    decode.optional(decode.string),
  )
  use enable_iam_database_authentication <- decode.optional_field(
    "EnableIAMDatabaseAuthentication",
    option.None,
    decode.optional(decode.bool),
  )
  use database_insights_mode <- decode.optional_field(
    "DatabaseInsightsMode",
    option.None,
    decode.optional(decode_database_insights_mode_enum()),
  )
  use enable_performance_insights <- decode.optional_field(
    "EnablePerformanceInsights",
    option.None,
    decode.optional(decode.bool),
  )
  use performance_insights_kms_key_id <- decode.optional_field(
    "PerformanceInsightsKMSKeyId",
    option.None,
    decode.optional(decode.string),
  )
  use performance_insights_retention_period <- decode.optional_field(
    "PerformanceInsightsRetentionPeriod",
    option.None,
    decode.optional(decode.int),
  )
  use enable_cloudwatch_logs_exports <- decode.optional_field(
    "EnableCloudwatchLogsExports",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use processor_features <- decode.optional_field(
    "ProcessorFeatures",
    option.None,
    decode.optional(decode.list(decode_processor_feature_struct_params())),
  )
  use use_default_processor_features <- decode.optional_field(
    "UseDefaultProcessorFeatures",
    option.None,
    decode.optional(decode.bool),
  )
  use deletion_protection <- decode.optional_field(
    "DeletionProtection",
    option.None,
    decode.optional(decode.bool),
  )
  use domain <- decode.optional_field(
    "Domain",
    option.None,
    decode.optional(decode.string),
  )
  use domain_iam_role_name <- decode.optional_field(
    "DomainIAMRoleName",
    option.None,
    decode.optional(decode.string),
  )
  use domain_fqdn <- decode.optional_field(
    "DomainFqdn",
    option.None,
    decode.optional(decode.string),
  )
  use domain_ou <- decode.optional_field(
    "DomainOu",
    option.None,
    decode.optional(decode.string),
  )
  use domain_auth_secret_arn <- decode.optional_field(
    "DomainAuthSecretArn",
    option.None,
    decode.optional(decode.string),
  )
  use domain_dns_ips <- decode.optional_field(
    "DomainDnsIps",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use replica_mode <- decode.optional_field(
    "ReplicaMode",
    option.None,
    decode.optional(decode_replica_mode_enum()),
  )
  use enable_customer_owned_ip <- decode.optional_field(
    "EnableCustomerOwnedIp",
    option.None,
    decode.optional(decode.bool),
  )
  use network_type <- decode.optional_field(
    "NetworkType",
    option.None,
    decode.optional(decode.string),
  )
  use max_allocated_storage <- decode.optional_field(
    "MaxAllocatedStorage",
    option.None,
    decode.optional(decode.int),
  )
  use backup_target <- decode.optional_field(
    "BackupTarget",
    option.None,
    decode.optional(decode.string),
  )
  use custom_iam_instance_profile <- decode.optional_field(
    "CustomIamInstanceProfile",
    option.None,
    decode.optional(decode.string),
  )
  use allocated_storage <- decode.optional_field(
    "AllocatedStorage",
    option.None,
    decode.optional(decode.int),
  )
  use source_db_cluster_identifier <- decode.optional_field(
    "SourceDBClusterIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use dedicated_log_volume <- decode.optional_field(
    "DedicatedLogVolume",
    option.None,
    decode.optional(decode.bool),
  )
  use upgrade_storage_config <- decode.optional_field(
    "UpgradeStorageConfig",
    option.None,
    decode.optional(decode.bool),
  )
  use ca_certificate_identifier <- decode.optional_field(
    "CACertificateIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use additional_storage_volumes <- decode.optional_field(
    "AdditionalStorageVolumes",
    option.None,
    decode.optional(
      decode.list(decode_additional_storage_volume_struct_params()),
    ),
  )
  use tag_specifications <- decode.optional_field(
    "TagSpecifications",
    option.None,
    decode.optional(decode.list(decode_tag_specification_struct_params())),
  )
  decode.success(CreateDBInstanceReadReplicaInput(
    db_instance_identifier: db_instance_identifier,
    source_db_instance_identifier: source_db_instance_identifier,
    db_instance_class: db_instance_class,
    availability_zone: availability_zone,
    port: port,
    multi_az: multi_az,
    auto_minor_version_upgrade: auto_minor_version_upgrade,
    iops: iops,
    storage_throughput: storage_throughput,
    option_group_name: option_group_name,
    db_parameter_group_name: db_parameter_group_name,
    publicly_accessible: publicly_accessible,
    tags: tags,
    db_subnet_group_name: db_subnet_group_name,
    vpc_security_group_ids: vpc_security_group_ids,
    storage_type: storage_type,
    copy_tags_to_snapshot: copy_tags_to_snapshot,
    monitoring_interval: monitoring_interval,
    monitoring_role_arn: monitoring_role_arn,
    kms_key_id: kms_key_id,
    pre_signed_url: pre_signed_url,
    enable_iam_database_authentication: enable_iam_database_authentication,
    database_insights_mode: database_insights_mode,
    enable_performance_insights: enable_performance_insights,
    performance_insights_kms_key_id: performance_insights_kms_key_id,
    performance_insights_retention_period: performance_insights_retention_period,
    enable_cloudwatch_logs_exports: enable_cloudwatch_logs_exports,
    processor_features: processor_features,
    use_default_processor_features: use_default_processor_features,
    deletion_protection: deletion_protection,
    domain: domain,
    domain_iam_role_name: domain_iam_role_name,
    domain_fqdn: domain_fqdn,
    domain_ou: domain_ou,
    domain_auth_secret_arn: domain_auth_secret_arn,
    domain_dns_ips: domain_dns_ips,
    replica_mode: replica_mode,
    enable_customer_owned_ip: enable_customer_owned_ip,
    network_type: network_type,
    max_allocated_storage: max_allocated_storage,
    backup_target: backup_target,
    custom_iam_instance_profile: custom_iam_instance_profile,
    allocated_storage: allocated_storage,
    source_db_cluster_identifier: source_db_cluster_identifier,
    dedicated_log_volume: dedicated_log_volume,
    upgrade_storage_config: upgrade_storage_config,
    ca_certificate_identifier: ca_certificate_identifier,
    additional_storage_volumes: additional_storage_volumes,
    tag_specifications: tag_specifications,
  ))
}

pub fn decode_create_db_instance_read_replica_input(
  json_string: String,
) -> Result(CreateDBInstanceReadReplicaInput, String) {
  result.map_error(
    json.parse(
      json_string,
      decode_create_db_instance_read_replica_input_struct(),
    ),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_create_db_instance_read_replica_request(
  input: CreateDBInstanceReadReplicaInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=CreateDBInstanceReadReplica&Version=2014-10-31"
  let body = {
    let v = input.db_instance_identifier
    string.concat([
      body,
      string.concat(["&", "DBInstanceIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.source_db_instance_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "SourceDBInstanceIdentifier",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.db_instance_class {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DBInstanceClass", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.availability_zone {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "AvailabilityZone", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.port {
    option.None -> body
    option.Some(v) ->
      string.concat([body, string.concat(["&", "Port", "=", int.to_string(v)])])
  }
  let body = case input.multi_az {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "MultiAZ",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.auto_minor_version_upgrade {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "AutoMinorVersionUpgrade",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.iops {
    option.None -> body
    option.Some(v) ->
      string.concat([body, string.concat(["&", "Iops", "=", int.to_string(v)])])
  }
  let body = case input.storage_throughput {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "StorageThroughput", "=", int.to_string(v)]),
      ])
  }
  let body = case input.option_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "OptionGroupName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.db_parameter_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DBParameterGroupName",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.publicly_accessible {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "PubliclyAccessible",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.tags {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Tags", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_tag_at(
                  string.concat(["Tags", ".Tag.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.db_subnet_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DBSubnetGroupName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.vpc_security_group_ids {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "VpcSecurityGroupIds", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "VpcSecurityGroupIds",
                    ".VpcSecurityGroupId.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body = case input.storage_type {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "StorageType", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.copy_tags_to_snapshot {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "CopyTagsToSnapshot",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.monitoring_interval {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MonitoringInterval", "=", int.to_string(v)]),
      ])
  }
  let body = case input.monitoring_role_arn {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MonitoringRoleArn", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.kms_key_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "KmsKeyId", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.pre_signed_url {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "PreSignedUrl", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.enable_iam_database_authentication {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EnableIAMDatabaseAuthentication",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.database_insights_mode {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DatabaseInsightsMode",
          "=",
          uri.encode_component(database_insights_mode_to_wire(v)),
        ]),
      ])
  }
  let body = case input.enable_performance_insights {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EnablePerformanceInsights",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.performance_insights_kms_key_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "PerformanceInsightsKMSKeyId",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.performance_insights_retention_period {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "PerformanceInsightsRetentionPeriod",
          "=",
          int.to_string(v),
        ]),
      ])
  }
  let body = case input.enable_cloudwatch_logs_exports {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "EnableCloudwatchLogsExports", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "EnableCloudwatchLogsExports",
                    ".member.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body = case input.processor_features {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "ProcessorFeatures", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_processor_feature_at(
                  string.concat([
                    "ProcessorFeatures",
                    ".ProcessorFeature.",
                    int.to_string(idx + 1),
                  ]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.use_default_processor_features {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "UseDefaultProcessorFeatures",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.deletion_protection {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DeletionProtection",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.domain {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Domain", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.domain_iam_role_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DomainIAMRoleName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.domain_fqdn {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DomainFqdn", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.domain_ou {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DomainOu", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.domain_auth_secret_arn {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DomainAuthSecretArn", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.domain_dns_ips {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "DomainDnsIps", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "DomainDnsIps",
                    ".member.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body = case input.replica_mode {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "ReplicaMode",
          "=",
          uri.encode_component(replica_mode_to_wire(v)),
        ]),
      ])
  }
  let body = case input.enable_customer_owned_ip {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EnableCustomerOwnedIp",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.network_type {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "NetworkType", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.max_allocated_storage {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxAllocatedStorage", "=", int.to_string(v)]),
      ])
  }
  let body = case input.backup_target {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "BackupTarget", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.custom_iam_instance_profile {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "CustomIamInstanceProfile",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.allocated_storage {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "AllocatedStorage", "=", int.to_string(v)]),
      ])
  }
  let body = case input.source_db_cluster_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "SourceDBClusterIdentifier",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.dedicated_log_volume {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DedicatedLogVolume",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.upgrade_storage_config {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "UpgradeStorageConfig",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.ca_certificate_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "CACertificateIdentifier",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.additional_storage_volumes {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "AdditionalStorageVolumes", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_additional_storage_volume_at(
                  string.concat([
                    "AdditionalStorageVolumes",
                    ".member.",
                    int.to_string(idx + 1),
                  ]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.tag_specifications {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "TagSpecifications", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_tag_specification_at(
                  string.concat([
                    "TagSpecifications",
                    ".item.",
                    int.to_string(idx + 1),
                  ]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_create_db_instance_read_replica_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(CreateDBInstanceReadReplicaOutput, String) {
  Ok(CreateDBInstanceReadReplicaOutput)
}

pub type CreateDBParameterGroupInput {
  CreateDBParameterGroupInput(
    db_parameter_group_name: String,
    db_parameter_group_family: String,
    description: String,
    tags: option.Option(List(Tag)),
  )
}

pub fn create_db_parameter_group_input_default(
  db_parameter_group_name db_parameter_group_name: String,
  db_parameter_group_family db_parameter_group_family: String,
  description description: String,
) -> CreateDBParameterGroupInput {
  CreateDBParameterGroupInput(
    db_parameter_group_name: db_parameter_group_name,
    db_parameter_group_family: db_parameter_group_family,
    description: description,
    tags: option.None,
  )
}

pub type CreateDBParameterGroupOutput {
  CreateDBParameterGroupOutput
}

pub fn decode_create_db_parameter_group_input_struct() -> decode.Decoder(
  CreateDBParameterGroupInput,
) {
  use <- decode.recursive
  use db_parameter_group_name <- decode.field(
    "DBParameterGroupName",
    decode.string,
  )
  use db_parameter_group_family <- decode.field(
    "DBParameterGroupFamily",
    decode.string,
  )
  use description <- decode.field("Description", decode.string)
  use tags <- decode.optional_field(
    "Tags",
    option.None,
    decode.optional(decode.list(decode_tag_struct_params())),
  )
  decode.success(CreateDBParameterGroupInput(
    db_parameter_group_name: db_parameter_group_name,
    db_parameter_group_family: db_parameter_group_family,
    description: description,
    tags: tags,
  ))
}

pub fn decode_create_db_parameter_group_input(
  json_string: String,
) -> Result(CreateDBParameterGroupInput, String) {
  result.map_error(
    json.parse(json_string, decode_create_db_parameter_group_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_create_db_parameter_group_request(
  input: CreateDBParameterGroupInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=CreateDBParameterGroup&Version=2014-10-31"
  let body = {
    let v = input.db_parameter_group_name
    string.concat([
      body,
      string.concat(["&", "DBParameterGroupName", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.db_parameter_group_family
    string.concat([
      body,
      string.concat([
        "&",
        "DBParameterGroupFamily",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body = {
    let v = input.description
    string.concat([
      body,
      string.concat(["&", "Description", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.tags {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Tags", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_tag_at(
                  string.concat(["Tags", ".Tag.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_create_db_parameter_group_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(CreateDBParameterGroupOutput, String) {
  Ok(CreateDBParameterGroupOutput)
}

pub type CreateDBProxyInput {
  CreateDBProxyInput(
    db_proxy_name: String,
    engine_family: EngineFamily,
    default_auth_scheme: option.Option(DefaultAuthScheme),
    auth: option.Option(List(UserAuthConfig)),
    role_arn: String,
    vpc_subnet_ids: List(String),
    vpc_security_group_ids: option.Option(List(String)),
    require_tls: option.Option(Bool),
    idle_client_timeout: option.Option(Int),
    debug_logging: option.Option(Bool),
    tags: option.Option(List(Tag)),
    endpoint_network_type: option.Option(EndpointNetworkType),
    target_connection_network_type: option.Option(TargetConnectionNetworkType),
  )
}

pub fn create_db_proxy_input_default(
  db_proxy_name db_proxy_name: String,
  engine_family engine_family: EngineFamily,
  role_arn role_arn: String,
  vpc_subnet_ids vpc_subnet_ids: List(String),
) -> CreateDBProxyInput {
  CreateDBProxyInput(
    db_proxy_name: db_proxy_name,
    engine_family: engine_family,
    default_auth_scheme: option.None,
    auth: option.None,
    role_arn: role_arn,
    vpc_subnet_ids: vpc_subnet_ids,
    vpc_security_group_ids: option.None,
    require_tls: option.None,
    idle_client_timeout: option.None,
    debug_logging: option.None,
    tags: option.None,
    endpoint_network_type: option.None,
    target_connection_network_type: option.None,
  )
}

pub type CreateDBProxyOutput {
  CreateDBProxyOutput
}

pub fn decode_create_db_proxy_input_struct() -> decode.Decoder(
  CreateDBProxyInput,
) {
  use <- decode.recursive
  use db_proxy_name <- decode.field("DBProxyName", decode.string)
  use engine_family <- decode.field("EngineFamily", decode_engine_family_enum())
  use default_auth_scheme <- decode.optional_field(
    "DefaultAuthScheme",
    option.None,
    decode.optional(decode_default_auth_scheme_enum()),
  )
  use auth <- decode.optional_field(
    "Auth",
    option.None,
    decode.optional(decode.list(decode_user_auth_config_struct_params())),
  )
  use role_arn <- decode.field("RoleArn", decode.string)
  use vpc_subnet_ids <- decode.field("VpcSubnetIds", decode.list(decode.string))
  use vpc_security_group_ids <- decode.optional_field(
    "VpcSecurityGroupIds",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use require_tls <- decode.optional_field(
    "RequireTLS",
    option.None,
    decode.optional(decode.bool),
  )
  use idle_client_timeout <- decode.optional_field(
    "IdleClientTimeout",
    option.None,
    decode.optional(decode.int),
  )
  use debug_logging <- decode.optional_field(
    "DebugLogging",
    option.None,
    decode.optional(decode.bool),
  )
  use tags <- decode.optional_field(
    "Tags",
    option.None,
    decode.optional(decode.list(decode_tag_struct_params())),
  )
  use endpoint_network_type <- decode.optional_field(
    "EndpointNetworkType",
    option.None,
    decode.optional(decode_endpoint_network_type_enum()),
  )
  use target_connection_network_type <- decode.optional_field(
    "TargetConnectionNetworkType",
    option.None,
    decode.optional(decode_target_connection_network_type_enum()),
  )
  decode.success(CreateDBProxyInput(
    db_proxy_name: db_proxy_name,
    engine_family: engine_family,
    default_auth_scheme: default_auth_scheme,
    auth: auth,
    role_arn: role_arn,
    vpc_subnet_ids: vpc_subnet_ids,
    vpc_security_group_ids: vpc_security_group_ids,
    require_tls: require_tls,
    idle_client_timeout: idle_client_timeout,
    debug_logging: debug_logging,
    tags: tags,
    endpoint_network_type: endpoint_network_type,
    target_connection_network_type: target_connection_network_type,
  ))
}

pub fn decode_create_db_proxy_input(
  json_string: String,
) -> Result(CreateDBProxyInput, String) {
  result.map_error(
    json.parse(json_string, decode_create_db_proxy_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_create_db_proxy_request(
  input: CreateDBProxyInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=CreateDBProxy&Version=2014-10-31"
  let body = {
    let v = input.db_proxy_name
    string.concat([
      body,
      string.concat(["&", "DBProxyName", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.engine_family
    string.concat([
      body,
      string.concat([
        "&",
        "EngineFamily",
        "=",
        uri.encode_component(engine_family_to_wire(v)),
      ]),
    ])
  }
  let body = case input.default_auth_scheme {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DefaultAuthScheme",
          "=",
          uri.encode_component(default_auth_scheme_to_wire(v)),
        ]),
      ])
  }
  let body = case input.auth {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Auth", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_user_auth_config_at(
                  string.concat(["Auth", ".member.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = {
    let v = input.role_arn
    string.concat([
      body,
      string.concat(["&", "RoleArn", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.vpc_subnet_ids
    string.concat([
      body,
      case v {
        [] -> string.concat(["&", "VpcSubnetIds", "=", ""])
        _ ->
          list.index_fold(v, "", fn(acc, item, idx) {
            string.concat([
              acc,
              string.concat([
                "&",
                string.concat([
                  "VpcSubnetIds",
                  ".member.",
                  int.to_string(idx + 1),
                ]),
                "=",
                uri.encode_component(item),
              ]),
            ])
          })
      },
    ])
  }
  let body = case input.vpc_security_group_ids {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "VpcSecurityGroupIds", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "VpcSecurityGroupIds",
                    ".member.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body = case input.require_tls {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "RequireTLS",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.idle_client_timeout {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "IdleClientTimeout", "=", int.to_string(v)]),
      ])
  }
  let body = case input.debug_logging {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DebugLogging",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.tags {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Tags", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_tag_at(
                  string.concat(["Tags", ".Tag.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.endpoint_network_type {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EndpointNetworkType",
          "=",
          uri.encode_component(endpoint_network_type_to_wire(v)),
        ]),
      ])
  }
  let body = case input.target_connection_network_type {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "TargetConnectionNetworkType",
          "=",
          uri.encode_component(target_connection_network_type_to_wire(v)),
        ]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_create_db_proxy_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(CreateDBProxyOutput, String) {
  Ok(CreateDBProxyOutput)
}

pub type CreateDBProxyEndpointInput {
  CreateDBProxyEndpointInput(
    db_proxy_name: String,
    db_proxy_endpoint_name: String,
    vpc_subnet_ids: List(String),
    vpc_security_group_ids: option.Option(List(String)),
    target_role: option.Option(DBProxyEndpointTargetRole),
    tags: option.Option(List(Tag)),
    endpoint_network_type: option.Option(EndpointNetworkType),
  )
}

pub fn create_db_proxy_endpoint_input_default(
  db_proxy_name db_proxy_name: String,
  db_proxy_endpoint_name db_proxy_endpoint_name: String,
  vpc_subnet_ids vpc_subnet_ids: List(String),
) -> CreateDBProxyEndpointInput {
  CreateDBProxyEndpointInput(
    db_proxy_name: db_proxy_name,
    db_proxy_endpoint_name: db_proxy_endpoint_name,
    vpc_subnet_ids: vpc_subnet_ids,
    vpc_security_group_ids: option.None,
    target_role: option.None,
    tags: option.None,
    endpoint_network_type: option.None,
  )
}

pub type CreateDBProxyEndpointOutput {
  CreateDBProxyEndpointOutput
}

pub fn decode_create_db_proxy_endpoint_input_struct() -> decode.Decoder(
  CreateDBProxyEndpointInput,
) {
  use <- decode.recursive
  use db_proxy_name <- decode.field("DBProxyName", decode.string)
  use db_proxy_endpoint_name <- decode.field(
    "DBProxyEndpointName",
    decode.string,
  )
  use vpc_subnet_ids <- decode.field("VpcSubnetIds", decode.list(decode.string))
  use vpc_security_group_ids <- decode.optional_field(
    "VpcSecurityGroupIds",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use target_role <- decode.optional_field(
    "TargetRole",
    option.None,
    decode.optional(decode_db_proxy_endpoint_target_role_enum()),
  )
  use tags <- decode.optional_field(
    "Tags",
    option.None,
    decode.optional(decode.list(decode_tag_struct_params())),
  )
  use endpoint_network_type <- decode.optional_field(
    "EndpointNetworkType",
    option.None,
    decode.optional(decode_endpoint_network_type_enum()),
  )
  decode.success(CreateDBProxyEndpointInput(
    db_proxy_name: db_proxy_name,
    db_proxy_endpoint_name: db_proxy_endpoint_name,
    vpc_subnet_ids: vpc_subnet_ids,
    vpc_security_group_ids: vpc_security_group_ids,
    target_role: target_role,
    tags: tags,
    endpoint_network_type: endpoint_network_type,
  ))
}

pub fn decode_create_db_proxy_endpoint_input(
  json_string: String,
) -> Result(CreateDBProxyEndpointInput, String) {
  result.map_error(
    json.parse(json_string, decode_create_db_proxy_endpoint_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_create_db_proxy_endpoint_request(
  input: CreateDBProxyEndpointInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=CreateDBProxyEndpoint&Version=2014-10-31"
  let body = {
    let v = input.db_proxy_name
    string.concat([
      body,
      string.concat(["&", "DBProxyName", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.db_proxy_endpoint_name
    string.concat([
      body,
      string.concat(["&", "DBProxyEndpointName", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.vpc_subnet_ids
    string.concat([
      body,
      case v {
        [] -> string.concat(["&", "VpcSubnetIds", "=", ""])
        _ ->
          list.index_fold(v, "", fn(acc, item, idx) {
            string.concat([
              acc,
              string.concat([
                "&",
                string.concat([
                  "VpcSubnetIds",
                  ".member.",
                  int.to_string(idx + 1),
                ]),
                "=",
                uri.encode_component(item),
              ]),
            ])
          })
      },
    ])
  }
  let body = case input.vpc_security_group_ids {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "VpcSecurityGroupIds", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "VpcSecurityGroupIds",
                    ".member.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body = case input.target_role {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "TargetRole",
          "=",
          uri.encode_component(db_proxy_endpoint_target_role_to_wire(v)),
        ]),
      ])
  }
  let body = case input.tags {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Tags", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_tag_at(
                  string.concat(["Tags", ".Tag.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.endpoint_network_type {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EndpointNetworkType",
          "=",
          uri.encode_component(endpoint_network_type_to_wire(v)),
        ]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_create_db_proxy_endpoint_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(CreateDBProxyEndpointOutput, String) {
  Ok(CreateDBProxyEndpointOutput)
}

pub type CreateDBSecurityGroupInput {
  CreateDBSecurityGroupInput(
    db_security_group_name: String,
    db_security_group_description: String,
    tags: option.Option(List(Tag)),
  )
}

pub fn create_db_security_group_input_default(
  db_security_group_name db_security_group_name: String,
  db_security_group_description db_security_group_description: String,
) -> CreateDBSecurityGroupInput {
  CreateDBSecurityGroupInput(
    db_security_group_name: db_security_group_name,
    db_security_group_description: db_security_group_description,
    tags: option.None,
  )
}

pub type CreateDBSecurityGroupOutput {
  CreateDBSecurityGroupOutput
}

pub fn decode_create_db_security_group_input_struct() -> decode.Decoder(
  CreateDBSecurityGroupInput,
) {
  use <- decode.recursive
  use db_security_group_name <- decode.field(
    "DBSecurityGroupName",
    decode.string,
  )
  use db_security_group_description <- decode.field(
    "DBSecurityGroupDescription",
    decode.string,
  )
  use tags <- decode.optional_field(
    "Tags",
    option.None,
    decode.optional(decode.list(decode_tag_struct_params())),
  )
  decode.success(CreateDBSecurityGroupInput(
    db_security_group_name: db_security_group_name,
    db_security_group_description: db_security_group_description,
    tags: tags,
  ))
}

pub fn decode_create_db_security_group_input(
  json_string: String,
) -> Result(CreateDBSecurityGroupInput, String) {
  result.map_error(
    json.parse(json_string, decode_create_db_security_group_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_create_db_security_group_request(
  input: CreateDBSecurityGroupInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=CreateDBSecurityGroup&Version=2014-10-31"
  let body = {
    let v = input.db_security_group_name
    string.concat([
      body,
      string.concat(["&", "DBSecurityGroupName", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.db_security_group_description
    string.concat([
      body,
      string.concat([
        "&",
        "DBSecurityGroupDescription",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body = case input.tags {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Tags", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_tag_at(
                  string.concat(["Tags", ".Tag.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_create_db_security_group_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(CreateDBSecurityGroupOutput, String) {
  Ok(CreateDBSecurityGroupOutput)
}

pub type CreateDBShardGroupInput {
  CreateDBShardGroupInput(
    db_shard_group_identifier: String,
    db_cluster_identifier: String,
    compute_redundancy: option.Option(Int),
    max_acu: json_float.SmithyFloat,
    min_acu: option.Option(json_float.SmithyFloat),
    publicly_accessible: option.Option(Bool),
    tags: option.Option(List(Tag)),
  )
}

pub fn create_db_shard_group_input_default(
  db_shard_group_identifier db_shard_group_identifier: String,
  db_cluster_identifier db_cluster_identifier: String,
  max_acu max_acu: json_float.SmithyFloat,
) -> CreateDBShardGroupInput {
  CreateDBShardGroupInput(
    db_shard_group_identifier: db_shard_group_identifier,
    db_cluster_identifier: db_cluster_identifier,
    compute_redundancy: option.None,
    max_acu: max_acu,
    min_acu: option.None,
    publicly_accessible: option.None,
    tags: option.None,
  )
}

pub type CreateDBShardGroupOutput {
  CreateDBShardGroupOutput
}

pub fn decode_create_db_shard_group_input_struct() -> decode.Decoder(
  CreateDBShardGroupInput,
) {
  use <- decode.recursive
  use db_shard_group_identifier <- decode.field(
    "DBShardGroupIdentifier",
    decode.string,
  )
  use db_cluster_identifier <- decode.field(
    "DBClusterIdentifier",
    decode.string,
  )
  use compute_redundancy <- decode.optional_field(
    "ComputeRedundancy",
    option.None,
    decode.optional(decode.int),
  )
  use max_acu <- decode.field("MaxACU", json_float.decoder())
  use min_acu <- decode.optional_field(
    "MinACU",
    option.None,
    decode.optional(json_float.decoder()),
  )
  use publicly_accessible <- decode.optional_field(
    "PubliclyAccessible",
    option.None,
    decode.optional(decode.bool),
  )
  use tags <- decode.optional_field(
    "Tags",
    option.None,
    decode.optional(decode.list(decode_tag_struct_params())),
  )
  decode.success(CreateDBShardGroupInput(
    db_shard_group_identifier: db_shard_group_identifier,
    db_cluster_identifier: db_cluster_identifier,
    compute_redundancy: compute_redundancy,
    max_acu: max_acu,
    min_acu: min_acu,
    publicly_accessible: publicly_accessible,
    tags: tags,
  ))
}

pub fn decode_create_db_shard_group_input(
  json_string: String,
) -> Result(CreateDBShardGroupInput, String) {
  result.map_error(
    json.parse(json_string, decode_create_db_shard_group_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_create_db_shard_group_request(
  input: CreateDBShardGroupInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=CreateDBShardGroup&Version=2014-10-31"
  let body = {
    let v = input.db_shard_group_identifier
    string.concat([
      body,
      string.concat([
        "&",
        "DBShardGroupIdentifier",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body = {
    let v = input.db_cluster_identifier
    string.concat([
      body,
      string.concat(["&", "DBClusterIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.compute_redundancy {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "ComputeRedundancy", "=", int.to_string(v)]),
      ])
  }
  let body = {
    let v = input.max_acu
    string.concat([
      body,
      string.concat(["&", "MaxACU", "=", format_smithy_float(v)]),
    ])
  }
  let body = case input.min_acu {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MinACU", "=", format_smithy_float(v)]),
      ])
  }
  let body = case input.publicly_accessible {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "PubliclyAccessible",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.tags {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Tags", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_tag_at(
                  string.concat(["Tags", ".Tag.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_create_db_shard_group_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(CreateDBShardGroupOutput, String) {
  Ok(CreateDBShardGroupOutput)
}

pub type CreateDBSnapshotInput {
  CreateDBSnapshotInput(
    db_snapshot_identifier: String,
    db_instance_identifier: String,
    tags: option.Option(List(Tag)),
  )
}

pub fn create_db_snapshot_input_default(
  db_snapshot_identifier db_snapshot_identifier: String,
  db_instance_identifier db_instance_identifier: String,
) -> CreateDBSnapshotInput {
  CreateDBSnapshotInput(
    db_snapshot_identifier: db_snapshot_identifier,
    db_instance_identifier: db_instance_identifier,
    tags: option.None,
  )
}

pub type CreateDBSnapshotOutput {
  CreateDBSnapshotOutput
}

pub fn decode_create_db_snapshot_input_struct() -> decode.Decoder(
  CreateDBSnapshotInput,
) {
  use <- decode.recursive
  use db_snapshot_identifier <- decode.field(
    "DBSnapshotIdentifier",
    decode.string,
  )
  use db_instance_identifier <- decode.field(
    "DBInstanceIdentifier",
    decode.string,
  )
  use tags <- decode.optional_field(
    "Tags",
    option.None,
    decode.optional(decode.list(decode_tag_struct_params())),
  )
  decode.success(CreateDBSnapshotInput(
    db_snapshot_identifier: db_snapshot_identifier,
    db_instance_identifier: db_instance_identifier,
    tags: tags,
  ))
}

pub fn decode_create_db_snapshot_input(
  json_string: String,
) -> Result(CreateDBSnapshotInput, String) {
  result.map_error(
    json.parse(json_string, decode_create_db_snapshot_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_create_db_snapshot_request(
  input: CreateDBSnapshotInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=CreateDBSnapshot&Version=2014-10-31"
  let body = {
    let v = input.db_snapshot_identifier
    string.concat([
      body,
      string.concat(["&", "DBSnapshotIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.db_instance_identifier
    string.concat([
      body,
      string.concat(["&", "DBInstanceIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.tags {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Tags", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_tag_at(
                  string.concat(["Tags", ".Tag.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_create_db_snapshot_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(CreateDBSnapshotOutput, String) {
  Ok(CreateDBSnapshotOutput)
}

pub type CreateDBSubnetGroupInput {
  CreateDBSubnetGroupInput(
    db_subnet_group_name: String,
    db_subnet_group_description: String,
    subnet_ids: List(String),
    tags: option.Option(List(Tag)),
  )
}

pub fn create_db_subnet_group_input_default(
  db_subnet_group_name db_subnet_group_name: String,
  db_subnet_group_description db_subnet_group_description: String,
  subnet_ids subnet_ids: List(String),
) -> CreateDBSubnetGroupInput {
  CreateDBSubnetGroupInput(
    db_subnet_group_name: db_subnet_group_name,
    db_subnet_group_description: db_subnet_group_description,
    subnet_ids: subnet_ids,
    tags: option.None,
  )
}

pub type CreateDBSubnetGroupOutput {
  CreateDBSubnetGroupOutput
}

pub fn decode_create_db_subnet_group_input_struct() -> decode.Decoder(
  CreateDBSubnetGroupInput,
) {
  use <- decode.recursive
  use db_subnet_group_name <- decode.field("DBSubnetGroupName", decode.string)
  use db_subnet_group_description <- decode.field(
    "DBSubnetGroupDescription",
    decode.string,
  )
  use subnet_ids <- decode.field("SubnetIds", decode.list(decode.string))
  use tags <- decode.optional_field(
    "Tags",
    option.None,
    decode.optional(decode.list(decode_tag_struct_params())),
  )
  decode.success(CreateDBSubnetGroupInput(
    db_subnet_group_name: db_subnet_group_name,
    db_subnet_group_description: db_subnet_group_description,
    subnet_ids: subnet_ids,
    tags: tags,
  ))
}

pub fn decode_create_db_subnet_group_input(
  json_string: String,
) -> Result(CreateDBSubnetGroupInput, String) {
  result.map_error(
    json.parse(json_string, decode_create_db_subnet_group_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_create_db_subnet_group_request(
  input: CreateDBSubnetGroupInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=CreateDBSubnetGroup&Version=2014-10-31"
  let body = {
    let v = input.db_subnet_group_name
    string.concat([
      body,
      string.concat(["&", "DBSubnetGroupName", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.db_subnet_group_description
    string.concat([
      body,
      string.concat([
        "&",
        "DBSubnetGroupDescription",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body = {
    let v = input.subnet_ids
    string.concat([
      body,
      case v {
        [] -> string.concat(["&", "SubnetIds", "=", ""])
        _ ->
          list.index_fold(v, "", fn(acc, item, idx) {
            string.concat([
              acc,
              string.concat([
                "&",
                string.concat([
                  "SubnetIds",
                  ".SubnetIdentifier.",
                  int.to_string(idx + 1),
                ]),
                "=",
                uri.encode_component(item),
              ]),
            ])
          })
      },
    ])
  }
  let body = case input.tags {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Tags", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_tag_at(
                  string.concat(["Tags", ".Tag.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_create_db_subnet_group_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(CreateDBSubnetGroupOutput, String) {
  Ok(CreateDBSubnetGroupOutput)
}

pub type CreateEventSubscriptionInput {
  CreateEventSubscriptionInput(
    subscription_name: String,
    sns_topic_arn: String,
    source_type: option.Option(String),
    event_categories: option.Option(List(String)),
    source_ids: option.Option(List(String)),
    enabled: option.Option(Bool),
    tags: option.Option(List(Tag)),
  )
}

pub fn create_event_subscription_input_default(
  subscription_name subscription_name: String,
  sns_topic_arn sns_topic_arn: String,
) -> CreateEventSubscriptionInput {
  CreateEventSubscriptionInput(
    subscription_name: subscription_name,
    sns_topic_arn: sns_topic_arn,
    source_type: option.None,
    event_categories: option.None,
    source_ids: option.None,
    enabled: option.None,
    tags: option.None,
  )
}

pub type CreateEventSubscriptionOutput {
  CreateEventSubscriptionOutput
}

pub fn decode_create_event_subscription_input_struct() -> decode.Decoder(
  CreateEventSubscriptionInput,
) {
  use <- decode.recursive
  use subscription_name <- decode.field("SubscriptionName", decode.string)
  use sns_topic_arn <- decode.field("SnsTopicArn", decode.string)
  use source_type <- decode.optional_field(
    "SourceType",
    option.None,
    decode.optional(decode.string),
  )
  use event_categories <- decode.optional_field(
    "EventCategories",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use source_ids <- decode.optional_field(
    "SourceIds",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use enabled <- decode.optional_field(
    "Enabled",
    option.None,
    decode.optional(decode.bool),
  )
  use tags <- decode.optional_field(
    "Tags",
    option.None,
    decode.optional(decode.list(decode_tag_struct_params())),
  )
  decode.success(CreateEventSubscriptionInput(
    subscription_name: subscription_name,
    sns_topic_arn: sns_topic_arn,
    source_type: source_type,
    event_categories: event_categories,
    source_ids: source_ids,
    enabled: enabled,
    tags: tags,
  ))
}

pub fn decode_create_event_subscription_input(
  json_string: String,
) -> Result(CreateEventSubscriptionInput, String) {
  result.map_error(
    json.parse(json_string, decode_create_event_subscription_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_create_event_subscription_request(
  input: CreateEventSubscriptionInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=CreateEventSubscription&Version=2014-10-31"
  let body = {
    let v = input.subscription_name
    string.concat([
      body,
      string.concat(["&", "SubscriptionName", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.sns_topic_arn
    string.concat([
      body,
      string.concat(["&", "SnsTopicArn", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.source_type {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "SourceType", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.event_categories {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "EventCategories", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "EventCategories",
                    ".EventCategory.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body = case input.source_ids {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "SourceIds", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "SourceIds",
                    ".SourceId.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body = case input.enabled {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "Enabled",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.tags {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Tags", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_tag_at(
                  string.concat(["Tags", ".Tag.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_create_event_subscription_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(CreateEventSubscriptionOutput, String) {
  Ok(CreateEventSubscriptionOutput)
}

pub type CreateGlobalClusterInput {
  CreateGlobalClusterInput(
    global_cluster_identifier: String,
    source_db_cluster_identifier: option.Option(String),
    engine: option.Option(String),
    engine_version: option.Option(String),
    engine_lifecycle_support: option.Option(String),
    deletion_protection: option.Option(Bool),
    database_name: option.Option(String),
    storage_encrypted: option.Option(Bool),
    tags: option.Option(List(Tag)),
  )
}

pub fn create_global_cluster_input_default(
  global_cluster_identifier global_cluster_identifier: String,
) -> CreateGlobalClusterInput {
  CreateGlobalClusterInput(
    global_cluster_identifier: global_cluster_identifier,
    source_db_cluster_identifier: option.None,
    engine: option.None,
    engine_version: option.None,
    engine_lifecycle_support: option.None,
    deletion_protection: option.None,
    database_name: option.None,
    storage_encrypted: option.None,
    tags: option.None,
  )
}

pub type CreateGlobalClusterOutput {
  CreateGlobalClusterOutput
}

pub fn decode_create_global_cluster_input_struct() -> decode.Decoder(
  CreateGlobalClusterInput,
) {
  use <- decode.recursive
  use global_cluster_identifier <- decode.field(
    "GlobalClusterIdentifier",
    decode.string,
  )
  use source_db_cluster_identifier <- decode.optional_field(
    "SourceDBClusterIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use engine <- decode.optional_field(
    "Engine",
    option.None,
    decode.optional(decode.string),
  )
  use engine_version <- decode.optional_field(
    "EngineVersion",
    option.None,
    decode.optional(decode.string),
  )
  use engine_lifecycle_support <- decode.optional_field(
    "EngineLifecycleSupport",
    option.None,
    decode.optional(decode.string),
  )
  use deletion_protection <- decode.optional_field(
    "DeletionProtection",
    option.None,
    decode.optional(decode.bool),
  )
  use database_name <- decode.optional_field(
    "DatabaseName",
    option.None,
    decode.optional(decode.string),
  )
  use storage_encrypted <- decode.optional_field(
    "StorageEncrypted",
    option.None,
    decode.optional(decode.bool),
  )
  use tags <- decode.optional_field(
    "Tags",
    option.None,
    decode.optional(decode.list(decode_tag_struct_params())),
  )
  decode.success(CreateGlobalClusterInput(
    global_cluster_identifier: global_cluster_identifier,
    source_db_cluster_identifier: source_db_cluster_identifier,
    engine: engine,
    engine_version: engine_version,
    engine_lifecycle_support: engine_lifecycle_support,
    deletion_protection: deletion_protection,
    database_name: database_name,
    storage_encrypted: storage_encrypted,
    tags: tags,
  ))
}

pub fn decode_create_global_cluster_input(
  json_string: String,
) -> Result(CreateGlobalClusterInput, String) {
  result.map_error(
    json.parse(json_string, decode_create_global_cluster_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_create_global_cluster_request(
  input: CreateGlobalClusterInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=CreateGlobalCluster&Version=2014-10-31"
  let body = {
    let v = input.global_cluster_identifier
    string.concat([
      body,
      string.concat([
        "&",
        "GlobalClusterIdentifier",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body = case input.source_db_cluster_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "SourceDBClusterIdentifier",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.engine {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Engine", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.engine_version {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "EngineVersion", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.engine_lifecycle_support {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EngineLifecycleSupport",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.deletion_protection {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DeletionProtection",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.database_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DatabaseName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.storage_encrypted {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "StorageEncrypted",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.tags {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Tags", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_tag_at(
                  string.concat(["Tags", ".Tag.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_create_global_cluster_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(CreateGlobalClusterOutput, String) {
  Ok(CreateGlobalClusterOutput)
}

pub type CreateIntegrationInput {
  CreateIntegrationInput(
    source_arn: String,
    target_arn: String,
    integration_name: String,
    kms_key_id: option.Option(String),
    additional_encryption_context: option.Option(dict.Dict(String, String)),
    tags: option.Option(List(Tag)),
    data_filter: option.Option(String),
    description: option.Option(String),
  )
}

pub fn create_integration_input_default(
  source_arn source_arn: String,
  target_arn target_arn: String,
  integration_name integration_name: String,
) -> CreateIntegrationInput {
  CreateIntegrationInput(
    source_arn: source_arn,
    target_arn: target_arn,
    integration_name: integration_name,
    kms_key_id: option.None,
    additional_encryption_context: option.None,
    tags: option.None,
    data_filter: option.None,
    description: option.None,
  )
}

pub type CreateIntegrationOutput {
  CreateIntegrationOutput
}

pub fn decode_create_integration_input_struct() -> decode.Decoder(
  CreateIntegrationInput,
) {
  use <- decode.recursive
  use source_arn <- decode.field("SourceArn", decode.string)
  use target_arn <- decode.field("TargetArn", decode.string)
  use integration_name <- decode.field("IntegrationName", decode.string)
  use kms_key_id <- decode.optional_field(
    "KMSKeyId",
    option.None,
    decode.optional(decode.string),
  )
  use additional_encryption_context <- decode.optional_field(
    "AdditionalEncryptionContext",
    option.None,
    decode.optional(decode.dict(decode.string, decode.string)),
  )
  use tags <- decode.optional_field(
    "Tags",
    option.None,
    decode.optional(decode.list(decode_tag_struct_params())),
  )
  use data_filter <- decode.optional_field(
    "DataFilter",
    option.None,
    decode.optional(decode.string),
  )
  use description <- decode.optional_field(
    "Description",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(CreateIntegrationInput(
    source_arn: source_arn,
    target_arn: target_arn,
    integration_name: integration_name,
    kms_key_id: kms_key_id,
    additional_encryption_context: additional_encryption_context,
    tags: tags,
    data_filter: data_filter,
    description: description,
  ))
}

pub fn decode_create_integration_input(
  json_string: String,
) -> Result(CreateIntegrationInput, String) {
  result.map_error(
    json.parse(json_string, decode_create_integration_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_create_integration_request(
  input: CreateIntegrationInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=CreateIntegration&Version=2014-10-31"
  let body = {
    let v = input.source_arn
    string.concat([
      body,
      string.concat(["&", "SourceArn", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.target_arn
    string.concat([
      body,
      string.concat(["&", "TargetArn", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.integration_name
    string.concat([
      body,
      string.concat(["&", "IntegrationName", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.kms_key_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "KMSKeyId", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.additional_encryption_context {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case dict.size(v) {
          0 -> ""
          _ -> {
            let entries =
              dict.to_list(v)
              |> list.sort(fn(a, b) { string.compare(a.0, b.0) })
            list.index_fold(entries, "", fn(acc, pair, idx) {
              let #(k, v) = pair
              let entry_prefix =
                string.concat([
                  "AdditionalEncryptionContext",
                  ".entry.",
                  int.to_string(idx + 1),
                ])
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([entry_prefix, ".key"]),
                  "=",
                  uri.encode_component(k),
                ]),
                string.concat([
                  "&",
                  string.concat([entry_prefix, ".value"]),
                  "=",
                  uri.encode_component(v),
                ]),
              ])
            })
          }
        },
      ])
  }
  let body = case input.tags {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Tags", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_tag_at(
                  string.concat(["Tags", ".Tag.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.data_filter {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DataFilter", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.description {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Description", "=", uri.encode_component(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_create_integration_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(CreateIntegrationOutput, String) {
  Ok(CreateIntegrationOutput)
}

pub type CreateOptionGroupInput {
  CreateOptionGroupInput(
    option_group_name: String,
    engine_name: String,
    major_engine_version: String,
    option_group_description: String,
    tags: option.Option(List(Tag)),
  )
}

pub fn create_option_group_input_default(
  option_group_name option_group_name: String,
  engine_name engine_name: String,
  major_engine_version major_engine_version: String,
  option_group_description option_group_description: String,
) -> CreateOptionGroupInput {
  CreateOptionGroupInput(
    option_group_name: option_group_name,
    engine_name: engine_name,
    major_engine_version: major_engine_version,
    option_group_description: option_group_description,
    tags: option.None,
  )
}

pub type CreateOptionGroupOutput {
  CreateOptionGroupOutput
}

pub fn decode_create_option_group_input_struct() -> decode.Decoder(
  CreateOptionGroupInput,
) {
  use <- decode.recursive
  use option_group_name <- decode.field("OptionGroupName", decode.string)
  use engine_name <- decode.field("EngineName", decode.string)
  use major_engine_version <- decode.field("MajorEngineVersion", decode.string)
  use option_group_description <- decode.field(
    "OptionGroupDescription",
    decode.string,
  )
  use tags <- decode.optional_field(
    "Tags",
    option.None,
    decode.optional(decode.list(decode_tag_struct_params())),
  )
  decode.success(CreateOptionGroupInput(
    option_group_name: option_group_name,
    engine_name: engine_name,
    major_engine_version: major_engine_version,
    option_group_description: option_group_description,
    tags: tags,
  ))
}

pub fn decode_create_option_group_input(
  json_string: String,
) -> Result(CreateOptionGroupInput, String) {
  result.map_error(
    json.parse(json_string, decode_create_option_group_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_create_option_group_request(
  input: CreateOptionGroupInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=CreateOptionGroup&Version=2014-10-31"
  let body = {
    let v = input.option_group_name
    string.concat([
      body,
      string.concat(["&", "OptionGroupName", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.engine_name
    string.concat([
      body,
      string.concat(["&", "EngineName", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.major_engine_version
    string.concat([
      body,
      string.concat(["&", "MajorEngineVersion", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.option_group_description
    string.concat([
      body,
      string.concat([
        "&",
        "OptionGroupDescription",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body = case input.tags {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Tags", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_tag_at(
                  string.concat(["Tags", ".Tag.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_create_option_group_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(CreateOptionGroupOutput, String) {
  Ok(CreateOptionGroupOutput)
}

pub type CreateTenantDatabaseInput {
  CreateTenantDatabaseInput(
    db_instance_identifier: String,
    tenant_db_name: String,
    master_username: String,
    master_user_password: option.Option(String),
    character_set_name: option.Option(String),
    nchar_character_set_name: option.Option(String),
    manage_master_user_password: option.Option(Bool),
    master_user_secret_kms_key_id: option.Option(String),
    tags: option.Option(List(Tag)),
  )
}

pub fn create_tenant_database_input_default(
  db_instance_identifier db_instance_identifier: String,
  tenant_db_name tenant_db_name: String,
  master_username master_username: String,
) -> CreateTenantDatabaseInput {
  CreateTenantDatabaseInput(
    db_instance_identifier: db_instance_identifier,
    tenant_db_name: tenant_db_name,
    master_username: master_username,
    master_user_password: option.None,
    character_set_name: option.None,
    nchar_character_set_name: option.None,
    manage_master_user_password: option.None,
    master_user_secret_kms_key_id: option.None,
    tags: option.None,
  )
}

pub type CreateTenantDatabaseOutput {
  CreateTenantDatabaseOutput
}

pub fn decode_create_tenant_database_input_struct() -> decode.Decoder(
  CreateTenantDatabaseInput,
) {
  use <- decode.recursive
  use db_instance_identifier <- decode.field(
    "DBInstanceIdentifier",
    decode.string,
  )
  use tenant_db_name <- decode.field("TenantDBName", decode.string)
  use master_username <- decode.field("MasterUsername", decode.string)
  use master_user_password <- decode.optional_field(
    "MasterUserPassword",
    option.None,
    decode.optional(decode.string),
  )
  use character_set_name <- decode.optional_field(
    "CharacterSetName",
    option.None,
    decode.optional(decode.string),
  )
  use nchar_character_set_name <- decode.optional_field(
    "NcharCharacterSetName",
    option.None,
    decode.optional(decode.string),
  )
  use manage_master_user_password <- decode.optional_field(
    "ManageMasterUserPassword",
    option.None,
    decode.optional(decode.bool),
  )
  use master_user_secret_kms_key_id <- decode.optional_field(
    "MasterUserSecretKmsKeyId",
    option.None,
    decode.optional(decode.string),
  )
  use tags <- decode.optional_field(
    "Tags",
    option.None,
    decode.optional(decode.list(decode_tag_struct_params())),
  )
  decode.success(CreateTenantDatabaseInput(
    db_instance_identifier: db_instance_identifier,
    tenant_db_name: tenant_db_name,
    master_username: master_username,
    master_user_password: master_user_password,
    character_set_name: character_set_name,
    nchar_character_set_name: nchar_character_set_name,
    manage_master_user_password: manage_master_user_password,
    master_user_secret_kms_key_id: master_user_secret_kms_key_id,
    tags: tags,
  ))
}

pub fn decode_create_tenant_database_input(
  json_string: String,
) -> Result(CreateTenantDatabaseInput, String) {
  result.map_error(
    json.parse(json_string, decode_create_tenant_database_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_create_tenant_database_request(
  input: CreateTenantDatabaseInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=CreateTenantDatabase&Version=2014-10-31"
  let body = {
    let v = input.db_instance_identifier
    string.concat([
      body,
      string.concat(["&", "DBInstanceIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.tenant_db_name
    string.concat([
      body,
      string.concat(["&", "TenantDBName", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.master_username
    string.concat([
      body,
      string.concat(["&", "MasterUsername", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.master_user_password {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MasterUserPassword", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.character_set_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "CharacterSetName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.nchar_character_set_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "NcharCharacterSetName",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.manage_master_user_password {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "ManageMasterUserPassword",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.master_user_secret_kms_key_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "MasterUserSecretKmsKeyId",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.tags {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Tags", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_tag_at(
                  string.concat(["Tags", ".Tag.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_create_tenant_database_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(CreateTenantDatabaseOutput, String) {
  Ok(CreateTenantDatabaseOutput)
}

pub type DeleteBlueGreenDeploymentInput {
  DeleteBlueGreenDeploymentInput(
    blue_green_deployment_identifier: String,
    delete_target: option.Option(Bool),
  )
}

pub fn delete_blue_green_deployment_input_default(
  blue_green_deployment_identifier blue_green_deployment_identifier: String,
) -> DeleteBlueGreenDeploymentInput {
  DeleteBlueGreenDeploymentInput(
    blue_green_deployment_identifier: blue_green_deployment_identifier,
    delete_target: option.None,
  )
}

pub type DeleteBlueGreenDeploymentOutput {
  DeleteBlueGreenDeploymentOutput
}

pub fn decode_delete_blue_green_deployment_input_struct() -> decode.Decoder(
  DeleteBlueGreenDeploymentInput,
) {
  use <- decode.recursive
  use blue_green_deployment_identifier <- decode.field(
    "BlueGreenDeploymentIdentifier",
    decode.string,
  )
  use delete_target <- decode.optional_field(
    "DeleteTarget",
    option.None,
    decode.optional(decode.bool),
  )
  decode.success(DeleteBlueGreenDeploymentInput(
    blue_green_deployment_identifier: blue_green_deployment_identifier,
    delete_target: delete_target,
  ))
}

pub fn decode_delete_blue_green_deployment_input(
  json_string: String,
) -> Result(DeleteBlueGreenDeploymentInput, String) {
  result.map_error(
    json.parse(json_string, decode_delete_blue_green_deployment_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_delete_blue_green_deployment_request(
  input: DeleteBlueGreenDeploymentInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DeleteBlueGreenDeployment&Version=2014-10-31"
  let body = {
    let v = input.blue_green_deployment_identifier
    string.concat([
      body,
      string.concat([
        "&",
        "BlueGreenDeploymentIdentifier",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body = case input.delete_target {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DeleteTarget",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_delete_blue_green_deployment_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DeleteBlueGreenDeploymentOutput, String) {
  Ok(DeleteBlueGreenDeploymentOutput)
}

pub type DeleteCustomDBEngineVersionInput {
  DeleteCustomDBEngineVersionInput(engine: String, engine_version: String)
}

pub fn delete_custom_db_engine_version_input_default(
  engine engine: String,
  engine_version engine_version: String,
) -> DeleteCustomDBEngineVersionInput {
  DeleteCustomDBEngineVersionInput(
    engine: engine,
    engine_version: engine_version,
  )
}

pub type DeleteCustomDBEngineVersionOutput {
  DeleteCustomDBEngineVersionOutput
}

pub fn decode_delete_custom_db_engine_version_input_struct() -> decode.Decoder(
  DeleteCustomDBEngineVersionInput,
) {
  use <- decode.recursive
  use engine <- decode.field("Engine", decode.string)
  use engine_version <- decode.field("EngineVersion", decode.string)
  decode.success(DeleteCustomDBEngineVersionInput(
    engine: engine,
    engine_version: engine_version,
  ))
}

pub fn decode_delete_custom_db_engine_version_input(
  json_string: String,
) -> Result(DeleteCustomDBEngineVersionInput, String) {
  result.map_error(
    json.parse(
      json_string,
      decode_delete_custom_db_engine_version_input_struct(),
    ),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_delete_custom_db_engine_version_request(
  input: DeleteCustomDBEngineVersionInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DeleteCustomDBEngineVersion&Version=2014-10-31"
  let body = {
    let v = input.engine
    string.concat([
      body,
      string.concat(["&", "Engine", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.engine_version
    string.concat([
      body,
      string.concat(["&", "EngineVersion", "=", uri.encode_component(v)]),
    ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_delete_custom_db_engine_version_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DeleteCustomDBEngineVersionOutput, String) {
  Ok(DeleteCustomDBEngineVersionOutput)
}

pub type DeleteDBClusterInput {
  DeleteDBClusterInput(
    db_cluster_identifier: String,
    skip_final_snapshot: option.Option(Bool),
    final_db_snapshot_identifier: option.Option(String),
    delete_automated_backups: option.Option(Bool),
  )
}

pub fn delete_db_cluster_input_default(
  db_cluster_identifier db_cluster_identifier: String,
) -> DeleteDBClusterInput {
  DeleteDBClusterInput(
    db_cluster_identifier: db_cluster_identifier,
    skip_final_snapshot: option.None,
    final_db_snapshot_identifier: option.None,
    delete_automated_backups: option.None,
  )
}

pub type DeleteDBClusterOutput {
  DeleteDBClusterOutput
}

pub fn decode_delete_db_cluster_input_struct() -> decode.Decoder(
  DeleteDBClusterInput,
) {
  use <- decode.recursive
  use db_cluster_identifier <- decode.field(
    "DBClusterIdentifier",
    decode.string,
  )
  use skip_final_snapshot <- decode.optional_field(
    "SkipFinalSnapshot",
    option.None,
    decode.optional(decode.bool),
  )
  use final_db_snapshot_identifier <- decode.optional_field(
    "FinalDBSnapshotIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use delete_automated_backups <- decode.optional_field(
    "DeleteAutomatedBackups",
    option.None,
    decode.optional(decode.bool),
  )
  decode.success(DeleteDBClusterInput(
    db_cluster_identifier: db_cluster_identifier,
    skip_final_snapshot: skip_final_snapshot,
    final_db_snapshot_identifier: final_db_snapshot_identifier,
    delete_automated_backups: delete_automated_backups,
  ))
}

pub fn decode_delete_db_cluster_input(
  json_string: String,
) -> Result(DeleteDBClusterInput, String) {
  result.map_error(
    json.parse(json_string, decode_delete_db_cluster_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_delete_db_cluster_request(
  input: DeleteDBClusterInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DeleteDBCluster&Version=2014-10-31"
  let body = {
    let v = input.db_cluster_identifier
    string.concat([
      body,
      string.concat(["&", "DBClusterIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.skip_final_snapshot {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "SkipFinalSnapshot",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.final_db_snapshot_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "FinalDBSnapshotIdentifier",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.delete_automated_backups {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DeleteAutomatedBackups",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_delete_db_cluster_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DeleteDBClusterOutput, String) {
  Ok(DeleteDBClusterOutput)
}

pub type DeleteDBClusterAutomatedBackupInput {
  DeleteDBClusterAutomatedBackupInput(db_cluster_resource_id: String)
}

pub fn delete_db_cluster_automated_backup_input_default(
  db_cluster_resource_id db_cluster_resource_id: String,
) -> DeleteDBClusterAutomatedBackupInput {
  DeleteDBClusterAutomatedBackupInput(
    db_cluster_resource_id: db_cluster_resource_id,
  )
}

pub type DeleteDBClusterAutomatedBackupOutput {
  DeleteDBClusterAutomatedBackupOutput
}

pub fn decode_delete_db_cluster_automated_backup_input_struct() -> decode.Decoder(
  DeleteDBClusterAutomatedBackupInput,
) {
  use <- decode.recursive
  use db_cluster_resource_id <- decode.field(
    "DbClusterResourceId",
    decode.string,
  )
  decode.success(DeleteDBClusterAutomatedBackupInput(
    db_cluster_resource_id: db_cluster_resource_id,
  ))
}

pub fn decode_delete_db_cluster_automated_backup_input(
  json_string: String,
) -> Result(DeleteDBClusterAutomatedBackupInput, String) {
  result.map_error(
    json.parse(
      json_string,
      decode_delete_db_cluster_automated_backup_input_struct(),
    ),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_delete_db_cluster_automated_backup_request(
  input: DeleteDBClusterAutomatedBackupInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DeleteDBClusterAutomatedBackup&Version=2014-10-31"
  let body = {
    let v = input.db_cluster_resource_id
    string.concat([
      body,
      string.concat(["&", "DbClusterResourceId", "=", uri.encode_component(v)]),
    ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_delete_db_cluster_automated_backup_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DeleteDBClusterAutomatedBackupOutput, String) {
  Ok(DeleteDBClusterAutomatedBackupOutput)
}

pub type DeleteDBClusterEndpointInput {
  DeleteDBClusterEndpointInput(db_cluster_endpoint_identifier: String)
}

pub fn delete_db_cluster_endpoint_input_default(
  db_cluster_endpoint_identifier db_cluster_endpoint_identifier: String,
) -> DeleteDBClusterEndpointInput {
  DeleteDBClusterEndpointInput(
    db_cluster_endpoint_identifier: db_cluster_endpoint_identifier,
  )
}

pub type DeleteDBClusterEndpointOutput {
  DeleteDBClusterEndpointOutput
}

pub fn decode_delete_db_cluster_endpoint_input_struct() -> decode.Decoder(
  DeleteDBClusterEndpointInput,
) {
  use <- decode.recursive
  use db_cluster_endpoint_identifier <- decode.field(
    "DBClusterEndpointIdentifier",
    decode.string,
  )
  decode.success(DeleteDBClusterEndpointInput(
    db_cluster_endpoint_identifier: db_cluster_endpoint_identifier,
  ))
}

pub fn decode_delete_db_cluster_endpoint_input(
  json_string: String,
) -> Result(DeleteDBClusterEndpointInput, String) {
  result.map_error(
    json.parse(json_string, decode_delete_db_cluster_endpoint_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_delete_db_cluster_endpoint_request(
  input: DeleteDBClusterEndpointInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DeleteDBClusterEndpoint&Version=2014-10-31"
  let body = {
    let v = input.db_cluster_endpoint_identifier
    string.concat([
      body,
      string.concat([
        "&",
        "DBClusterEndpointIdentifier",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_delete_db_cluster_endpoint_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DeleteDBClusterEndpointOutput, String) {
  Ok(DeleteDBClusterEndpointOutput)
}

pub type DeleteDBClusterParameterGroupInput {
  DeleteDBClusterParameterGroupInput(db_cluster_parameter_group_name: String)
}

pub fn delete_db_cluster_parameter_group_input_default(
  db_cluster_parameter_group_name db_cluster_parameter_group_name: String,
) -> DeleteDBClusterParameterGroupInput {
  DeleteDBClusterParameterGroupInput(
    db_cluster_parameter_group_name: db_cluster_parameter_group_name,
  )
}

pub type DeleteDBClusterParameterGroupOutput {
  DeleteDBClusterParameterGroupOutput
}

pub fn decode_delete_db_cluster_parameter_group_input_struct() -> decode.Decoder(
  DeleteDBClusterParameterGroupInput,
) {
  use <- decode.recursive
  use db_cluster_parameter_group_name <- decode.field(
    "DBClusterParameterGroupName",
    decode.string,
  )
  decode.success(DeleteDBClusterParameterGroupInput(
    db_cluster_parameter_group_name: db_cluster_parameter_group_name,
  ))
}

pub fn decode_delete_db_cluster_parameter_group_input(
  json_string: String,
) -> Result(DeleteDBClusterParameterGroupInput, String) {
  result.map_error(
    json.parse(
      json_string,
      decode_delete_db_cluster_parameter_group_input_struct(),
    ),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_delete_db_cluster_parameter_group_request(
  input: DeleteDBClusterParameterGroupInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DeleteDBClusterParameterGroup&Version=2014-10-31"
  let body = {
    let v = input.db_cluster_parameter_group_name
    string.concat([
      body,
      string.concat([
        "&",
        "DBClusterParameterGroupName",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_delete_db_cluster_parameter_group_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DeleteDBClusterParameterGroupOutput, String) {
  Ok(DeleteDBClusterParameterGroupOutput)
}

pub type DeleteDBClusterSnapshotInput {
  DeleteDBClusterSnapshotInput(db_cluster_snapshot_identifier: String)
}

pub fn delete_db_cluster_snapshot_input_default(
  db_cluster_snapshot_identifier db_cluster_snapshot_identifier: String,
) -> DeleteDBClusterSnapshotInput {
  DeleteDBClusterSnapshotInput(
    db_cluster_snapshot_identifier: db_cluster_snapshot_identifier,
  )
}

pub type DeleteDBClusterSnapshotOutput {
  DeleteDBClusterSnapshotOutput
}

pub fn decode_delete_db_cluster_snapshot_input_struct() -> decode.Decoder(
  DeleteDBClusterSnapshotInput,
) {
  use <- decode.recursive
  use db_cluster_snapshot_identifier <- decode.field(
    "DBClusterSnapshotIdentifier",
    decode.string,
  )
  decode.success(DeleteDBClusterSnapshotInput(
    db_cluster_snapshot_identifier: db_cluster_snapshot_identifier,
  ))
}

pub fn decode_delete_db_cluster_snapshot_input(
  json_string: String,
) -> Result(DeleteDBClusterSnapshotInput, String) {
  result.map_error(
    json.parse(json_string, decode_delete_db_cluster_snapshot_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_delete_db_cluster_snapshot_request(
  input: DeleteDBClusterSnapshotInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DeleteDBClusterSnapshot&Version=2014-10-31"
  let body = {
    let v = input.db_cluster_snapshot_identifier
    string.concat([
      body,
      string.concat([
        "&",
        "DBClusterSnapshotIdentifier",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_delete_db_cluster_snapshot_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DeleteDBClusterSnapshotOutput, String) {
  Ok(DeleteDBClusterSnapshotOutput)
}

pub type DeleteDBInstanceInput {
  DeleteDBInstanceInput(
    db_instance_identifier: String,
    skip_final_snapshot: option.Option(Bool),
    final_db_snapshot_identifier: option.Option(String),
    delete_automated_backups: option.Option(Bool),
  )
}

pub fn delete_db_instance_input_default(
  db_instance_identifier db_instance_identifier: String,
) -> DeleteDBInstanceInput {
  DeleteDBInstanceInput(
    db_instance_identifier: db_instance_identifier,
    skip_final_snapshot: option.None,
    final_db_snapshot_identifier: option.None,
    delete_automated_backups: option.None,
  )
}

pub type DeleteDBInstanceOutput {
  DeleteDBInstanceOutput
}

pub fn decode_delete_db_instance_input_struct() -> decode.Decoder(
  DeleteDBInstanceInput,
) {
  use <- decode.recursive
  use db_instance_identifier <- decode.field(
    "DBInstanceIdentifier",
    decode.string,
  )
  use skip_final_snapshot <- decode.optional_field(
    "SkipFinalSnapshot",
    option.None,
    decode.optional(decode.bool),
  )
  use final_db_snapshot_identifier <- decode.optional_field(
    "FinalDBSnapshotIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use delete_automated_backups <- decode.optional_field(
    "DeleteAutomatedBackups",
    option.None,
    decode.optional(decode.bool),
  )
  decode.success(DeleteDBInstanceInput(
    db_instance_identifier: db_instance_identifier,
    skip_final_snapshot: skip_final_snapshot,
    final_db_snapshot_identifier: final_db_snapshot_identifier,
    delete_automated_backups: delete_automated_backups,
  ))
}

pub fn decode_delete_db_instance_input(
  json_string: String,
) -> Result(DeleteDBInstanceInput, String) {
  result.map_error(
    json.parse(json_string, decode_delete_db_instance_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_delete_db_instance_request(
  input: DeleteDBInstanceInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DeleteDBInstance&Version=2014-10-31"
  let body = {
    let v = input.db_instance_identifier
    string.concat([
      body,
      string.concat(["&", "DBInstanceIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.skip_final_snapshot {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "SkipFinalSnapshot",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.final_db_snapshot_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "FinalDBSnapshotIdentifier",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.delete_automated_backups {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DeleteAutomatedBackups",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_delete_db_instance_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DeleteDBInstanceOutput, String) {
  Ok(DeleteDBInstanceOutput)
}

pub type DeleteDBInstanceAutomatedBackupInput {
  DeleteDBInstanceAutomatedBackupInput(
    dbi_resource_id: option.Option(String),
    db_instance_automated_backups_arn: option.Option(String),
  )
}

pub fn delete_db_instance_automated_backup_input_default() -> DeleteDBInstanceAutomatedBackupInput {
  DeleteDBInstanceAutomatedBackupInput(
    dbi_resource_id: option.None,
    db_instance_automated_backups_arn: option.None,
  )
}

pub type DeleteDBInstanceAutomatedBackupOutput {
  DeleteDBInstanceAutomatedBackupOutput
}

pub fn decode_delete_db_instance_automated_backup_input_struct() -> decode.Decoder(
  DeleteDBInstanceAutomatedBackupInput,
) {
  use <- decode.recursive
  use dbi_resource_id <- decode.optional_field(
    "DbiResourceId",
    option.None,
    decode.optional(decode.string),
  )
  use db_instance_automated_backups_arn <- decode.optional_field(
    "DBInstanceAutomatedBackupsArn",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(DeleteDBInstanceAutomatedBackupInput(
    dbi_resource_id: dbi_resource_id,
    db_instance_automated_backups_arn: db_instance_automated_backups_arn,
  ))
}

pub fn decode_delete_db_instance_automated_backup_input(
  json_string: String,
) -> Result(DeleteDBInstanceAutomatedBackupInput, String) {
  result.map_error(
    json.parse(
      json_string,
      decode_delete_db_instance_automated_backup_input_struct(),
    ),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_delete_db_instance_automated_backup_request(
  input: DeleteDBInstanceAutomatedBackupInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DeleteDBInstanceAutomatedBackup&Version=2014-10-31"
  let body = case input.dbi_resource_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DbiResourceId", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.db_instance_automated_backups_arn {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DBInstanceAutomatedBackupsArn",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_delete_db_instance_automated_backup_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DeleteDBInstanceAutomatedBackupOutput, String) {
  Ok(DeleteDBInstanceAutomatedBackupOutput)
}

pub type DeleteDBParameterGroupInput {
  DeleteDBParameterGroupInput(db_parameter_group_name: String)
}

pub fn delete_db_parameter_group_input_default(
  db_parameter_group_name db_parameter_group_name: String,
) -> DeleteDBParameterGroupInput {
  DeleteDBParameterGroupInput(db_parameter_group_name: db_parameter_group_name)
}

pub type DeleteDBParameterGroupOutput {
  DeleteDBParameterGroupOutput
}

pub fn decode_delete_db_parameter_group_input_struct() -> decode.Decoder(
  DeleteDBParameterGroupInput,
) {
  use <- decode.recursive
  use db_parameter_group_name <- decode.field(
    "DBParameterGroupName",
    decode.string,
  )
  decode.success(DeleteDBParameterGroupInput(
    db_parameter_group_name: db_parameter_group_name,
  ))
}

pub fn decode_delete_db_parameter_group_input(
  json_string: String,
) -> Result(DeleteDBParameterGroupInput, String) {
  result.map_error(
    json.parse(json_string, decode_delete_db_parameter_group_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_delete_db_parameter_group_request(
  input: DeleteDBParameterGroupInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DeleteDBParameterGroup&Version=2014-10-31"
  let body = {
    let v = input.db_parameter_group_name
    string.concat([
      body,
      string.concat(["&", "DBParameterGroupName", "=", uri.encode_component(v)]),
    ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_delete_db_parameter_group_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DeleteDBParameterGroupOutput, String) {
  Ok(DeleteDBParameterGroupOutput)
}

pub type DeleteDBProxyInput {
  DeleteDBProxyInput(db_proxy_name: String)
}

pub fn delete_db_proxy_input_default(
  db_proxy_name db_proxy_name: String,
) -> DeleteDBProxyInput {
  DeleteDBProxyInput(db_proxy_name: db_proxy_name)
}

pub type DeleteDBProxyOutput {
  DeleteDBProxyOutput
}

pub fn decode_delete_db_proxy_input_struct() -> decode.Decoder(
  DeleteDBProxyInput,
) {
  use <- decode.recursive
  use db_proxy_name <- decode.field("DBProxyName", decode.string)
  decode.success(DeleteDBProxyInput(db_proxy_name: db_proxy_name))
}

pub fn decode_delete_db_proxy_input(
  json_string: String,
) -> Result(DeleteDBProxyInput, String) {
  result.map_error(
    json.parse(json_string, decode_delete_db_proxy_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_delete_db_proxy_request(
  input: DeleteDBProxyInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DeleteDBProxy&Version=2014-10-31"
  let body = {
    let v = input.db_proxy_name
    string.concat([
      body,
      string.concat(["&", "DBProxyName", "=", uri.encode_component(v)]),
    ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_delete_db_proxy_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DeleteDBProxyOutput, String) {
  Ok(DeleteDBProxyOutput)
}

pub type DeleteDBProxyEndpointInput {
  DeleteDBProxyEndpointInput(db_proxy_endpoint_name: String)
}

pub fn delete_db_proxy_endpoint_input_default(
  db_proxy_endpoint_name db_proxy_endpoint_name: String,
) -> DeleteDBProxyEndpointInput {
  DeleteDBProxyEndpointInput(db_proxy_endpoint_name: db_proxy_endpoint_name)
}

pub type DeleteDBProxyEndpointOutput {
  DeleteDBProxyEndpointOutput
}

pub fn decode_delete_db_proxy_endpoint_input_struct() -> decode.Decoder(
  DeleteDBProxyEndpointInput,
) {
  use <- decode.recursive
  use db_proxy_endpoint_name <- decode.field(
    "DBProxyEndpointName",
    decode.string,
  )
  decode.success(DeleteDBProxyEndpointInput(
    db_proxy_endpoint_name: db_proxy_endpoint_name,
  ))
}

pub fn decode_delete_db_proxy_endpoint_input(
  json_string: String,
) -> Result(DeleteDBProxyEndpointInput, String) {
  result.map_error(
    json.parse(json_string, decode_delete_db_proxy_endpoint_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_delete_db_proxy_endpoint_request(
  input: DeleteDBProxyEndpointInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DeleteDBProxyEndpoint&Version=2014-10-31"
  let body = {
    let v = input.db_proxy_endpoint_name
    string.concat([
      body,
      string.concat(["&", "DBProxyEndpointName", "=", uri.encode_component(v)]),
    ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_delete_db_proxy_endpoint_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DeleteDBProxyEndpointOutput, String) {
  Ok(DeleteDBProxyEndpointOutput)
}

pub type DeleteDBSecurityGroupInput {
  DeleteDBSecurityGroupInput(db_security_group_name: String)
}

pub fn delete_db_security_group_input_default(
  db_security_group_name db_security_group_name: String,
) -> DeleteDBSecurityGroupInput {
  DeleteDBSecurityGroupInput(db_security_group_name: db_security_group_name)
}

pub type DeleteDBSecurityGroupOutput {
  DeleteDBSecurityGroupOutput
}

pub fn decode_delete_db_security_group_input_struct() -> decode.Decoder(
  DeleteDBSecurityGroupInput,
) {
  use <- decode.recursive
  use db_security_group_name <- decode.field(
    "DBSecurityGroupName",
    decode.string,
  )
  decode.success(DeleteDBSecurityGroupInput(
    db_security_group_name: db_security_group_name,
  ))
}

pub fn decode_delete_db_security_group_input(
  json_string: String,
) -> Result(DeleteDBSecurityGroupInput, String) {
  result.map_error(
    json.parse(json_string, decode_delete_db_security_group_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_delete_db_security_group_request(
  input: DeleteDBSecurityGroupInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DeleteDBSecurityGroup&Version=2014-10-31"
  let body = {
    let v = input.db_security_group_name
    string.concat([
      body,
      string.concat(["&", "DBSecurityGroupName", "=", uri.encode_component(v)]),
    ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_delete_db_security_group_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DeleteDBSecurityGroupOutput, String) {
  Ok(DeleteDBSecurityGroupOutput)
}

pub type DeleteDBShardGroupInput {
  DeleteDBShardGroupInput(db_shard_group_identifier: String)
}

pub fn delete_db_shard_group_input_default(
  db_shard_group_identifier db_shard_group_identifier: String,
) -> DeleteDBShardGroupInput {
  DeleteDBShardGroupInput(db_shard_group_identifier: db_shard_group_identifier)
}

pub type DeleteDBShardGroupOutput {
  DeleteDBShardGroupOutput
}

pub fn decode_delete_db_shard_group_input_struct() -> decode.Decoder(
  DeleteDBShardGroupInput,
) {
  use <- decode.recursive
  use db_shard_group_identifier <- decode.field(
    "DBShardGroupIdentifier",
    decode.string,
  )
  decode.success(DeleteDBShardGroupInput(
    db_shard_group_identifier: db_shard_group_identifier,
  ))
}

pub fn decode_delete_db_shard_group_input(
  json_string: String,
) -> Result(DeleteDBShardGroupInput, String) {
  result.map_error(
    json.parse(json_string, decode_delete_db_shard_group_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_delete_db_shard_group_request(
  input: DeleteDBShardGroupInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DeleteDBShardGroup&Version=2014-10-31"
  let body = {
    let v = input.db_shard_group_identifier
    string.concat([
      body,
      string.concat([
        "&",
        "DBShardGroupIdentifier",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_delete_db_shard_group_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DeleteDBShardGroupOutput, String) {
  Ok(DeleteDBShardGroupOutput)
}

pub type DeleteDBSnapshotInput {
  DeleteDBSnapshotInput(db_snapshot_identifier: String)
}

pub fn delete_db_snapshot_input_default(
  db_snapshot_identifier db_snapshot_identifier: String,
) -> DeleteDBSnapshotInput {
  DeleteDBSnapshotInput(db_snapshot_identifier: db_snapshot_identifier)
}

pub type DeleteDBSnapshotOutput {
  DeleteDBSnapshotOutput
}

pub fn decode_delete_db_snapshot_input_struct() -> decode.Decoder(
  DeleteDBSnapshotInput,
) {
  use <- decode.recursive
  use db_snapshot_identifier <- decode.field(
    "DBSnapshotIdentifier",
    decode.string,
  )
  decode.success(DeleteDBSnapshotInput(
    db_snapshot_identifier: db_snapshot_identifier,
  ))
}

pub fn decode_delete_db_snapshot_input(
  json_string: String,
) -> Result(DeleteDBSnapshotInput, String) {
  result.map_error(
    json.parse(json_string, decode_delete_db_snapshot_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_delete_db_snapshot_request(
  input: DeleteDBSnapshotInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DeleteDBSnapshot&Version=2014-10-31"
  let body = {
    let v = input.db_snapshot_identifier
    string.concat([
      body,
      string.concat(["&", "DBSnapshotIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_delete_db_snapshot_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DeleteDBSnapshotOutput, String) {
  Ok(DeleteDBSnapshotOutput)
}

pub type DeleteDBSubnetGroupInput {
  DeleteDBSubnetGroupInput(db_subnet_group_name: String)
}

pub fn delete_db_subnet_group_input_default(
  db_subnet_group_name db_subnet_group_name: String,
) -> DeleteDBSubnetGroupInput {
  DeleteDBSubnetGroupInput(db_subnet_group_name: db_subnet_group_name)
}

pub type DeleteDBSubnetGroupOutput {
  DeleteDBSubnetGroupOutput
}

pub fn decode_delete_db_subnet_group_input_struct() -> decode.Decoder(
  DeleteDBSubnetGroupInput,
) {
  use <- decode.recursive
  use db_subnet_group_name <- decode.field("DBSubnetGroupName", decode.string)
  decode.success(DeleteDBSubnetGroupInput(
    db_subnet_group_name: db_subnet_group_name,
  ))
}

pub fn decode_delete_db_subnet_group_input(
  json_string: String,
) -> Result(DeleteDBSubnetGroupInput, String) {
  result.map_error(
    json.parse(json_string, decode_delete_db_subnet_group_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_delete_db_subnet_group_request(
  input: DeleteDBSubnetGroupInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DeleteDBSubnetGroup&Version=2014-10-31"
  let body = {
    let v = input.db_subnet_group_name
    string.concat([
      body,
      string.concat(["&", "DBSubnetGroupName", "=", uri.encode_component(v)]),
    ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_delete_db_subnet_group_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DeleteDBSubnetGroupOutput, String) {
  Ok(DeleteDBSubnetGroupOutput)
}

pub type DeleteEventSubscriptionInput {
  DeleteEventSubscriptionInput(subscription_name: String)
}

pub fn delete_event_subscription_input_default(
  subscription_name subscription_name: String,
) -> DeleteEventSubscriptionInput {
  DeleteEventSubscriptionInput(subscription_name: subscription_name)
}

pub type DeleteEventSubscriptionOutput {
  DeleteEventSubscriptionOutput
}

pub fn decode_delete_event_subscription_input_struct() -> decode.Decoder(
  DeleteEventSubscriptionInput,
) {
  use <- decode.recursive
  use subscription_name <- decode.field("SubscriptionName", decode.string)
  decode.success(DeleteEventSubscriptionInput(
    subscription_name: subscription_name,
  ))
}

pub fn decode_delete_event_subscription_input(
  json_string: String,
) -> Result(DeleteEventSubscriptionInput, String) {
  result.map_error(
    json.parse(json_string, decode_delete_event_subscription_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_delete_event_subscription_request(
  input: DeleteEventSubscriptionInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DeleteEventSubscription&Version=2014-10-31"
  let body = {
    let v = input.subscription_name
    string.concat([
      body,
      string.concat(["&", "SubscriptionName", "=", uri.encode_component(v)]),
    ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_delete_event_subscription_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DeleteEventSubscriptionOutput, String) {
  Ok(DeleteEventSubscriptionOutput)
}

pub type DeleteGlobalClusterInput {
  DeleteGlobalClusterInput(global_cluster_identifier: String)
}

pub fn delete_global_cluster_input_default(
  global_cluster_identifier global_cluster_identifier: String,
) -> DeleteGlobalClusterInput {
  DeleteGlobalClusterInput(global_cluster_identifier: global_cluster_identifier)
}

pub type DeleteGlobalClusterOutput {
  DeleteGlobalClusterOutput
}

pub fn decode_delete_global_cluster_input_struct() -> decode.Decoder(
  DeleteGlobalClusterInput,
) {
  use <- decode.recursive
  use global_cluster_identifier <- decode.field(
    "GlobalClusterIdentifier",
    decode.string,
  )
  decode.success(DeleteGlobalClusterInput(
    global_cluster_identifier: global_cluster_identifier,
  ))
}

pub fn decode_delete_global_cluster_input(
  json_string: String,
) -> Result(DeleteGlobalClusterInput, String) {
  result.map_error(
    json.parse(json_string, decode_delete_global_cluster_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_delete_global_cluster_request(
  input: DeleteGlobalClusterInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DeleteGlobalCluster&Version=2014-10-31"
  let body = {
    let v = input.global_cluster_identifier
    string.concat([
      body,
      string.concat([
        "&",
        "GlobalClusterIdentifier",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_delete_global_cluster_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DeleteGlobalClusterOutput, String) {
  Ok(DeleteGlobalClusterOutput)
}

pub type DeleteIntegrationInput {
  DeleteIntegrationInput(integration_identifier: String)
}

pub fn delete_integration_input_default(
  integration_identifier integration_identifier: String,
) -> DeleteIntegrationInput {
  DeleteIntegrationInput(integration_identifier: integration_identifier)
}

pub type DeleteIntegrationOutput {
  DeleteIntegrationOutput
}

pub fn decode_delete_integration_input_struct() -> decode.Decoder(
  DeleteIntegrationInput,
) {
  use <- decode.recursive
  use integration_identifier <- decode.field(
    "IntegrationIdentifier",
    decode.string,
  )
  decode.success(DeleteIntegrationInput(
    integration_identifier: integration_identifier,
  ))
}

pub fn decode_delete_integration_input(
  json_string: String,
) -> Result(DeleteIntegrationInput, String) {
  result.map_error(
    json.parse(json_string, decode_delete_integration_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_delete_integration_request(
  input: DeleteIntegrationInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DeleteIntegration&Version=2014-10-31"
  let body = {
    let v = input.integration_identifier
    string.concat([
      body,
      string.concat(["&", "IntegrationIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_delete_integration_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DeleteIntegrationOutput, String) {
  Ok(DeleteIntegrationOutput)
}

pub type DeleteOptionGroupInput {
  DeleteOptionGroupInput(option_group_name: String)
}

pub fn delete_option_group_input_default(
  option_group_name option_group_name: String,
) -> DeleteOptionGroupInput {
  DeleteOptionGroupInput(option_group_name: option_group_name)
}

pub type DeleteOptionGroupOutput {
  DeleteOptionGroupOutput
}

pub fn decode_delete_option_group_input_struct() -> decode.Decoder(
  DeleteOptionGroupInput,
) {
  use <- decode.recursive
  use option_group_name <- decode.field("OptionGroupName", decode.string)
  decode.success(DeleteOptionGroupInput(option_group_name: option_group_name))
}

pub fn decode_delete_option_group_input(
  json_string: String,
) -> Result(DeleteOptionGroupInput, String) {
  result.map_error(
    json.parse(json_string, decode_delete_option_group_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_delete_option_group_request(
  input: DeleteOptionGroupInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DeleteOptionGroup&Version=2014-10-31"
  let body = {
    let v = input.option_group_name
    string.concat([
      body,
      string.concat(["&", "OptionGroupName", "=", uri.encode_component(v)]),
    ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_delete_option_group_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DeleteOptionGroupOutput, String) {
  Ok(DeleteOptionGroupOutput)
}

pub type DeleteTenantDatabaseInput {
  DeleteTenantDatabaseInput(
    db_instance_identifier: String,
    tenant_db_name: String,
    skip_final_snapshot: option.Option(Bool),
    final_db_snapshot_identifier: option.Option(String),
  )
}

pub fn delete_tenant_database_input_default(
  db_instance_identifier db_instance_identifier: String,
  tenant_db_name tenant_db_name: String,
) -> DeleteTenantDatabaseInput {
  DeleteTenantDatabaseInput(
    db_instance_identifier: db_instance_identifier,
    tenant_db_name: tenant_db_name,
    skip_final_snapshot: option.None,
    final_db_snapshot_identifier: option.None,
  )
}

pub type DeleteTenantDatabaseOutput {
  DeleteTenantDatabaseOutput
}

pub fn decode_delete_tenant_database_input_struct() -> decode.Decoder(
  DeleteTenantDatabaseInput,
) {
  use <- decode.recursive
  use db_instance_identifier <- decode.field(
    "DBInstanceIdentifier",
    decode.string,
  )
  use tenant_db_name <- decode.field("TenantDBName", decode.string)
  use skip_final_snapshot <- decode.optional_field(
    "SkipFinalSnapshot",
    option.None,
    decode.optional(decode.bool),
  )
  use final_db_snapshot_identifier <- decode.optional_field(
    "FinalDBSnapshotIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(DeleteTenantDatabaseInput(
    db_instance_identifier: db_instance_identifier,
    tenant_db_name: tenant_db_name,
    skip_final_snapshot: skip_final_snapshot,
    final_db_snapshot_identifier: final_db_snapshot_identifier,
  ))
}

pub fn decode_delete_tenant_database_input(
  json_string: String,
) -> Result(DeleteTenantDatabaseInput, String) {
  result.map_error(
    json.parse(json_string, decode_delete_tenant_database_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_delete_tenant_database_request(
  input: DeleteTenantDatabaseInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DeleteTenantDatabase&Version=2014-10-31"
  let body = {
    let v = input.db_instance_identifier
    string.concat([
      body,
      string.concat(["&", "DBInstanceIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.tenant_db_name
    string.concat([
      body,
      string.concat(["&", "TenantDBName", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.skip_final_snapshot {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "SkipFinalSnapshot",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.final_db_snapshot_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "FinalDBSnapshotIdentifier",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_delete_tenant_database_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DeleteTenantDatabaseOutput, String) {
  Ok(DeleteTenantDatabaseOutput)
}

pub type DeregisterDBProxyTargetsInput {
  DeregisterDBProxyTargetsInput(
    db_proxy_name: String,
    target_group_name: option.Option(String),
    db_instance_identifiers: option.Option(List(String)),
    db_cluster_identifiers: option.Option(List(String)),
  )
}

pub fn deregister_db_proxy_targets_input_default(
  db_proxy_name db_proxy_name: String,
) -> DeregisterDBProxyTargetsInput {
  DeregisterDBProxyTargetsInput(
    db_proxy_name: db_proxy_name,
    target_group_name: option.None,
    db_instance_identifiers: option.None,
    db_cluster_identifiers: option.None,
  )
}

pub type DeregisterDBProxyTargetsOutput {
  DeregisterDBProxyTargetsOutput
}

pub fn decode_deregister_db_proxy_targets_input_struct() -> decode.Decoder(
  DeregisterDBProxyTargetsInput,
) {
  use <- decode.recursive
  use db_proxy_name <- decode.field("DBProxyName", decode.string)
  use target_group_name <- decode.optional_field(
    "TargetGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use db_instance_identifiers <- decode.optional_field(
    "DBInstanceIdentifiers",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use db_cluster_identifiers <- decode.optional_field(
    "DBClusterIdentifiers",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  decode.success(DeregisterDBProxyTargetsInput(
    db_proxy_name: db_proxy_name,
    target_group_name: target_group_name,
    db_instance_identifiers: db_instance_identifiers,
    db_cluster_identifiers: db_cluster_identifiers,
  ))
}

pub fn decode_deregister_db_proxy_targets_input(
  json_string: String,
) -> Result(DeregisterDBProxyTargetsInput, String) {
  result.map_error(
    json.parse(json_string, decode_deregister_db_proxy_targets_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_deregister_db_proxy_targets_request(
  input: DeregisterDBProxyTargetsInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DeregisterDBProxyTargets&Version=2014-10-31"
  let body = {
    let v = input.db_proxy_name
    string.concat([
      body,
      string.concat(["&", "DBProxyName", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.target_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "TargetGroupName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.db_instance_identifiers {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "DBInstanceIdentifiers", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "DBInstanceIdentifiers",
                    ".member.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body = case input.db_cluster_identifiers {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "DBClusterIdentifiers", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "DBClusterIdentifiers",
                    ".member.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_deregister_db_proxy_targets_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DeregisterDBProxyTargetsOutput, String) {
  Ok(DeregisterDBProxyTargetsOutput)
}

pub type DescribeAccountAttributesInput {
  DescribeAccountAttributesInput
}

pub type DescribeAccountAttributesOutput {
  DescribeAccountAttributesOutput
}

pub fn build_describe_account_attributes_request(
  _input: DescribeAccountAttributesInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let headers =
    dict.from_list([#("Content-Type", "application/x-www-form-urlencoded")])
  #(
    "POST",
    "/",
    headers,
    bit_array.from_string("Action=DescribeAccountAttributes&Version=2014-10-31"),
  )
}

pub fn parse_describe_account_attributes_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribeAccountAttributesOutput, String) {
  Ok(DescribeAccountAttributesOutput)
}

pub type DescribeBlueGreenDeploymentsInput {
  DescribeBlueGreenDeploymentsInput(
    blue_green_deployment_identifier: option.Option(String),
    filters: option.Option(List(Filter)),
    marker: option.Option(String),
    max_records: option.Option(Int),
  )
}

pub fn describe_blue_green_deployments_input_default() -> DescribeBlueGreenDeploymentsInput {
  DescribeBlueGreenDeploymentsInput(
    blue_green_deployment_identifier: option.None,
    filters: option.None,
    marker: option.None,
    max_records: option.None,
  )
}

pub type DescribeBlueGreenDeploymentsOutput {
  DescribeBlueGreenDeploymentsOutput
}

pub fn decode_describe_blue_green_deployments_input_struct() -> decode.Decoder(
  DescribeBlueGreenDeploymentsInput,
) {
  use <- decode.recursive
  use blue_green_deployment_identifier <- decode.optional_field(
    "BlueGreenDeploymentIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use filters <- decode.optional_field(
    "Filters",
    option.None,
    decode.optional(decode.list(decode_filter_struct_params())),
  )
  use marker <- decode.optional_field(
    "Marker",
    option.None,
    decode.optional(decode.string),
  )
  use max_records <- decode.optional_field(
    "MaxRecords",
    option.None,
    decode.optional(decode.int),
  )
  decode.success(DescribeBlueGreenDeploymentsInput(
    blue_green_deployment_identifier: blue_green_deployment_identifier,
    filters: filters,
    marker: marker,
    max_records: max_records,
  ))
}

pub fn decode_describe_blue_green_deployments_input(
  json_string: String,
) -> Result(DescribeBlueGreenDeploymentsInput, String) {
  result.map_error(
    json.parse(
      json_string,
      decode_describe_blue_green_deployments_input_struct(),
    ),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_describe_blue_green_deployments_request(
  input: DescribeBlueGreenDeploymentsInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DescribeBlueGreenDeployments&Version=2014-10-31"
  let body = case input.blue_green_deployment_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "BlueGreenDeploymentIdentifier",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.filters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Filters", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_filter_at(
                  string.concat(["Filters", ".Filter.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.marker {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Marker", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.max_records {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxRecords", "=", int.to_string(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_describe_blue_green_deployments_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribeBlueGreenDeploymentsOutput, String) {
  Ok(DescribeBlueGreenDeploymentsOutput)
}

pub type DescribeCertificatesInput {
  DescribeCertificatesInput(
    certificate_identifier: option.Option(String),
    filters: option.Option(List(Filter)),
    max_records: option.Option(Int),
    marker: option.Option(String),
  )
}

pub fn describe_certificates_input_default() -> DescribeCertificatesInput {
  DescribeCertificatesInput(
    certificate_identifier: option.None,
    filters: option.None,
    max_records: option.None,
    marker: option.None,
  )
}

pub type DescribeCertificatesOutput {
  DescribeCertificatesOutput
}

pub fn decode_describe_certificates_input_struct() -> decode.Decoder(
  DescribeCertificatesInput,
) {
  use <- decode.recursive
  use certificate_identifier <- decode.optional_field(
    "CertificateIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use filters <- decode.optional_field(
    "Filters",
    option.None,
    decode.optional(decode.list(decode_filter_struct_params())),
  )
  use max_records <- decode.optional_field(
    "MaxRecords",
    option.None,
    decode.optional(decode.int),
  )
  use marker <- decode.optional_field(
    "Marker",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(DescribeCertificatesInput(
    certificate_identifier: certificate_identifier,
    filters: filters,
    max_records: max_records,
    marker: marker,
  ))
}

pub fn decode_describe_certificates_input(
  json_string: String,
) -> Result(DescribeCertificatesInput, String) {
  result.map_error(
    json.parse(json_string, decode_describe_certificates_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_describe_certificates_request(
  input: DescribeCertificatesInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DescribeCertificates&Version=2014-10-31"
  let body = case input.certificate_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "CertificateIdentifier",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.filters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Filters", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_filter_at(
                  string.concat(["Filters", ".Filter.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.max_records {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxRecords", "=", int.to_string(v)]),
      ])
  }
  let body = case input.marker {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Marker", "=", uri.encode_component(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_describe_certificates_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribeCertificatesOutput, String) {
  Ok(DescribeCertificatesOutput)
}

pub type DescribeDBClusterAutomatedBackupsInput {
  DescribeDBClusterAutomatedBackupsInput(
    db_cluster_resource_id: option.Option(String),
    db_cluster_identifier: option.Option(String),
    filters: option.Option(List(Filter)),
    max_records: option.Option(Int),
    marker: option.Option(String),
  )
}

pub fn describe_db_cluster_automated_backups_input_default() -> DescribeDBClusterAutomatedBackupsInput {
  DescribeDBClusterAutomatedBackupsInput(
    db_cluster_resource_id: option.None,
    db_cluster_identifier: option.None,
    filters: option.None,
    max_records: option.None,
    marker: option.None,
  )
}

pub type DescribeDBClusterAutomatedBackupsOutput {
  DescribeDBClusterAutomatedBackupsOutput
}

pub fn decode_describe_db_cluster_automated_backups_input_struct() -> decode.Decoder(
  DescribeDBClusterAutomatedBackupsInput,
) {
  use <- decode.recursive
  use db_cluster_resource_id <- decode.optional_field(
    "DbClusterResourceId",
    option.None,
    decode.optional(decode.string),
  )
  use db_cluster_identifier <- decode.optional_field(
    "DBClusterIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use filters <- decode.optional_field(
    "Filters",
    option.None,
    decode.optional(decode.list(decode_filter_struct_params())),
  )
  use max_records <- decode.optional_field(
    "MaxRecords",
    option.None,
    decode.optional(decode.int),
  )
  use marker <- decode.optional_field(
    "Marker",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(DescribeDBClusterAutomatedBackupsInput(
    db_cluster_resource_id: db_cluster_resource_id,
    db_cluster_identifier: db_cluster_identifier,
    filters: filters,
    max_records: max_records,
    marker: marker,
  ))
}

pub fn decode_describe_db_cluster_automated_backups_input(
  json_string: String,
) -> Result(DescribeDBClusterAutomatedBackupsInput, String) {
  result.map_error(
    json.parse(
      json_string,
      decode_describe_db_cluster_automated_backups_input_struct(),
    ),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_describe_db_cluster_automated_backups_request(
  input: DescribeDBClusterAutomatedBackupsInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DescribeDBClusterAutomatedBackups&Version=2014-10-31"
  let body = case input.db_cluster_resource_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DbClusterResourceId", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.db_cluster_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DBClusterIdentifier", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.filters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Filters", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_filter_at(
                  string.concat(["Filters", ".Filter.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.max_records {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxRecords", "=", int.to_string(v)]),
      ])
  }
  let body = case input.marker {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Marker", "=", uri.encode_component(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_describe_db_cluster_automated_backups_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribeDBClusterAutomatedBackupsOutput, String) {
  Ok(DescribeDBClusterAutomatedBackupsOutput)
}

pub type DescribeDBClusterBacktracksInput {
  DescribeDBClusterBacktracksInput(
    db_cluster_identifier: String,
    backtrack_identifier: option.Option(String),
    filters: option.Option(List(Filter)),
    max_records: option.Option(Int),
    marker: option.Option(String),
  )
}

pub fn describe_db_cluster_backtracks_input_default(
  db_cluster_identifier db_cluster_identifier: String,
) -> DescribeDBClusterBacktracksInput {
  DescribeDBClusterBacktracksInput(
    db_cluster_identifier: db_cluster_identifier,
    backtrack_identifier: option.None,
    filters: option.None,
    max_records: option.None,
    marker: option.None,
  )
}

pub type DescribeDBClusterBacktracksOutput {
  DescribeDBClusterBacktracksOutput
}

pub fn decode_describe_db_cluster_backtracks_input_struct() -> decode.Decoder(
  DescribeDBClusterBacktracksInput,
) {
  use <- decode.recursive
  use db_cluster_identifier <- decode.field(
    "DBClusterIdentifier",
    decode.string,
  )
  use backtrack_identifier <- decode.optional_field(
    "BacktrackIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use filters <- decode.optional_field(
    "Filters",
    option.None,
    decode.optional(decode.list(decode_filter_struct_params())),
  )
  use max_records <- decode.optional_field(
    "MaxRecords",
    option.None,
    decode.optional(decode.int),
  )
  use marker <- decode.optional_field(
    "Marker",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(DescribeDBClusterBacktracksInput(
    db_cluster_identifier: db_cluster_identifier,
    backtrack_identifier: backtrack_identifier,
    filters: filters,
    max_records: max_records,
    marker: marker,
  ))
}

pub fn decode_describe_db_cluster_backtracks_input(
  json_string: String,
) -> Result(DescribeDBClusterBacktracksInput, String) {
  result.map_error(
    json.parse(
      json_string,
      decode_describe_db_cluster_backtracks_input_struct(),
    ),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_describe_db_cluster_backtracks_request(
  input: DescribeDBClusterBacktracksInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DescribeDBClusterBacktracks&Version=2014-10-31"
  let body = {
    let v = input.db_cluster_identifier
    string.concat([
      body,
      string.concat(["&", "DBClusterIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.backtrack_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "BacktrackIdentifier", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.filters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Filters", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_filter_at(
                  string.concat(["Filters", ".Filter.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.max_records {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxRecords", "=", int.to_string(v)]),
      ])
  }
  let body = case input.marker {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Marker", "=", uri.encode_component(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_describe_db_cluster_backtracks_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribeDBClusterBacktracksOutput, String) {
  Ok(DescribeDBClusterBacktracksOutput)
}

pub type DescribeDBClusterEndpointsInput {
  DescribeDBClusterEndpointsInput(
    db_cluster_identifier: option.Option(String),
    db_cluster_endpoint_identifier: option.Option(String),
    filters: option.Option(List(Filter)),
    max_records: option.Option(Int),
    marker: option.Option(String),
  )
}

pub fn describe_db_cluster_endpoints_input_default() -> DescribeDBClusterEndpointsInput {
  DescribeDBClusterEndpointsInput(
    db_cluster_identifier: option.None,
    db_cluster_endpoint_identifier: option.None,
    filters: option.None,
    max_records: option.None,
    marker: option.None,
  )
}

pub type DescribeDBClusterEndpointsOutput {
  DescribeDBClusterEndpointsOutput
}

pub fn decode_describe_db_cluster_endpoints_input_struct() -> decode.Decoder(
  DescribeDBClusterEndpointsInput,
) {
  use <- decode.recursive
  use db_cluster_identifier <- decode.optional_field(
    "DBClusterIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use db_cluster_endpoint_identifier <- decode.optional_field(
    "DBClusterEndpointIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use filters <- decode.optional_field(
    "Filters",
    option.None,
    decode.optional(decode.list(decode_filter_struct_params())),
  )
  use max_records <- decode.optional_field(
    "MaxRecords",
    option.None,
    decode.optional(decode.int),
  )
  use marker <- decode.optional_field(
    "Marker",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(DescribeDBClusterEndpointsInput(
    db_cluster_identifier: db_cluster_identifier,
    db_cluster_endpoint_identifier: db_cluster_endpoint_identifier,
    filters: filters,
    max_records: max_records,
    marker: marker,
  ))
}

pub fn decode_describe_db_cluster_endpoints_input(
  json_string: String,
) -> Result(DescribeDBClusterEndpointsInput, String) {
  result.map_error(
    json.parse(json_string, decode_describe_db_cluster_endpoints_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_describe_db_cluster_endpoints_request(
  input: DescribeDBClusterEndpointsInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DescribeDBClusterEndpoints&Version=2014-10-31"
  let body = case input.db_cluster_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DBClusterIdentifier", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.db_cluster_endpoint_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DBClusterEndpointIdentifier",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.filters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Filters", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_filter_at(
                  string.concat(["Filters", ".Filter.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.max_records {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxRecords", "=", int.to_string(v)]),
      ])
  }
  let body = case input.marker {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Marker", "=", uri.encode_component(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_describe_db_cluster_endpoints_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribeDBClusterEndpointsOutput, String) {
  Ok(DescribeDBClusterEndpointsOutput)
}

pub type DescribeDBClusterParameterGroupsInput {
  DescribeDBClusterParameterGroupsInput(
    db_cluster_parameter_group_name: option.Option(String),
    filters: option.Option(List(Filter)),
    max_records: option.Option(Int),
    marker: option.Option(String),
  )
}

pub fn describe_db_cluster_parameter_groups_input_default() -> DescribeDBClusterParameterGroupsInput {
  DescribeDBClusterParameterGroupsInput(
    db_cluster_parameter_group_name: option.None,
    filters: option.None,
    max_records: option.None,
    marker: option.None,
  )
}

pub type DescribeDBClusterParameterGroupsOutput {
  DescribeDBClusterParameterGroupsOutput
}

pub fn decode_describe_db_cluster_parameter_groups_input_struct() -> decode.Decoder(
  DescribeDBClusterParameterGroupsInput,
) {
  use <- decode.recursive
  use db_cluster_parameter_group_name <- decode.optional_field(
    "DBClusterParameterGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use filters <- decode.optional_field(
    "Filters",
    option.None,
    decode.optional(decode.list(decode_filter_struct_params())),
  )
  use max_records <- decode.optional_field(
    "MaxRecords",
    option.None,
    decode.optional(decode.int),
  )
  use marker <- decode.optional_field(
    "Marker",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(DescribeDBClusterParameterGroupsInput(
    db_cluster_parameter_group_name: db_cluster_parameter_group_name,
    filters: filters,
    max_records: max_records,
    marker: marker,
  ))
}

pub fn decode_describe_db_cluster_parameter_groups_input(
  json_string: String,
) -> Result(DescribeDBClusterParameterGroupsInput, String) {
  result.map_error(
    json.parse(
      json_string,
      decode_describe_db_cluster_parameter_groups_input_struct(),
    ),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_describe_db_cluster_parameter_groups_request(
  input: DescribeDBClusterParameterGroupsInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DescribeDBClusterParameterGroups&Version=2014-10-31"
  let body = case input.db_cluster_parameter_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DBClusterParameterGroupName",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.filters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Filters", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_filter_at(
                  string.concat(["Filters", ".Filter.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.max_records {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxRecords", "=", int.to_string(v)]),
      ])
  }
  let body = case input.marker {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Marker", "=", uri.encode_component(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_describe_db_cluster_parameter_groups_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribeDBClusterParameterGroupsOutput, String) {
  Ok(DescribeDBClusterParameterGroupsOutput)
}

pub type DescribeDBClusterParametersInput {
  DescribeDBClusterParametersInput(
    db_cluster_parameter_group_name: String,
    source: option.Option(String),
    filters: option.Option(List(Filter)),
    max_records: option.Option(Int),
    marker: option.Option(String),
  )
}

pub fn describe_db_cluster_parameters_input_default(
  db_cluster_parameter_group_name db_cluster_parameter_group_name: String,
) -> DescribeDBClusterParametersInput {
  DescribeDBClusterParametersInput(
    db_cluster_parameter_group_name: db_cluster_parameter_group_name,
    source: option.None,
    filters: option.None,
    max_records: option.None,
    marker: option.None,
  )
}

pub type DescribeDBClusterParametersOutput {
  DescribeDBClusterParametersOutput
}

pub fn decode_describe_db_cluster_parameters_input_struct() -> decode.Decoder(
  DescribeDBClusterParametersInput,
) {
  use <- decode.recursive
  use db_cluster_parameter_group_name <- decode.field(
    "DBClusterParameterGroupName",
    decode.string,
  )
  use source <- decode.optional_field(
    "Source",
    option.None,
    decode.optional(decode.string),
  )
  use filters <- decode.optional_field(
    "Filters",
    option.None,
    decode.optional(decode.list(decode_filter_struct_params())),
  )
  use max_records <- decode.optional_field(
    "MaxRecords",
    option.None,
    decode.optional(decode.int),
  )
  use marker <- decode.optional_field(
    "Marker",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(DescribeDBClusterParametersInput(
    db_cluster_parameter_group_name: db_cluster_parameter_group_name,
    source: source,
    filters: filters,
    max_records: max_records,
    marker: marker,
  ))
}

pub fn decode_describe_db_cluster_parameters_input(
  json_string: String,
) -> Result(DescribeDBClusterParametersInput, String) {
  result.map_error(
    json.parse(
      json_string,
      decode_describe_db_cluster_parameters_input_struct(),
    ),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_describe_db_cluster_parameters_request(
  input: DescribeDBClusterParametersInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DescribeDBClusterParameters&Version=2014-10-31"
  let body = {
    let v = input.db_cluster_parameter_group_name
    string.concat([
      body,
      string.concat([
        "&",
        "DBClusterParameterGroupName",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body = case input.source {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Source", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.filters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Filters", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_filter_at(
                  string.concat(["Filters", ".Filter.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.max_records {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxRecords", "=", int.to_string(v)]),
      ])
  }
  let body = case input.marker {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Marker", "=", uri.encode_component(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_describe_db_cluster_parameters_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribeDBClusterParametersOutput, String) {
  Ok(DescribeDBClusterParametersOutput)
}

pub type DescribeDBClustersInput {
  DescribeDBClustersInput(
    db_cluster_identifier: option.Option(String),
    filters: option.Option(List(Filter)),
    max_records: option.Option(Int),
    marker: option.Option(String),
    include_shared: option.Option(Bool),
  )
}

pub fn describe_db_clusters_input_default() -> DescribeDBClustersInput {
  DescribeDBClustersInput(
    db_cluster_identifier: option.None,
    filters: option.None,
    max_records: option.None,
    marker: option.None,
    include_shared: option.None,
  )
}

pub type DescribeDBClustersOutput {
  DescribeDBClustersOutput
}

pub fn decode_describe_db_clusters_input_struct() -> decode.Decoder(
  DescribeDBClustersInput,
) {
  use <- decode.recursive
  use db_cluster_identifier <- decode.optional_field(
    "DBClusterIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use filters <- decode.optional_field(
    "Filters",
    option.None,
    decode.optional(decode.list(decode_filter_struct_params())),
  )
  use max_records <- decode.optional_field(
    "MaxRecords",
    option.None,
    decode.optional(decode.int),
  )
  use marker <- decode.optional_field(
    "Marker",
    option.None,
    decode.optional(decode.string),
  )
  use include_shared <- decode.optional_field(
    "IncludeShared",
    option.None,
    decode.optional(decode.bool),
  )
  decode.success(DescribeDBClustersInput(
    db_cluster_identifier: db_cluster_identifier,
    filters: filters,
    max_records: max_records,
    marker: marker,
    include_shared: include_shared,
  ))
}

pub fn decode_describe_db_clusters_input(
  json_string: String,
) -> Result(DescribeDBClustersInput, String) {
  result.map_error(
    json.parse(json_string, decode_describe_db_clusters_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_describe_db_clusters_request(
  input: DescribeDBClustersInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DescribeDBClusters&Version=2014-10-31"
  let body = case input.db_cluster_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DBClusterIdentifier", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.filters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Filters", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_filter_at(
                  string.concat(["Filters", ".Filter.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.max_records {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxRecords", "=", int.to_string(v)]),
      ])
  }
  let body = case input.marker {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Marker", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.include_shared {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "IncludeShared",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_describe_db_clusters_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribeDBClustersOutput, String) {
  Ok(DescribeDBClustersOutput)
}

pub type DescribeDBClusterSnapshotAttributesInput {
  DescribeDBClusterSnapshotAttributesInput(
    db_cluster_snapshot_identifier: String,
  )
}

pub fn describe_db_cluster_snapshot_attributes_input_default(
  db_cluster_snapshot_identifier db_cluster_snapshot_identifier: String,
) -> DescribeDBClusterSnapshotAttributesInput {
  DescribeDBClusterSnapshotAttributesInput(
    db_cluster_snapshot_identifier: db_cluster_snapshot_identifier,
  )
}

pub type DescribeDBClusterSnapshotAttributesOutput {
  DescribeDBClusterSnapshotAttributesOutput
}

pub fn decode_describe_db_cluster_snapshot_attributes_input_struct() -> decode.Decoder(
  DescribeDBClusterSnapshotAttributesInput,
) {
  use <- decode.recursive
  use db_cluster_snapshot_identifier <- decode.field(
    "DBClusterSnapshotIdentifier",
    decode.string,
  )
  decode.success(DescribeDBClusterSnapshotAttributesInput(
    db_cluster_snapshot_identifier: db_cluster_snapshot_identifier,
  ))
}

pub fn decode_describe_db_cluster_snapshot_attributes_input(
  json_string: String,
) -> Result(DescribeDBClusterSnapshotAttributesInput, String) {
  result.map_error(
    json.parse(
      json_string,
      decode_describe_db_cluster_snapshot_attributes_input_struct(),
    ),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_describe_db_cluster_snapshot_attributes_request(
  input: DescribeDBClusterSnapshotAttributesInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DescribeDBClusterSnapshotAttributes&Version=2014-10-31"
  let body = {
    let v = input.db_cluster_snapshot_identifier
    string.concat([
      body,
      string.concat([
        "&",
        "DBClusterSnapshotIdentifier",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_describe_db_cluster_snapshot_attributes_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribeDBClusterSnapshotAttributesOutput, String) {
  Ok(DescribeDBClusterSnapshotAttributesOutput)
}

pub type DescribeDBClusterSnapshotsInput {
  DescribeDBClusterSnapshotsInput(
    db_cluster_identifier: option.Option(String),
    db_cluster_snapshot_identifier: option.Option(String),
    snapshot_type: option.Option(String),
    filters: option.Option(List(Filter)),
    max_records: option.Option(Int),
    marker: option.Option(String),
    include_shared: option.Option(Bool),
    include_public: option.Option(Bool),
    db_cluster_resource_id: option.Option(String),
  )
}

pub fn describe_db_cluster_snapshots_input_default() -> DescribeDBClusterSnapshotsInput {
  DescribeDBClusterSnapshotsInput(
    db_cluster_identifier: option.None,
    db_cluster_snapshot_identifier: option.None,
    snapshot_type: option.None,
    filters: option.None,
    max_records: option.None,
    marker: option.None,
    include_shared: option.None,
    include_public: option.None,
    db_cluster_resource_id: option.None,
  )
}

pub type DescribeDBClusterSnapshotsOutput {
  DescribeDBClusterSnapshotsOutput
}

pub fn decode_describe_db_cluster_snapshots_input_struct() -> decode.Decoder(
  DescribeDBClusterSnapshotsInput,
) {
  use <- decode.recursive
  use db_cluster_identifier <- decode.optional_field(
    "DBClusterIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use db_cluster_snapshot_identifier <- decode.optional_field(
    "DBClusterSnapshotIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use snapshot_type <- decode.optional_field(
    "SnapshotType",
    option.None,
    decode.optional(decode.string),
  )
  use filters <- decode.optional_field(
    "Filters",
    option.None,
    decode.optional(decode.list(decode_filter_struct_params())),
  )
  use max_records <- decode.optional_field(
    "MaxRecords",
    option.None,
    decode.optional(decode.int),
  )
  use marker <- decode.optional_field(
    "Marker",
    option.None,
    decode.optional(decode.string),
  )
  use include_shared <- decode.optional_field(
    "IncludeShared",
    option.None,
    decode.optional(decode.bool),
  )
  use include_public <- decode.optional_field(
    "IncludePublic",
    option.None,
    decode.optional(decode.bool),
  )
  use db_cluster_resource_id <- decode.optional_field(
    "DbClusterResourceId",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(DescribeDBClusterSnapshotsInput(
    db_cluster_identifier: db_cluster_identifier,
    db_cluster_snapshot_identifier: db_cluster_snapshot_identifier,
    snapshot_type: snapshot_type,
    filters: filters,
    max_records: max_records,
    marker: marker,
    include_shared: include_shared,
    include_public: include_public,
    db_cluster_resource_id: db_cluster_resource_id,
  ))
}

pub fn decode_describe_db_cluster_snapshots_input(
  json_string: String,
) -> Result(DescribeDBClusterSnapshotsInput, String) {
  result.map_error(
    json.parse(json_string, decode_describe_db_cluster_snapshots_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_describe_db_cluster_snapshots_request(
  input: DescribeDBClusterSnapshotsInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DescribeDBClusterSnapshots&Version=2014-10-31"
  let body = case input.db_cluster_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DBClusterIdentifier", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.db_cluster_snapshot_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DBClusterSnapshotIdentifier",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.snapshot_type {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "SnapshotType", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.filters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Filters", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_filter_at(
                  string.concat(["Filters", ".Filter.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.max_records {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxRecords", "=", int.to_string(v)]),
      ])
  }
  let body = case input.marker {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Marker", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.include_shared {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "IncludeShared",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.include_public {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "IncludePublic",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.db_cluster_resource_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DbClusterResourceId", "=", uri.encode_component(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_describe_db_cluster_snapshots_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribeDBClusterSnapshotsOutput, String) {
  Ok(DescribeDBClusterSnapshotsOutput)
}

pub type DescribeDBEngineVersionsInput {
  DescribeDBEngineVersionsInput(
    engine: option.Option(String),
    engine_version: option.Option(String),
    db_parameter_group_family: option.Option(String),
    filters: option.Option(List(Filter)),
    max_records: option.Option(Int),
    marker: option.Option(String),
    default_only: option.Option(Bool),
    list_supported_character_sets: option.Option(Bool),
    list_supported_timezones: option.Option(Bool),
    include_all: option.Option(Bool),
  )
}

pub fn describe_db_engine_versions_input_default() -> DescribeDBEngineVersionsInput {
  DescribeDBEngineVersionsInput(
    engine: option.None,
    engine_version: option.None,
    db_parameter_group_family: option.None,
    filters: option.None,
    max_records: option.None,
    marker: option.None,
    default_only: option.None,
    list_supported_character_sets: option.None,
    list_supported_timezones: option.None,
    include_all: option.None,
  )
}

pub type DescribeDBEngineVersionsOutput {
  DescribeDBEngineVersionsOutput
}

pub fn decode_describe_db_engine_versions_input_struct() -> decode.Decoder(
  DescribeDBEngineVersionsInput,
) {
  use <- decode.recursive
  use engine <- decode.optional_field(
    "Engine",
    option.None,
    decode.optional(decode.string),
  )
  use engine_version <- decode.optional_field(
    "EngineVersion",
    option.None,
    decode.optional(decode.string),
  )
  use db_parameter_group_family <- decode.optional_field(
    "DBParameterGroupFamily",
    option.None,
    decode.optional(decode.string),
  )
  use filters <- decode.optional_field(
    "Filters",
    option.None,
    decode.optional(decode.list(decode_filter_struct_params())),
  )
  use max_records <- decode.optional_field(
    "MaxRecords",
    option.None,
    decode.optional(decode.int),
  )
  use marker <- decode.optional_field(
    "Marker",
    option.None,
    decode.optional(decode.string),
  )
  use default_only <- decode.optional_field(
    "DefaultOnly",
    option.None,
    decode.optional(decode.bool),
  )
  use list_supported_character_sets <- decode.optional_field(
    "ListSupportedCharacterSets",
    option.None,
    decode.optional(decode.bool),
  )
  use list_supported_timezones <- decode.optional_field(
    "ListSupportedTimezones",
    option.None,
    decode.optional(decode.bool),
  )
  use include_all <- decode.optional_field(
    "IncludeAll",
    option.None,
    decode.optional(decode.bool),
  )
  decode.success(DescribeDBEngineVersionsInput(
    engine: engine,
    engine_version: engine_version,
    db_parameter_group_family: db_parameter_group_family,
    filters: filters,
    max_records: max_records,
    marker: marker,
    default_only: default_only,
    list_supported_character_sets: list_supported_character_sets,
    list_supported_timezones: list_supported_timezones,
    include_all: include_all,
  ))
}

pub fn decode_describe_db_engine_versions_input(
  json_string: String,
) -> Result(DescribeDBEngineVersionsInput, String) {
  result.map_error(
    json.parse(json_string, decode_describe_db_engine_versions_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_describe_db_engine_versions_request(
  input: DescribeDBEngineVersionsInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DescribeDBEngineVersions&Version=2014-10-31"
  let body = case input.engine {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Engine", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.engine_version {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "EngineVersion", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.db_parameter_group_family {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DBParameterGroupFamily",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.filters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Filters", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_filter_at(
                  string.concat(["Filters", ".Filter.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.max_records {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxRecords", "=", int.to_string(v)]),
      ])
  }
  let body = case input.marker {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Marker", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.default_only {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DefaultOnly",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.list_supported_character_sets {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "ListSupportedCharacterSets",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.list_supported_timezones {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "ListSupportedTimezones",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.include_all {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "IncludeAll",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_describe_db_engine_versions_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribeDBEngineVersionsOutput, String) {
  Ok(DescribeDBEngineVersionsOutput)
}

pub type DescribeDBInstanceAutomatedBackupsInput {
  DescribeDBInstanceAutomatedBackupsInput(
    dbi_resource_id: option.Option(String),
    db_instance_identifier: option.Option(String),
    filters: option.Option(List(Filter)),
    max_records: option.Option(Int),
    marker: option.Option(String),
    db_instance_automated_backups_arn: option.Option(String),
  )
}

pub fn describe_db_instance_automated_backups_input_default() -> DescribeDBInstanceAutomatedBackupsInput {
  DescribeDBInstanceAutomatedBackupsInput(
    dbi_resource_id: option.None,
    db_instance_identifier: option.None,
    filters: option.None,
    max_records: option.None,
    marker: option.None,
    db_instance_automated_backups_arn: option.None,
  )
}

pub type DescribeDBInstanceAutomatedBackupsOutput {
  DescribeDBInstanceAutomatedBackupsOutput
}

pub fn decode_describe_db_instance_automated_backups_input_struct() -> decode.Decoder(
  DescribeDBInstanceAutomatedBackupsInput,
) {
  use <- decode.recursive
  use dbi_resource_id <- decode.optional_field(
    "DbiResourceId",
    option.None,
    decode.optional(decode.string),
  )
  use db_instance_identifier <- decode.optional_field(
    "DBInstanceIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use filters <- decode.optional_field(
    "Filters",
    option.None,
    decode.optional(decode.list(decode_filter_struct_params())),
  )
  use max_records <- decode.optional_field(
    "MaxRecords",
    option.None,
    decode.optional(decode.int),
  )
  use marker <- decode.optional_field(
    "Marker",
    option.None,
    decode.optional(decode.string),
  )
  use db_instance_automated_backups_arn <- decode.optional_field(
    "DBInstanceAutomatedBackupsArn",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(DescribeDBInstanceAutomatedBackupsInput(
    dbi_resource_id: dbi_resource_id,
    db_instance_identifier: db_instance_identifier,
    filters: filters,
    max_records: max_records,
    marker: marker,
    db_instance_automated_backups_arn: db_instance_automated_backups_arn,
  ))
}

pub fn decode_describe_db_instance_automated_backups_input(
  json_string: String,
) -> Result(DescribeDBInstanceAutomatedBackupsInput, String) {
  result.map_error(
    json.parse(
      json_string,
      decode_describe_db_instance_automated_backups_input_struct(),
    ),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_describe_db_instance_automated_backups_request(
  input: DescribeDBInstanceAutomatedBackupsInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DescribeDBInstanceAutomatedBackups&Version=2014-10-31"
  let body = case input.dbi_resource_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DbiResourceId", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.db_instance_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DBInstanceIdentifier",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.filters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Filters", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_filter_at(
                  string.concat(["Filters", ".Filter.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.max_records {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxRecords", "=", int.to_string(v)]),
      ])
  }
  let body = case input.marker {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Marker", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.db_instance_automated_backups_arn {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DBInstanceAutomatedBackupsArn",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_describe_db_instance_automated_backups_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribeDBInstanceAutomatedBackupsOutput, String) {
  Ok(DescribeDBInstanceAutomatedBackupsOutput)
}

pub type DescribeDBInstancesInput {
  DescribeDBInstancesInput(
    db_instance_identifier: option.Option(String),
    filters: option.Option(List(Filter)),
    max_records: option.Option(Int),
    marker: option.Option(String),
  )
}

pub fn describe_db_instances_input_default() -> DescribeDBInstancesInput {
  DescribeDBInstancesInput(
    db_instance_identifier: option.None,
    filters: option.None,
    max_records: option.None,
    marker: option.None,
  )
}

pub type DescribeDBInstancesOutput {
  DescribeDBInstancesOutput
}

pub fn decode_describe_db_instances_input_struct() -> decode.Decoder(
  DescribeDBInstancesInput,
) {
  use <- decode.recursive
  use db_instance_identifier <- decode.optional_field(
    "DBInstanceIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use filters <- decode.optional_field(
    "Filters",
    option.None,
    decode.optional(decode.list(decode_filter_struct_params())),
  )
  use max_records <- decode.optional_field(
    "MaxRecords",
    option.None,
    decode.optional(decode.int),
  )
  use marker <- decode.optional_field(
    "Marker",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(DescribeDBInstancesInput(
    db_instance_identifier: db_instance_identifier,
    filters: filters,
    max_records: max_records,
    marker: marker,
  ))
}

pub fn decode_describe_db_instances_input(
  json_string: String,
) -> Result(DescribeDBInstancesInput, String) {
  result.map_error(
    json.parse(json_string, decode_describe_db_instances_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_describe_db_instances_request(
  input: DescribeDBInstancesInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DescribeDBInstances&Version=2014-10-31"
  let body = case input.db_instance_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DBInstanceIdentifier",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.filters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Filters", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_filter_at(
                  string.concat(["Filters", ".Filter.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.max_records {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxRecords", "=", int.to_string(v)]),
      ])
  }
  let body = case input.marker {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Marker", "=", uri.encode_component(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_describe_db_instances_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribeDBInstancesOutput, String) {
  Ok(DescribeDBInstancesOutput)
}

pub type DescribeDBLogFilesInput {
  DescribeDBLogFilesInput(
    db_instance_identifier: String,
    filename_contains: option.Option(String),
    file_last_written: option.Option(Int),
    file_size: option.Option(Int),
    filters: option.Option(List(Filter)),
    max_records: option.Option(Int),
    marker: option.Option(String),
  )
}

pub fn describe_db_log_files_input_default(
  db_instance_identifier db_instance_identifier: String,
) -> DescribeDBLogFilesInput {
  DescribeDBLogFilesInput(
    db_instance_identifier: db_instance_identifier,
    filename_contains: option.None,
    file_last_written: option.None,
    file_size: option.None,
    filters: option.None,
    max_records: option.None,
    marker: option.None,
  )
}

pub type DescribeDBLogFilesOutput {
  DescribeDBLogFilesOutput
}

pub fn decode_describe_db_log_files_input_struct() -> decode.Decoder(
  DescribeDBLogFilesInput,
) {
  use <- decode.recursive
  use db_instance_identifier <- decode.field(
    "DBInstanceIdentifier",
    decode.string,
  )
  use filename_contains <- decode.optional_field(
    "FilenameContains",
    option.None,
    decode.optional(decode.string),
  )
  use file_last_written <- decode.optional_field(
    "FileLastWritten",
    option.None,
    decode.optional(decode.int),
  )
  use file_size <- decode.optional_field(
    "FileSize",
    option.None,
    decode.optional(decode.int),
  )
  use filters <- decode.optional_field(
    "Filters",
    option.None,
    decode.optional(decode.list(decode_filter_struct_params())),
  )
  use max_records <- decode.optional_field(
    "MaxRecords",
    option.None,
    decode.optional(decode.int),
  )
  use marker <- decode.optional_field(
    "Marker",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(DescribeDBLogFilesInput(
    db_instance_identifier: db_instance_identifier,
    filename_contains: filename_contains,
    file_last_written: file_last_written,
    file_size: file_size,
    filters: filters,
    max_records: max_records,
    marker: marker,
  ))
}

pub fn decode_describe_db_log_files_input(
  json_string: String,
) -> Result(DescribeDBLogFilesInput, String) {
  result.map_error(
    json.parse(json_string, decode_describe_db_log_files_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_describe_db_log_files_request(
  input: DescribeDBLogFilesInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DescribeDBLogFiles&Version=2014-10-31"
  let body = {
    let v = input.db_instance_identifier
    string.concat([
      body,
      string.concat(["&", "DBInstanceIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.filename_contains {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "FilenameContains", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.file_last_written {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "FileLastWritten", "=", int.to_string(v)]),
      ])
  }
  let body = case input.file_size {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "FileSize", "=", int.to_string(v)]),
      ])
  }
  let body = case input.filters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Filters", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_filter_at(
                  string.concat(["Filters", ".Filter.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.max_records {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxRecords", "=", int.to_string(v)]),
      ])
  }
  let body = case input.marker {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Marker", "=", uri.encode_component(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_describe_db_log_files_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribeDBLogFilesOutput, String) {
  Ok(DescribeDBLogFilesOutput)
}

pub type DescribeDBMajorEngineVersionsInput {
  DescribeDBMajorEngineVersionsInput(
    engine: option.Option(String),
    major_engine_version: option.Option(String),
    marker: option.Option(String),
    max_records: option.Option(Int),
  )
}

pub fn describe_db_major_engine_versions_input_default() -> DescribeDBMajorEngineVersionsInput {
  DescribeDBMajorEngineVersionsInput(
    engine: option.None,
    major_engine_version: option.None,
    marker: option.None,
    max_records: option.None,
  )
}

pub type DescribeDBMajorEngineVersionsOutput {
  DescribeDBMajorEngineVersionsOutput
}

pub fn decode_describe_db_major_engine_versions_input_struct() -> decode.Decoder(
  DescribeDBMajorEngineVersionsInput,
) {
  use <- decode.recursive
  use engine <- decode.optional_field(
    "Engine",
    option.None,
    decode.optional(decode.string),
  )
  use major_engine_version <- decode.optional_field(
    "MajorEngineVersion",
    option.None,
    decode.optional(decode.string),
  )
  use marker <- decode.optional_field(
    "Marker",
    option.None,
    decode.optional(decode.string),
  )
  use max_records <- decode.optional_field(
    "MaxRecords",
    option.None,
    decode.optional(decode.int),
  )
  decode.success(DescribeDBMajorEngineVersionsInput(
    engine: engine,
    major_engine_version: major_engine_version,
    marker: marker,
    max_records: max_records,
  ))
}

pub fn decode_describe_db_major_engine_versions_input(
  json_string: String,
) -> Result(DescribeDBMajorEngineVersionsInput, String) {
  result.map_error(
    json.parse(
      json_string,
      decode_describe_db_major_engine_versions_input_struct(),
    ),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_describe_db_major_engine_versions_request(
  input: DescribeDBMajorEngineVersionsInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DescribeDBMajorEngineVersions&Version=2014-10-31"
  let body = case input.engine {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Engine", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.major_engine_version {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MajorEngineVersion", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.marker {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Marker", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.max_records {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxRecords", "=", int.to_string(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_describe_db_major_engine_versions_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribeDBMajorEngineVersionsOutput, String) {
  Ok(DescribeDBMajorEngineVersionsOutput)
}

pub type DescribeDBParameterGroupsInput {
  DescribeDBParameterGroupsInput(
    db_parameter_group_name: option.Option(String),
    filters: option.Option(List(Filter)),
    max_records: option.Option(Int),
    marker: option.Option(String),
  )
}

pub fn describe_db_parameter_groups_input_default() -> DescribeDBParameterGroupsInput {
  DescribeDBParameterGroupsInput(
    db_parameter_group_name: option.None,
    filters: option.None,
    max_records: option.None,
    marker: option.None,
  )
}

pub type DescribeDBParameterGroupsOutput {
  DescribeDBParameterGroupsOutput
}

pub fn decode_describe_db_parameter_groups_input_struct() -> decode.Decoder(
  DescribeDBParameterGroupsInput,
) {
  use <- decode.recursive
  use db_parameter_group_name <- decode.optional_field(
    "DBParameterGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use filters <- decode.optional_field(
    "Filters",
    option.None,
    decode.optional(decode.list(decode_filter_struct_params())),
  )
  use max_records <- decode.optional_field(
    "MaxRecords",
    option.None,
    decode.optional(decode.int),
  )
  use marker <- decode.optional_field(
    "Marker",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(DescribeDBParameterGroupsInput(
    db_parameter_group_name: db_parameter_group_name,
    filters: filters,
    max_records: max_records,
    marker: marker,
  ))
}

pub fn decode_describe_db_parameter_groups_input(
  json_string: String,
) -> Result(DescribeDBParameterGroupsInput, String) {
  result.map_error(
    json.parse(json_string, decode_describe_db_parameter_groups_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_describe_db_parameter_groups_request(
  input: DescribeDBParameterGroupsInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DescribeDBParameterGroups&Version=2014-10-31"
  let body = case input.db_parameter_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DBParameterGroupName",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.filters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Filters", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_filter_at(
                  string.concat(["Filters", ".Filter.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.max_records {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxRecords", "=", int.to_string(v)]),
      ])
  }
  let body = case input.marker {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Marker", "=", uri.encode_component(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_describe_db_parameter_groups_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribeDBParameterGroupsOutput, String) {
  Ok(DescribeDBParameterGroupsOutput)
}

pub type DescribeDBParametersInput {
  DescribeDBParametersInput(
    db_parameter_group_name: String,
    source: option.Option(String),
    filters: option.Option(List(Filter)),
    max_records: option.Option(Int),
    marker: option.Option(String),
  )
}

pub fn describe_db_parameters_input_default(
  db_parameter_group_name db_parameter_group_name: String,
) -> DescribeDBParametersInput {
  DescribeDBParametersInput(
    db_parameter_group_name: db_parameter_group_name,
    source: option.None,
    filters: option.None,
    max_records: option.None,
    marker: option.None,
  )
}

pub type DescribeDBParametersOutput {
  DescribeDBParametersOutput
}

pub fn decode_describe_db_parameters_input_struct() -> decode.Decoder(
  DescribeDBParametersInput,
) {
  use <- decode.recursive
  use db_parameter_group_name <- decode.field(
    "DBParameterGroupName",
    decode.string,
  )
  use source <- decode.optional_field(
    "Source",
    option.None,
    decode.optional(decode.string),
  )
  use filters <- decode.optional_field(
    "Filters",
    option.None,
    decode.optional(decode.list(decode_filter_struct_params())),
  )
  use max_records <- decode.optional_field(
    "MaxRecords",
    option.None,
    decode.optional(decode.int),
  )
  use marker <- decode.optional_field(
    "Marker",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(DescribeDBParametersInput(
    db_parameter_group_name: db_parameter_group_name,
    source: source,
    filters: filters,
    max_records: max_records,
    marker: marker,
  ))
}

pub fn decode_describe_db_parameters_input(
  json_string: String,
) -> Result(DescribeDBParametersInput, String) {
  result.map_error(
    json.parse(json_string, decode_describe_db_parameters_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_describe_db_parameters_request(
  input: DescribeDBParametersInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DescribeDBParameters&Version=2014-10-31"
  let body = {
    let v = input.db_parameter_group_name
    string.concat([
      body,
      string.concat(["&", "DBParameterGroupName", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.source {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Source", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.filters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Filters", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_filter_at(
                  string.concat(["Filters", ".Filter.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.max_records {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxRecords", "=", int.to_string(v)]),
      ])
  }
  let body = case input.marker {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Marker", "=", uri.encode_component(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_describe_db_parameters_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribeDBParametersOutput, String) {
  Ok(DescribeDBParametersOutput)
}

pub type DescribeDBProxiesInput {
  DescribeDBProxiesInput(
    db_proxy_name: option.Option(String),
    filters: option.Option(List(Filter)),
    marker: option.Option(String),
    max_records: option.Option(Int),
  )
}

pub fn describe_db_proxies_input_default() -> DescribeDBProxiesInput {
  DescribeDBProxiesInput(
    db_proxy_name: option.None,
    filters: option.None,
    marker: option.None,
    max_records: option.None,
  )
}

pub type DescribeDBProxiesOutput {
  DescribeDBProxiesOutput
}

pub fn decode_describe_db_proxies_input_struct() -> decode.Decoder(
  DescribeDBProxiesInput,
) {
  use <- decode.recursive
  use db_proxy_name <- decode.optional_field(
    "DBProxyName",
    option.None,
    decode.optional(decode.string),
  )
  use filters <- decode.optional_field(
    "Filters",
    option.None,
    decode.optional(decode.list(decode_filter_struct_params())),
  )
  use marker <- decode.optional_field(
    "Marker",
    option.None,
    decode.optional(decode.string),
  )
  use max_records <- decode.optional_field(
    "MaxRecords",
    option.None,
    decode.optional(decode.int),
  )
  decode.success(DescribeDBProxiesInput(
    db_proxy_name: db_proxy_name,
    filters: filters,
    marker: marker,
    max_records: max_records,
  ))
}

pub fn decode_describe_db_proxies_input(
  json_string: String,
) -> Result(DescribeDBProxiesInput, String) {
  result.map_error(
    json.parse(json_string, decode_describe_db_proxies_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_describe_db_proxies_request(
  input: DescribeDBProxiesInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DescribeDBProxies&Version=2014-10-31"
  let body = case input.db_proxy_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DBProxyName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.filters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Filters", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_filter_at(
                  string.concat(["Filters", ".Filter.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.marker {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Marker", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.max_records {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxRecords", "=", int.to_string(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_describe_db_proxies_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribeDBProxiesOutput, String) {
  Ok(DescribeDBProxiesOutput)
}

pub type DescribeDBProxyEndpointsInput {
  DescribeDBProxyEndpointsInput(
    db_proxy_name: option.Option(String),
    db_proxy_endpoint_name: option.Option(String),
    filters: option.Option(List(Filter)),
    marker: option.Option(String),
    max_records: option.Option(Int),
  )
}

pub fn describe_db_proxy_endpoints_input_default() -> DescribeDBProxyEndpointsInput {
  DescribeDBProxyEndpointsInput(
    db_proxy_name: option.None,
    db_proxy_endpoint_name: option.None,
    filters: option.None,
    marker: option.None,
    max_records: option.None,
  )
}

pub type DescribeDBProxyEndpointsOutput {
  DescribeDBProxyEndpointsOutput
}

pub fn decode_describe_db_proxy_endpoints_input_struct() -> decode.Decoder(
  DescribeDBProxyEndpointsInput,
) {
  use <- decode.recursive
  use db_proxy_name <- decode.optional_field(
    "DBProxyName",
    option.None,
    decode.optional(decode.string),
  )
  use db_proxy_endpoint_name <- decode.optional_field(
    "DBProxyEndpointName",
    option.None,
    decode.optional(decode.string),
  )
  use filters <- decode.optional_field(
    "Filters",
    option.None,
    decode.optional(decode.list(decode_filter_struct_params())),
  )
  use marker <- decode.optional_field(
    "Marker",
    option.None,
    decode.optional(decode.string),
  )
  use max_records <- decode.optional_field(
    "MaxRecords",
    option.None,
    decode.optional(decode.int),
  )
  decode.success(DescribeDBProxyEndpointsInput(
    db_proxy_name: db_proxy_name,
    db_proxy_endpoint_name: db_proxy_endpoint_name,
    filters: filters,
    marker: marker,
    max_records: max_records,
  ))
}

pub fn decode_describe_db_proxy_endpoints_input(
  json_string: String,
) -> Result(DescribeDBProxyEndpointsInput, String) {
  result.map_error(
    json.parse(json_string, decode_describe_db_proxy_endpoints_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_describe_db_proxy_endpoints_request(
  input: DescribeDBProxyEndpointsInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DescribeDBProxyEndpoints&Version=2014-10-31"
  let body = case input.db_proxy_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DBProxyName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.db_proxy_endpoint_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DBProxyEndpointName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.filters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Filters", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_filter_at(
                  string.concat(["Filters", ".Filter.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.marker {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Marker", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.max_records {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxRecords", "=", int.to_string(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_describe_db_proxy_endpoints_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribeDBProxyEndpointsOutput, String) {
  Ok(DescribeDBProxyEndpointsOutput)
}

pub type DescribeDBProxyTargetGroupsInput {
  DescribeDBProxyTargetGroupsInput(
    db_proxy_name: String,
    target_group_name: option.Option(String),
    filters: option.Option(List(Filter)),
    marker: option.Option(String),
    max_records: option.Option(Int),
  )
}

pub fn describe_db_proxy_target_groups_input_default(
  db_proxy_name db_proxy_name: String,
) -> DescribeDBProxyTargetGroupsInput {
  DescribeDBProxyTargetGroupsInput(
    db_proxy_name: db_proxy_name,
    target_group_name: option.None,
    filters: option.None,
    marker: option.None,
    max_records: option.None,
  )
}

pub type DescribeDBProxyTargetGroupsOutput {
  DescribeDBProxyTargetGroupsOutput
}

pub fn decode_describe_db_proxy_target_groups_input_struct() -> decode.Decoder(
  DescribeDBProxyTargetGroupsInput,
) {
  use <- decode.recursive
  use db_proxy_name <- decode.field("DBProxyName", decode.string)
  use target_group_name <- decode.optional_field(
    "TargetGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use filters <- decode.optional_field(
    "Filters",
    option.None,
    decode.optional(decode.list(decode_filter_struct_params())),
  )
  use marker <- decode.optional_field(
    "Marker",
    option.None,
    decode.optional(decode.string),
  )
  use max_records <- decode.optional_field(
    "MaxRecords",
    option.None,
    decode.optional(decode.int),
  )
  decode.success(DescribeDBProxyTargetGroupsInput(
    db_proxy_name: db_proxy_name,
    target_group_name: target_group_name,
    filters: filters,
    marker: marker,
    max_records: max_records,
  ))
}

pub fn decode_describe_db_proxy_target_groups_input(
  json_string: String,
) -> Result(DescribeDBProxyTargetGroupsInput, String) {
  result.map_error(
    json.parse(
      json_string,
      decode_describe_db_proxy_target_groups_input_struct(),
    ),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_describe_db_proxy_target_groups_request(
  input: DescribeDBProxyTargetGroupsInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DescribeDBProxyTargetGroups&Version=2014-10-31"
  let body = {
    let v = input.db_proxy_name
    string.concat([
      body,
      string.concat(["&", "DBProxyName", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.target_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "TargetGroupName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.filters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Filters", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_filter_at(
                  string.concat(["Filters", ".Filter.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.marker {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Marker", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.max_records {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxRecords", "=", int.to_string(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_describe_db_proxy_target_groups_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribeDBProxyTargetGroupsOutput, String) {
  Ok(DescribeDBProxyTargetGroupsOutput)
}

pub type DescribeDBProxyTargetsInput {
  DescribeDBProxyTargetsInput(
    db_proxy_name: String,
    target_group_name: option.Option(String),
    filters: option.Option(List(Filter)),
    marker: option.Option(String),
    max_records: option.Option(Int),
  )
}

pub fn describe_db_proxy_targets_input_default(
  db_proxy_name db_proxy_name: String,
) -> DescribeDBProxyTargetsInput {
  DescribeDBProxyTargetsInput(
    db_proxy_name: db_proxy_name,
    target_group_name: option.None,
    filters: option.None,
    marker: option.None,
    max_records: option.None,
  )
}

pub type DescribeDBProxyTargetsOutput {
  DescribeDBProxyTargetsOutput
}

pub fn decode_describe_db_proxy_targets_input_struct() -> decode.Decoder(
  DescribeDBProxyTargetsInput,
) {
  use <- decode.recursive
  use db_proxy_name <- decode.field("DBProxyName", decode.string)
  use target_group_name <- decode.optional_field(
    "TargetGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use filters <- decode.optional_field(
    "Filters",
    option.None,
    decode.optional(decode.list(decode_filter_struct_params())),
  )
  use marker <- decode.optional_field(
    "Marker",
    option.None,
    decode.optional(decode.string),
  )
  use max_records <- decode.optional_field(
    "MaxRecords",
    option.None,
    decode.optional(decode.int),
  )
  decode.success(DescribeDBProxyTargetsInput(
    db_proxy_name: db_proxy_name,
    target_group_name: target_group_name,
    filters: filters,
    marker: marker,
    max_records: max_records,
  ))
}

pub fn decode_describe_db_proxy_targets_input(
  json_string: String,
) -> Result(DescribeDBProxyTargetsInput, String) {
  result.map_error(
    json.parse(json_string, decode_describe_db_proxy_targets_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_describe_db_proxy_targets_request(
  input: DescribeDBProxyTargetsInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DescribeDBProxyTargets&Version=2014-10-31"
  let body = {
    let v = input.db_proxy_name
    string.concat([
      body,
      string.concat(["&", "DBProxyName", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.target_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "TargetGroupName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.filters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Filters", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_filter_at(
                  string.concat(["Filters", ".Filter.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.marker {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Marker", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.max_records {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxRecords", "=", int.to_string(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_describe_db_proxy_targets_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribeDBProxyTargetsOutput, String) {
  Ok(DescribeDBProxyTargetsOutput)
}

pub type DescribeDBRecommendationsInput {
  DescribeDBRecommendationsInput(
    last_updated_after: option.Option(json_timestamp.Timestamp),
    last_updated_before: option.Option(json_timestamp.Timestamp),
    locale: option.Option(String),
    filters: option.Option(List(Filter)),
    max_records: option.Option(Int),
    marker: option.Option(String),
  )
}

pub fn describe_db_recommendations_input_default() -> DescribeDBRecommendationsInput {
  DescribeDBRecommendationsInput(
    last_updated_after: option.None,
    last_updated_before: option.None,
    locale: option.None,
    filters: option.None,
    max_records: option.None,
    marker: option.None,
  )
}

pub type DescribeDBRecommendationsOutput {
  DescribeDBRecommendationsOutput
}

pub fn decode_describe_db_recommendations_input_struct() -> decode.Decoder(
  DescribeDBRecommendationsInput,
) {
  use <- decode.recursive
  use last_updated_after <- decode.optional_field(
    "LastUpdatedAfter",
    option.None,
    decode.optional(json_timestamp.decoder_precise()),
  )
  use last_updated_before <- decode.optional_field(
    "LastUpdatedBefore",
    option.None,
    decode.optional(json_timestamp.decoder_precise()),
  )
  use locale <- decode.optional_field(
    "Locale",
    option.None,
    decode.optional(decode.string),
  )
  use filters <- decode.optional_field(
    "Filters",
    option.None,
    decode.optional(decode.list(decode_filter_struct_params())),
  )
  use max_records <- decode.optional_field(
    "MaxRecords",
    option.None,
    decode.optional(decode.int),
  )
  use marker <- decode.optional_field(
    "Marker",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(DescribeDBRecommendationsInput(
    last_updated_after: last_updated_after,
    last_updated_before: last_updated_before,
    locale: locale,
    filters: filters,
    max_records: max_records,
    marker: marker,
  ))
}

pub fn decode_describe_db_recommendations_input(
  json_string: String,
) -> Result(DescribeDBRecommendationsInput, String) {
  result.map_error(
    json.parse(json_string, decode_describe_db_recommendations_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_describe_db_recommendations_request(
  input: DescribeDBRecommendationsInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DescribeDBRecommendations&Version=2014-10-31"
  let body = case input.last_updated_after {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "LastUpdatedAfter",
          "=",
          uri.encode_component(json_timestamp.format_iso8601_precise(v)),
        ]),
      ])
  }
  let body = case input.last_updated_before {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "LastUpdatedBefore",
          "=",
          uri.encode_component(json_timestamp.format_iso8601_precise(v)),
        ]),
      ])
  }
  let body = case input.locale {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Locale", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.filters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Filters", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_filter_at(
                  string.concat(["Filters", ".Filter.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.max_records {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxRecords", "=", int.to_string(v)]),
      ])
  }
  let body = case input.marker {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Marker", "=", uri.encode_component(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_describe_db_recommendations_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribeDBRecommendationsOutput, String) {
  Ok(DescribeDBRecommendationsOutput)
}

pub type DescribeDBSecurityGroupsInput {
  DescribeDBSecurityGroupsInput(
    db_security_group_name: option.Option(String),
    filters: option.Option(List(Filter)),
    max_records: option.Option(Int),
    marker: option.Option(String),
  )
}

pub fn describe_db_security_groups_input_default() -> DescribeDBSecurityGroupsInput {
  DescribeDBSecurityGroupsInput(
    db_security_group_name: option.None,
    filters: option.None,
    max_records: option.None,
    marker: option.None,
  )
}

pub type DescribeDBSecurityGroupsOutput {
  DescribeDBSecurityGroupsOutput
}

pub fn decode_describe_db_security_groups_input_struct() -> decode.Decoder(
  DescribeDBSecurityGroupsInput,
) {
  use <- decode.recursive
  use db_security_group_name <- decode.optional_field(
    "DBSecurityGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use filters <- decode.optional_field(
    "Filters",
    option.None,
    decode.optional(decode.list(decode_filter_struct_params())),
  )
  use max_records <- decode.optional_field(
    "MaxRecords",
    option.None,
    decode.optional(decode.int),
  )
  use marker <- decode.optional_field(
    "Marker",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(DescribeDBSecurityGroupsInput(
    db_security_group_name: db_security_group_name,
    filters: filters,
    max_records: max_records,
    marker: marker,
  ))
}

pub fn decode_describe_db_security_groups_input(
  json_string: String,
) -> Result(DescribeDBSecurityGroupsInput, String) {
  result.map_error(
    json.parse(json_string, decode_describe_db_security_groups_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_describe_db_security_groups_request(
  input: DescribeDBSecurityGroupsInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DescribeDBSecurityGroups&Version=2014-10-31"
  let body = case input.db_security_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DBSecurityGroupName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.filters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Filters", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_filter_at(
                  string.concat(["Filters", ".Filter.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.max_records {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxRecords", "=", int.to_string(v)]),
      ])
  }
  let body = case input.marker {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Marker", "=", uri.encode_component(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_describe_db_security_groups_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribeDBSecurityGroupsOutput, String) {
  Ok(DescribeDBSecurityGroupsOutput)
}

pub type DescribeDBShardGroupsInput {
  DescribeDBShardGroupsInput(
    db_shard_group_identifier: option.Option(String),
    filters: option.Option(List(Filter)),
    marker: option.Option(String),
    max_records: option.Option(Int),
  )
}

pub fn describe_db_shard_groups_input_default() -> DescribeDBShardGroupsInput {
  DescribeDBShardGroupsInput(
    db_shard_group_identifier: option.None,
    filters: option.None,
    marker: option.None,
    max_records: option.None,
  )
}

pub type DescribeDBShardGroupsOutput {
  DescribeDBShardGroupsOutput
}

pub fn decode_describe_db_shard_groups_input_struct() -> decode.Decoder(
  DescribeDBShardGroupsInput,
) {
  use <- decode.recursive
  use db_shard_group_identifier <- decode.optional_field(
    "DBShardGroupIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use filters <- decode.optional_field(
    "Filters",
    option.None,
    decode.optional(decode.list(decode_filter_struct_params())),
  )
  use marker <- decode.optional_field(
    "Marker",
    option.None,
    decode.optional(decode.string),
  )
  use max_records <- decode.optional_field(
    "MaxRecords",
    option.None,
    decode.optional(decode.int),
  )
  decode.success(DescribeDBShardGroupsInput(
    db_shard_group_identifier: db_shard_group_identifier,
    filters: filters,
    marker: marker,
    max_records: max_records,
  ))
}

pub fn decode_describe_db_shard_groups_input(
  json_string: String,
) -> Result(DescribeDBShardGroupsInput, String) {
  result.map_error(
    json.parse(json_string, decode_describe_db_shard_groups_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_describe_db_shard_groups_request(
  input: DescribeDBShardGroupsInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DescribeDBShardGroups&Version=2014-10-31"
  let body = case input.db_shard_group_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DBShardGroupIdentifier",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.filters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Filters", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_filter_at(
                  string.concat(["Filters", ".Filter.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.marker {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Marker", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.max_records {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxRecords", "=", int.to_string(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_describe_db_shard_groups_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribeDBShardGroupsOutput, String) {
  Ok(DescribeDBShardGroupsOutput)
}

pub type DescribeDBSnapshotAttributesInput {
  DescribeDBSnapshotAttributesInput(db_snapshot_identifier: String)
}

pub fn describe_db_snapshot_attributes_input_default(
  db_snapshot_identifier db_snapshot_identifier: String,
) -> DescribeDBSnapshotAttributesInput {
  DescribeDBSnapshotAttributesInput(
    db_snapshot_identifier: db_snapshot_identifier,
  )
}

pub type DescribeDBSnapshotAttributesOutput {
  DescribeDBSnapshotAttributesOutput
}

pub fn decode_describe_db_snapshot_attributes_input_struct() -> decode.Decoder(
  DescribeDBSnapshotAttributesInput,
) {
  use <- decode.recursive
  use db_snapshot_identifier <- decode.field(
    "DBSnapshotIdentifier",
    decode.string,
  )
  decode.success(DescribeDBSnapshotAttributesInput(
    db_snapshot_identifier: db_snapshot_identifier,
  ))
}

pub fn decode_describe_db_snapshot_attributes_input(
  json_string: String,
) -> Result(DescribeDBSnapshotAttributesInput, String) {
  result.map_error(
    json.parse(
      json_string,
      decode_describe_db_snapshot_attributes_input_struct(),
    ),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_describe_db_snapshot_attributes_request(
  input: DescribeDBSnapshotAttributesInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DescribeDBSnapshotAttributes&Version=2014-10-31"
  let body = {
    let v = input.db_snapshot_identifier
    string.concat([
      body,
      string.concat(["&", "DBSnapshotIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_describe_db_snapshot_attributes_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribeDBSnapshotAttributesOutput, String) {
  Ok(DescribeDBSnapshotAttributesOutput)
}

pub type DescribeDBSnapshotsInput {
  DescribeDBSnapshotsInput(
    db_instance_identifier: option.Option(String),
    db_snapshot_identifier: option.Option(String),
    snapshot_type: option.Option(String),
    filters: option.Option(List(Filter)),
    max_records: option.Option(Int),
    marker: option.Option(String),
    include_shared: option.Option(Bool),
    include_public: option.Option(Bool),
    dbi_resource_id: option.Option(String),
  )
}

pub fn describe_db_snapshots_input_default() -> DescribeDBSnapshotsInput {
  DescribeDBSnapshotsInput(
    db_instance_identifier: option.None,
    db_snapshot_identifier: option.None,
    snapshot_type: option.None,
    filters: option.None,
    max_records: option.None,
    marker: option.None,
    include_shared: option.None,
    include_public: option.None,
    dbi_resource_id: option.None,
  )
}

pub type DescribeDBSnapshotsOutput {
  DescribeDBSnapshotsOutput
}

pub fn decode_describe_db_snapshots_input_struct() -> decode.Decoder(
  DescribeDBSnapshotsInput,
) {
  use <- decode.recursive
  use db_instance_identifier <- decode.optional_field(
    "DBInstanceIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use db_snapshot_identifier <- decode.optional_field(
    "DBSnapshotIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use snapshot_type <- decode.optional_field(
    "SnapshotType",
    option.None,
    decode.optional(decode.string),
  )
  use filters <- decode.optional_field(
    "Filters",
    option.None,
    decode.optional(decode.list(decode_filter_struct_params())),
  )
  use max_records <- decode.optional_field(
    "MaxRecords",
    option.None,
    decode.optional(decode.int),
  )
  use marker <- decode.optional_field(
    "Marker",
    option.None,
    decode.optional(decode.string),
  )
  use include_shared <- decode.optional_field(
    "IncludeShared",
    option.None,
    decode.optional(decode.bool),
  )
  use include_public <- decode.optional_field(
    "IncludePublic",
    option.None,
    decode.optional(decode.bool),
  )
  use dbi_resource_id <- decode.optional_field(
    "DbiResourceId",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(DescribeDBSnapshotsInput(
    db_instance_identifier: db_instance_identifier,
    db_snapshot_identifier: db_snapshot_identifier,
    snapshot_type: snapshot_type,
    filters: filters,
    max_records: max_records,
    marker: marker,
    include_shared: include_shared,
    include_public: include_public,
    dbi_resource_id: dbi_resource_id,
  ))
}

pub fn decode_describe_db_snapshots_input(
  json_string: String,
) -> Result(DescribeDBSnapshotsInput, String) {
  result.map_error(
    json.parse(json_string, decode_describe_db_snapshots_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_describe_db_snapshots_request(
  input: DescribeDBSnapshotsInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DescribeDBSnapshots&Version=2014-10-31"
  let body = case input.db_instance_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DBInstanceIdentifier",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.db_snapshot_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DBSnapshotIdentifier",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.snapshot_type {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "SnapshotType", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.filters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Filters", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_filter_at(
                  string.concat(["Filters", ".Filter.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.max_records {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxRecords", "=", int.to_string(v)]),
      ])
  }
  let body = case input.marker {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Marker", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.include_shared {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "IncludeShared",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.include_public {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "IncludePublic",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.dbi_resource_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DbiResourceId", "=", uri.encode_component(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_describe_db_snapshots_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribeDBSnapshotsOutput, String) {
  Ok(DescribeDBSnapshotsOutput)
}

pub type DescribeDBSnapshotTenantDatabasesInput {
  DescribeDBSnapshotTenantDatabasesInput(
    db_instance_identifier: option.Option(String),
    db_snapshot_identifier: option.Option(String),
    snapshot_type: option.Option(String),
    filters: option.Option(List(Filter)),
    max_records: option.Option(Int),
    marker: option.Option(String),
    dbi_resource_id: option.Option(String),
  )
}

pub fn describe_db_snapshot_tenant_databases_input_default() -> DescribeDBSnapshotTenantDatabasesInput {
  DescribeDBSnapshotTenantDatabasesInput(
    db_instance_identifier: option.None,
    db_snapshot_identifier: option.None,
    snapshot_type: option.None,
    filters: option.None,
    max_records: option.None,
    marker: option.None,
    dbi_resource_id: option.None,
  )
}

pub type DescribeDBSnapshotTenantDatabasesOutput {
  DescribeDBSnapshotTenantDatabasesOutput
}

pub fn decode_describe_db_snapshot_tenant_databases_input_struct() -> decode.Decoder(
  DescribeDBSnapshotTenantDatabasesInput,
) {
  use <- decode.recursive
  use db_instance_identifier <- decode.optional_field(
    "DBInstanceIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use db_snapshot_identifier <- decode.optional_field(
    "DBSnapshotIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use snapshot_type <- decode.optional_field(
    "SnapshotType",
    option.None,
    decode.optional(decode.string),
  )
  use filters <- decode.optional_field(
    "Filters",
    option.None,
    decode.optional(decode.list(decode_filter_struct_params())),
  )
  use max_records <- decode.optional_field(
    "MaxRecords",
    option.None,
    decode.optional(decode.int),
  )
  use marker <- decode.optional_field(
    "Marker",
    option.None,
    decode.optional(decode.string),
  )
  use dbi_resource_id <- decode.optional_field(
    "DbiResourceId",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(DescribeDBSnapshotTenantDatabasesInput(
    db_instance_identifier: db_instance_identifier,
    db_snapshot_identifier: db_snapshot_identifier,
    snapshot_type: snapshot_type,
    filters: filters,
    max_records: max_records,
    marker: marker,
    dbi_resource_id: dbi_resource_id,
  ))
}

pub fn decode_describe_db_snapshot_tenant_databases_input(
  json_string: String,
) -> Result(DescribeDBSnapshotTenantDatabasesInput, String) {
  result.map_error(
    json.parse(
      json_string,
      decode_describe_db_snapshot_tenant_databases_input_struct(),
    ),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_describe_db_snapshot_tenant_databases_request(
  input: DescribeDBSnapshotTenantDatabasesInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DescribeDBSnapshotTenantDatabases&Version=2014-10-31"
  let body = case input.db_instance_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DBInstanceIdentifier",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.db_snapshot_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DBSnapshotIdentifier",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.snapshot_type {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "SnapshotType", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.filters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Filters", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_filter_at(
                  string.concat(["Filters", ".Filter.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.max_records {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxRecords", "=", int.to_string(v)]),
      ])
  }
  let body = case input.marker {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Marker", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.dbi_resource_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DbiResourceId", "=", uri.encode_component(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_describe_db_snapshot_tenant_databases_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribeDBSnapshotTenantDatabasesOutput, String) {
  Ok(DescribeDBSnapshotTenantDatabasesOutput)
}

pub type DescribeDBSubnetGroupsInput {
  DescribeDBSubnetGroupsInput(
    db_subnet_group_name: option.Option(String),
    filters: option.Option(List(Filter)),
    max_records: option.Option(Int),
    marker: option.Option(String),
  )
}

pub fn describe_db_subnet_groups_input_default() -> DescribeDBSubnetGroupsInput {
  DescribeDBSubnetGroupsInput(
    db_subnet_group_name: option.None,
    filters: option.None,
    max_records: option.None,
    marker: option.None,
  )
}

pub type DescribeDBSubnetGroupsOutput {
  DescribeDBSubnetGroupsOutput
}

pub fn decode_describe_db_subnet_groups_input_struct() -> decode.Decoder(
  DescribeDBSubnetGroupsInput,
) {
  use <- decode.recursive
  use db_subnet_group_name <- decode.optional_field(
    "DBSubnetGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use filters <- decode.optional_field(
    "Filters",
    option.None,
    decode.optional(decode.list(decode_filter_struct_params())),
  )
  use max_records <- decode.optional_field(
    "MaxRecords",
    option.None,
    decode.optional(decode.int),
  )
  use marker <- decode.optional_field(
    "Marker",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(DescribeDBSubnetGroupsInput(
    db_subnet_group_name: db_subnet_group_name,
    filters: filters,
    max_records: max_records,
    marker: marker,
  ))
}

pub fn decode_describe_db_subnet_groups_input(
  json_string: String,
) -> Result(DescribeDBSubnetGroupsInput, String) {
  result.map_error(
    json.parse(json_string, decode_describe_db_subnet_groups_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_describe_db_subnet_groups_request(
  input: DescribeDBSubnetGroupsInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DescribeDBSubnetGroups&Version=2014-10-31"
  let body = case input.db_subnet_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DBSubnetGroupName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.filters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Filters", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_filter_at(
                  string.concat(["Filters", ".Filter.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.max_records {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxRecords", "=", int.to_string(v)]),
      ])
  }
  let body = case input.marker {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Marker", "=", uri.encode_component(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_describe_db_subnet_groups_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribeDBSubnetGroupsOutput, String) {
  Ok(DescribeDBSubnetGroupsOutput)
}

pub type DescribeEngineDefaultClusterParametersInput {
  DescribeEngineDefaultClusterParametersInput(
    db_parameter_group_family: String,
    filters: option.Option(List(Filter)),
    max_records: option.Option(Int),
    marker: option.Option(String),
  )
}

pub fn describe_engine_default_cluster_parameters_input_default(
  db_parameter_group_family db_parameter_group_family: String,
) -> DescribeEngineDefaultClusterParametersInput {
  DescribeEngineDefaultClusterParametersInput(
    db_parameter_group_family: db_parameter_group_family,
    filters: option.None,
    max_records: option.None,
    marker: option.None,
  )
}

pub type DescribeEngineDefaultClusterParametersOutput {
  DescribeEngineDefaultClusterParametersOutput
}

pub fn decode_describe_engine_default_cluster_parameters_input_struct() -> decode.Decoder(
  DescribeEngineDefaultClusterParametersInput,
) {
  use <- decode.recursive
  use db_parameter_group_family <- decode.field(
    "DBParameterGroupFamily",
    decode.string,
  )
  use filters <- decode.optional_field(
    "Filters",
    option.None,
    decode.optional(decode.list(decode_filter_struct_params())),
  )
  use max_records <- decode.optional_field(
    "MaxRecords",
    option.None,
    decode.optional(decode.int),
  )
  use marker <- decode.optional_field(
    "Marker",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(DescribeEngineDefaultClusterParametersInput(
    db_parameter_group_family: db_parameter_group_family,
    filters: filters,
    max_records: max_records,
    marker: marker,
  ))
}

pub fn decode_describe_engine_default_cluster_parameters_input(
  json_string: String,
) -> Result(DescribeEngineDefaultClusterParametersInput, String) {
  result.map_error(
    json.parse(
      json_string,
      decode_describe_engine_default_cluster_parameters_input_struct(),
    ),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_describe_engine_default_cluster_parameters_request(
  input: DescribeEngineDefaultClusterParametersInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DescribeEngineDefaultClusterParameters&Version=2014-10-31"
  let body = {
    let v = input.db_parameter_group_family
    string.concat([
      body,
      string.concat([
        "&",
        "DBParameterGroupFamily",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body = case input.filters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Filters", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_filter_at(
                  string.concat(["Filters", ".Filter.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.max_records {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxRecords", "=", int.to_string(v)]),
      ])
  }
  let body = case input.marker {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Marker", "=", uri.encode_component(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_describe_engine_default_cluster_parameters_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribeEngineDefaultClusterParametersOutput, String) {
  Ok(DescribeEngineDefaultClusterParametersOutput)
}

pub type DescribeEngineDefaultParametersInput {
  DescribeEngineDefaultParametersInput(
    db_parameter_group_family: String,
    filters: option.Option(List(Filter)),
    max_records: option.Option(Int),
    marker: option.Option(String),
  )
}

pub fn describe_engine_default_parameters_input_default(
  db_parameter_group_family db_parameter_group_family: String,
) -> DescribeEngineDefaultParametersInput {
  DescribeEngineDefaultParametersInput(
    db_parameter_group_family: db_parameter_group_family,
    filters: option.None,
    max_records: option.None,
    marker: option.None,
  )
}

pub type DescribeEngineDefaultParametersOutput {
  DescribeEngineDefaultParametersOutput
}

pub fn decode_describe_engine_default_parameters_input_struct() -> decode.Decoder(
  DescribeEngineDefaultParametersInput,
) {
  use <- decode.recursive
  use db_parameter_group_family <- decode.field(
    "DBParameterGroupFamily",
    decode.string,
  )
  use filters <- decode.optional_field(
    "Filters",
    option.None,
    decode.optional(decode.list(decode_filter_struct_params())),
  )
  use max_records <- decode.optional_field(
    "MaxRecords",
    option.None,
    decode.optional(decode.int),
  )
  use marker <- decode.optional_field(
    "Marker",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(DescribeEngineDefaultParametersInput(
    db_parameter_group_family: db_parameter_group_family,
    filters: filters,
    max_records: max_records,
    marker: marker,
  ))
}

pub fn decode_describe_engine_default_parameters_input(
  json_string: String,
) -> Result(DescribeEngineDefaultParametersInput, String) {
  result.map_error(
    json.parse(
      json_string,
      decode_describe_engine_default_parameters_input_struct(),
    ),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_describe_engine_default_parameters_request(
  input: DescribeEngineDefaultParametersInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DescribeEngineDefaultParameters&Version=2014-10-31"
  let body = {
    let v = input.db_parameter_group_family
    string.concat([
      body,
      string.concat([
        "&",
        "DBParameterGroupFamily",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body = case input.filters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Filters", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_filter_at(
                  string.concat(["Filters", ".Filter.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.max_records {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxRecords", "=", int.to_string(v)]),
      ])
  }
  let body = case input.marker {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Marker", "=", uri.encode_component(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_describe_engine_default_parameters_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribeEngineDefaultParametersOutput, String) {
  Ok(DescribeEngineDefaultParametersOutput)
}

pub type DescribeEventCategoriesInput {
  DescribeEventCategoriesInput(
    source_type: option.Option(String),
    filters: option.Option(List(Filter)),
  )
}

pub fn describe_event_categories_input_default() -> DescribeEventCategoriesInput {
  DescribeEventCategoriesInput(source_type: option.None, filters: option.None)
}

pub type DescribeEventCategoriesOutput {
  DescribeEventCategoriesOutput
}

pub fn decode_describe_event_categories_input_struct() -> decode.Decoder(
  DescribeEventCategoriesInput,
) {
  use <- decode.recursive
  use source_type <- decode.optional_field(
    "SourceType",
    option.None,
    decode.optional(decode.string),
  )
  use filters <- decode.optional_field(
    "Filters",
    option.None,
    decode.optional(decode.list(decode_filter_struct_params())),
  )
  decode.success(DescribeEventCategoriesInput(
    source_type: source_type,
    filters: filters,
  ))
}

pub fn decode_describe_event_categories_input(
  json_string: String,
) -> Result(DescribeEventCategoriesInput, String) {
  result.map_error(
    json.parse(json_string, decode_describe_event_categories_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_describe_event_categories_request(
  input: DescribeEventCategoriesInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DescribeEventCategories&Version=2014-10-31"
  let body = case input.source_type {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "SourceType", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.filters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Filters", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_filter_at(
                  string.concat(["Filters", ".Filter.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_describe_event_categories_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribeEventCategoriesOutput, String) {
  Ok(DescribeEventCategoriesOutput)
}

pub type DescribeEventsInput {
  DescribeEventsInput(
    source_identifier: option.Option(String),
    source_type: option.Option(SourceType),
    start_time: option.Option(json_timestamp.Timestamp),
    end_time: option.Option(json_timestamp.Timestamp),
    duration: option.Option(Int),
    event_categories: option.Option(List(String)),
    filters: option.Option(List(Filter)),
    max_records: option.Option(Int),
    marker: option.Option(String),
  )
}

pub fn describe_events_input_default() -> DescribeEventsInput {
  DescribeEventsInput(
    source_identifier: option.None,
    source_type: option.None,
    start_time: option.None,
    end_time: option.None,
    duration: option.None,
    event_categories: option.None,
    filters: option.None,
    max_records: option.None,
    marker: option.None,
  )
}

pub type DescribeEventsOutput {
  DescribeEventsOutput
}

pub fn decode_describe_events_input_struct() -> decode.Decoder(
  DescribeEventsInput,
) {
  use <- decode.recursive
  use source_identifier <- decode.optional_field(
    "SourceIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use source_type <- decode.optional_field(
    "SourceType",
    option.None,
    decode.optional(decode_source_type_enum()),
  )
  use start_time <- decode.optional_field(
    "StartTime",
    option.None,
    decode.optional(json_timestamp.decoder_precise()),
  )
  use end_time <- decode.optional_field(
    "EndTime",
    option.None,
    decode.optional(json_timestamp.decoder_precise()),
  )
  use duration <- decode.optional_field(
    "Duration",
    option.None,
    decode.optional(decode.int),
  )
  use event_categories <- decode.optional_field(
    "EventCategories",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use filters <- decode.optional_field(
    "Filters",
    option.None,
    decode.optional(decode.list(decode_filter_struct_params())),
  )
  use max_records <- decode.optional_field(
    "MaxRecords",
    option.None,
    decode.optional(decode.int),
  )
  use marker <- decode.optional_field(
    "Marker",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(DescribeEventsInput(
    source_identifier: source_identifier,
    source_type: source_type,
    start_time: start_time,
    end_time: end_time,
    duration: duration,
    event_categories: event_categories,
    filters: filters,
    max_records: max_records,
    marker: marker,
  ))
}

pub fn decode_describe_events_input(
  json_string: String,
) -> Result(DescribeEventsInput, String) {
  result.map_error(
    json.parse(json_string, decode_describe_events_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_describe_events_request(
  input: DescribeEventsInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DescribeEvents&Version=2014-10-31"
  let body = case input.source_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "SourceIdentifier", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.source_type {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "SourceType",
          "=",
          uri.encode_component(source_type_to_wire(v)),
        ]),
      ])
  }
  let body = case input.start_time {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "StartTime",
          "=",
          uri.encode_component(json_timestamp.format_iso8601_precise(v)),
        ]),
      ])
  }
  let body = case input.end_time {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EndTime",
          "=",
          uri.encode_component(json_timestamp.format_iso8601_precise(v)),
        ]),
      ])
  }
  let body = case input.duration {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Duration", "=", int.to_string(v)]),
      ])
  }
  let body = case input.event_categories {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "EventCategories", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "EventCategories",
                    ".EventCategory.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body = case input.filters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Filters", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_filter_at(
                  string.concat(["Filters", ".Filter.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.max_records {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxRecords", "=", int.to_string(v)]),
      ])
  }
  let body = case input.marker {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Marker", "=", uri.encode_component(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_describe_events_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribeEventsOutput, String) {
  Ok(DescribeEventsOutput)
}

pub type DescribeEventSubscriptionsInput {
  DescribeEventSubscriptionsInput(
    subscription_name: option.Option(String),
    filters: option.Option(List(Filter)),
    max_records: option.Option(Int),
    marker: option.Option(String),
  )
}

pub fn describe_event_subscriptions_input_default() -> DescribeEventSubscriptionsInput {
  DescribeEventSubscriptionsInput(
    subscription_name: option.None,
    filters: option.None,
    max_records: option.None,
    marker: option.None,
  )
}

pub type DescribeEventSubscriptionsOutput {
  DescribeEventSubscriptionsOutput
}

pub fn decode_describe_event_subscriptions_input_struct() -> decode.Decoder(
  DescribeEventSubscriptionsInput,
) {
  use <- decode.recursive
  use subscription_name <- decode.optional_field(
    "SubscriptionName",
    option.None,
    decode.optional(decode.string),
  )
  use filters <- decode.optional_field(
    "Filters",
    option.None,
    decode.optional(decode.list(decode_filter_struct_params())),
  )
  use max_records <- decode.optional_field(
    "MaxRecords",
    option.None,
    decode.optional(decode.int),
  )
  use marker <- decode.optional_field(
    "Marker",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(DescribeEventSubscriptionsInput(
    subscription_name: subscription_name,
    filters: filters,
    max_records: max_records,
    marker: marker,
  ))
}

pub fn decode_describe_event_subscriptions_input(
  json_string: String,
) -> Result(DescribeEventSubscriptionsInput, String) {
  result.map_error(
    json.parse(json_string, decode_describe_event_subscriptions_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_describe_event_subscriptions_request(
  input: DescribeEventSubscriptionsInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DescribeEventSubscriptions&Version=2014-10-31"
  let body = case input.subscription_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "SubscriptionName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.filters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Filters", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_filter_at(
                  string.concat(["Filters", ".Filter.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.max_records {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxRecords", "=", int.to_string(v)]),
      ])
  }
  let body = case input.marker {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Marker", "=", uri.encode_component(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_describe_event_subscriptions_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribeEventSubscriptionsOutput, String) {
  Ok(DescribeEventSubscriptionsOutput)
}

pub type DescribeExportTasksInput {
  DescribeExportTasksInput(
    export_task_identifier: option.Option(String),
    source_arn: option.Option(String),
    filters: option.Option(List(Filter)),
    marker: option.Option(String),
    max_records: option.Option(Int),
    source_type: option.Option(ExportSourceType),
  )
}

pub fn describe_export_tasks_input_default() -> DescribeExportTasksInput {
  DescribeExportTasksInput(
    export_task_identifier: option.None,
    source_arn: option.None,
    filters: option.None,
    marker: option.None,
    max_records: option.None,
    source_type: option.None,
  )
}

pub type DescribeExportTasksOutput {
  DescribeExportTasksOutput
}

pub fn decode_describe_export_tasks_input_struct() -> decode.Decoder(
  DescribeExportTasksInput,
) {
  use <- decode.recursive
  use export_task_identifier <- decode.optional_field(
    "ExportTaskIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use source_arn <- decode.optional_field(
    "SourceArn",
    option.None,
    decode.optional(decode.string),
  )
  use filters <- decode.optional_field(
    "Filters",
    option.None,
    decode.optional(decode.list(decode_filter_struct_params())),
  )
  use marker <- decode.optional_field(
    "Marker",
    option.None,
    decode.optional(decode.string),
  )
  use max_records <- decode.optional_field(
    "MaxRecords",
    option.None,
    decode.optional(decode.int),
  )
  use source_type <- decode.optional_field(
    "SourceType",
    option.None,
    decode.optional(decode_export_source_type_enum()),
  )
  decode.success(DescribeExportTasksInput(
    export_task_identifier: export_task_identifier,
    source_arn: source_arn,
    filters: filters,
    marker: marker,
    max_records: max_records,
    source_type: source_type,
  ))
}

pub fn decode_describe_export_tasks_input(
  json_string: String,
) -> Result(DescribeExportTasksInput, String) {
  result.map_error(
    json.parse(json_string, decode_describe_export_tasks_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_describe_export_tasks_request(
  input: DescribeExportTasksInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DescribeExportTasks&Version=2014-10-31"
  let body = case input.export_task_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "ExportTaskIdentifier",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.source_arn {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "SourceArn", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.filters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Filters", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_filter_at(
                  string.concat(["Filters", ".Filter.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.marker {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Marker", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.max_records {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxRecords", "=", int.to_string(v)]),
      ])
  }
  let body = case input.source_type {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "SourceType",
          "=",
          uri.encode_component(export_source_type_to_wire(v)),
        ]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_describe_export_tasks_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribeExportTasksOutput, String) {
  Ok(DescribeExportTasksOutput)
}

pub type DescribeGlobalClustersInput {
  DescribeGlobalClustersInput(
    global_cluster_identifier: option.Option(String),
    filters: option.Option(List(Filter)),
    max_records: option.Option(Int),
    marker: option.Option(String),
  )
}

pub fn describe_global_clusters_input_default() -> DescribeGlobalClustersInput {
  DescribeGlobalClustersInput(
    global_cluster_identifier: option.None,
    filters: option.None,
    max_records: option.None,
    marker: option.None,
  )
}

pub type DescribeGlobalClustersOutput {
  DescribeGlobalClustersOutput
}

pub fn decode_describe_global_clusters_input_struct() -> decode.Decoder(
  DescribeGlobalClustersInput,
) {
  use <- decode.recursive
  use global_cluster_identifier <- decode.optional_field(
    "GlobalClusterIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use filters <- decode.optional_field(
    "Filters",
    option.None,
    decode.optional(decode.list(decode_filter_struct_params())),
  )
  use max_records <- decode.optional_field(
    "MaxRecords",
    option.None,
    decode.optional(decode.int),
  )
  use marker <- decode.optional_field(
    "Marker",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(DescribeGlobalClustersInput(
    global_cluster_identifier: global_cluster_identifier,
    filters: filters,
    max_records: max_records,
    marker: marker,
  ))
}

pub fn decode_describe_global_clusters_input(
  json_string: String,
) -> Result(DescribeGlobalClustersInput, String) {
  result.map_error(
    json.parse(json_string, decode_describe_global_clusters_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_describe_global_clusters_request(
  input: DescribeGlobalClustersInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DescribeGlobalClusters&Version=2014-10-31"
  let body = case input.global_cluster_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "GlobalClusterIdentifier",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.filters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Filters", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_filter_at(
                  string.concat(["Filters", ".Filter.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.max_records {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxRecords", "=", int.to_string(v)]),
      ])
  }
  let body = case input.marker {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Marker", "=", uri.encode_component(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_describe_global_clusters_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribeGlobalClustersOutput, String) {
  Ok(DescribeGlobalClustersOutput)
}

pub type DescribeIntegrationsInput {
  DescribeIntegrationsInput(
    integration_identifier: option.Option(String),
    filters: option.Option(List(Filter)),
    max_records: option.Option(Int),
    marker: option.Option(String),
  )
}

pub fn describe_integrations_input_default() -> DescribeIntegrationsInput {
  DescribeIntegrationsInput(
    integration_identifier: option.None,
    filters: option.None,
    max_records: option.None,
    marker: option.None,
  )
}

pub type DescribeIntegrationsOutput {
  DescribeIntegrationsOutput
}

pub fn decode_describe_integrations_input_struct() -> decode.Decoder(
  DescribeIntegrationsInput,
) {
  use <- decode.recursive
  use integration_identifier <- decode.optional_field(
    "IntegrationIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use filters <- decode.optional_field(
    "Filters",
    option.None,
    decode.optional(decode.list(decode_filter_struct_params())),
  )
  use max_records <- decode.optional_field(
    "MaxRecords",
    option.None,
    decode.optional(decode.int),
  )
  use marker <- decode.optional_field(
    "Marker",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(DescribeIntegrationsInput(
    integration_identifier: integration_identifier,
    filters: filters,
    max_records: max_records,
    marker: marker,
  ))
}

pub fn decode_describe_integrations_input(
  json_string: String,
) -> Result(DescribeIntegrationsInput, String) {
  result.map_error(
    json.parse(json_string, decode_describe_integrations_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_describe_integrations_request(
  input: DescribeIntegrationsInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DescribeIntegrations&Version=2014-10-31"
  let body = case input.integration_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "IntegrationIdentifier",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.filters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Filters", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_filter_at(
                  string.concat(["Filters", ".Filter.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.max_records {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxRecords", "=", int.to_string(v)]),
      ])
  }
  let body = case input.marker {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Marker", "=", uri.encode_component(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_describe_integrations_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribeIntegrationsOutput, String) {
  Ok(DescribeIntegrationsOutput)
}

pub type DescribeOptionGroupOptionsInput {
  DescribeOptionGroupOptionsInput(
    engine_name: String,
    major_engine_version: option.Option(String),
    filters: option.Option(List(Filter)),
    max_records: option.Option(Int),
    marker: option.Option(String),
  )
}

pub fn describe_option_group_options_input_default(
  engine_name engine_name: String,
) -> DescribeOptionGroupOptionsInput {
  DescribeOptionGroupOptionsInput(
    engine_name: engine_name,
    major_engine_version: option.None,
    filters: option.None,
    max_records: option.None,
    marker: option.None,
  )
}

pub type DescribeOptionGroupOptionsOutput {
  DescribeOptionGroupOptionsOutput
}

pub fn decode_describe_option_group_options_input_struct() -> decode.Decoder(
  DescribeOptionGroupOptionsInput,
) {
  use <- decode.recursive
  use engine_name <- decode.field("EngineName", decode.string)
  use major_engine_version <- decode.optional_field(
    "MajorEngineVersion",
    option.None,
    decode.optional(decode.string),
  )
  use filters <- decode.optional_field(
    "Filters",
    option.None,
    decode.optional(decode.list(decode_filter_struct_params())),
  )
  use max_records <- decode.optional_field(
    "MaxRecords",
    option.None,
    decode.optional(decode.int),
  )
  use marker <- decode.optional_field(
    "Marker",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(DescribeOptionGroupOptionsInput(
    engine_name: engine_name,
    major_engine_version: major_engine_version,
    filters: filters,
    max_records: max_records,
    marker: marker,
  ))
}

pub fn decode_describe_option_group_options_input(
  json_string: String,
) -> Result(DescribeOptionGroupOptionsInput, String) {
  result.map_error(
    json.parse(json_string, decode_describe_option_group_options_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_describe_option_group_options_request(
  input: DescribeOptionGroupOptionsInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DescribeOptionGroupOptions&Version=2014-10-31"
  let body = {
    let v = input.engine_name
    string.concat([
      body,
      string.concat(["&", "EngineName", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.major_engine_version {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MajorEngineVersion", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.filters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Filters", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_filter_at(
                  string.concat(["Filters", ".Filter.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.max_records {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxRecords", "=", int.to_string(v)]),
      ])
  }
  let body = case input.marker {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Marker", "=", uri.encode_component(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_describe_option_group_options_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribeOptionGroupOptionsOutput, String) {
  Ok(DescribeOptionGroupOptionsOutput)
}

pub type DescribeOptionGroupsInput {
  DescribeOptionGroupsInput(
    option_group_name: option.Option(String),
    filters: option.Option(List(Filter)),
    marker: option.Option(String),
    max_records: option.Option(Int),
    engine_name: option.Option(String),
    major_engine_version: option.Option(String),
  )
}

pub fn describe_option_groups_input_default() -> DescribeOptionGroupsInput {
  DescribeOptionGroupsInput(
    option_group_name: option.None,
    filters: option.None,
    marker: option.None,
    max_records: option.None,
    engine_name: option.None,
    major_engine_version: option.None,
  )
}

pub type DescribeOptionGroupsOutput {
  DescribeOptionGroupsOutput
}

pub fn decode_describe_option_groups_input_struct() -> decode.Decoder(
  DescribeOptionGroupsInput,
) {
  use <- decode.recursive
  use option_group_name <- decode.optional_field(
    "OptionGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use filters <- decode.optional_field(
    "Filters",
    option.None,
    decode.optional(decode.list(decode_filter_struct_params())),
  )
  use marker <- decode.optional_field(
    "Marker",
    option.None,
    decode.optional(decode.string),
  )
  use max_records <- decode.optional_field(
    "MaxRecords",
    option.None,
    decode.optional(decode.int),
  )
  use engine_name <- decode.optional_field(
    "EngineName",
    option.None,
    decode.optional(decode.string),
  )
  use major_engine_version <- decode.optional_field(
    "MajorEngineVersion",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(DescribeOptionGroupsInput(
    option_group_name: option_group_name,
    filters: filters,
    marker: marker,
    max_records: max_records,
    engine_name: engine_name,
    major_engine_version: major_engine_version,
  ))
}

pub fn decode_describe_option_groups_input(
  json_string: String,
) -> Result(DescribeOptionGroupsInput, String) {
  result.map_error(
    json.parse(json_string, decode_describe_option_groups_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_describe_option_groups_request(
  input: DescribeOptionGroupsInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DescribeOptionGroups&Version=2014-10-31"
  let body = case input.option_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "OptionGroupName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.filters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Filters", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_filter_at(
                  string.concat(["Filters", ".Filter.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.marker {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Marker", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.max_records {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxRecords", "=", int.to_string(v)]),
      ])
  }
  let body = case input.engine_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "EngineName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.major_engine_version {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MajorEngineVersion", "=", uri.encode_component(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_describe_option_groups_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribeOptionGroupsOutput, String) {
  Ok(DescribeOptionGroupsOutput)
}

pub type DescribeOrderableDBInstanceOptionsInput {
  DescribeOrderableDBInstanceOptionsInput(
    engine: String,
    engine_version: option.Option(String),
    db_instance_class: option.Option(String),
    license_model: option.Option(String),
    availability_zone_group: option.Option(String),
    vpc: option.Option(Bool),
    filters: option.Option(List(Filter)),
    max_records: option.Option(Int),
    marker: option.Option(String),
  )
}

pub fn describe_orderable_db_instance_options_input_default(
  engine engine: String,
) -> DescribeOrderableDBInstanceOptionsInput {
  DescribeOrderableDBInstanceOptionsInput(
    engine: engine,
    engine_version: option.None,
    db_instance_class: option.None,
    license_model: option.None,
    availability_zone_group: option.None,
    vpc: option.None,
    filters: option.None,
    max_records: option.None,
    marker: option.None,
  )
}

pub type DescribeOrderableDBInstanceOptionsOutput {
  DescribeOrderableDBInstanceOptionsOutput
}

pub fn decode_describe_orderable_db_instance_options_input_struct() -> decode.Decoder(
  DescribeOrderableDBInstanceOptionsInput,
) {
  use <- decode.recursive
  use engine <- decode.field("Engine", decode.string)
  use engine_version <- decode.optional_field(
    "EngineVersion",
    option.None,
    decode.optional(decode.string),
  )
  use db_instance_class <- decode.optional_field(
    "DBInstanceClass",
    option.None,
    decode.optional(decode.string),
  )
  use license_model <- decode.optional_field(
    "LicenseModel",
    option.None,
    decode.optional(decode.string),
  )
  use availability_zone_group <- decode.optional_field(
    "AvailabilityZoneGroup",
    option.None,
    decode.optional(decode.string),
  )
  use vpc <- decode.optional_field(
    "Vpc",
    option.None,
    decode.optional(decode.bool),
  )
  use filters <- decode.optional_field(
    "Filters",
    option.None,
    decode.optional(decode.list(decode_filter_struct_params())),
  )
  use max_records <- decode.optional_field(
    "MaxRecords",
    option.None,
    decode.optional(decode.int),
  )
  use marker <- decode.optional_field(
    "Marker",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(DescribeOrderableDBInstanceOptionsInput(
    engine: engine,
    engine_version: engine_version,
    db_instance_class: db_instance_class,
    license_model: license_model,
    availability_zone_group: availability_zone_group,
    vpc: vpc,
    filters: filters,
    max_records: max_records,
    marker: marker,
  ))
}

pub fn decode_describe_orderable_db_instance_options_input(
  json_string: String,
) -> Result(DescribeOrderableDBInstanceOptionsInput, String) {
  result.map_error(
    json.parse(
      json_string,
      decode_describe_orderable_db_instance_options_input_struct(),
    ),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_describe_orderable_db_instance_options_request(
  input: DescribeOrderableDBInstanceOptionsInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DescribeOrderableDBInstanceOptions&Version=2014-10-31"
  let body = {
    let v = input.engine
    string.concat([
      body,
      string.concat(["&", "Engine", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.engine_version {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "EngineVersion", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.db_instance_class {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DBInstanceClass", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.license_model {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "LicenseModel", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.availability_zone_group {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "AvailabilityZoneGroup",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.vpc {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "Vpc",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.filters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Filters", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_filter_at(
                  string.concat(["Filters", ".Filter.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.max_records {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxRecords", "=", int.to_string(v)]),
      ])
  }
  let body = case input.marker {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Marker", "=", uri.encode_component(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_describe_orderable_db_instance_options_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribeOrderableDBInstanceOptionsOutput, String) {
  Ok(DescribeOrderableDBInstanceOptionsOutput)
}

pub type DescribePendingMaintenanceActionsInput {
  DescribePendingMaintenanceActionsInput(
    resource_identifier: option.Option(String),
    filters: option.Option(List(Filter)),
    marker: option.Option(String),
    max_records: option.Option(Int),
  )
}

pub fn describe_pending_maintenance_actions_input_default() -> DescribePendingMaintenanceActionsInput {
  DescribePendingMaintenanceActionsInput(
    resource_identifier: option.None,
    filters: option.None,
    marker: option.None,
    max_records: option.None,
  )
}

pub type DescribePendingMaintenanceActionsOutput {
  DescribePendingMaintenanceActionsOutput
}

pub fn decode_describe_pending_maintenance_actions_input_struct() -> decode.Decoder(
  DescribePendingMaintenanceActionsInput,
) {
  use <- decode.recursive
  use resource_identifier <- decode.optional_field(
    "ResourceIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use filters <- decode.optional_field(
    "Filters",
    option.None,
    decode.optional(decode.list(decode_filter_struct_params())),
  )
  use marker <- decode.optional_field(
    "Marker",
    option.None,
    decode.optional(decode.string),
  )
  use max_records <- decode.optional_field(
    "MaxRecords",
    option.None,
    decode.optional(decode.int),
  )
  decode.success(DescribePendingMaintenanceActionsInput(
    resource_identifier: resource_identifier,
    filters: filters,
    marker: marker,
    max_records: max_records,
  ))
}

pub fn decode_describe_pending_maintenance_actions_input(
  json_string: String,
) -> Result(DescribePendingMaintenanceActionsInput, String) {
  result.map_error(
    json.parse(
      json_string,
      decode_describe_pending_maintenance_actions_input_struct(),
    ),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_describe_pending_maintenance_actions_request(
  input: DescribePendingMaintenanceActionsInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DescribePendingMaintenanceActions&Version=2014-10-31"
  let body = case input.resource_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "ResourceIdentifier", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.filters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Filters", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_filter_at(
                  string.concat(["Filters", ".Filter.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.marker {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Marker", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.max_records {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxRecords", "=", int.to_string(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_describe_pending_maintenance_actions_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribePendingMaintenanceActionsOutput, String) {
  Ok(DescribePendingMaintenanceActionsOutput)
}

pub type DescribeReservedDBInstancesInput {
  DescribeReservedDBInstancesInput(
    reserved_db_instance_id: option.Option(String),
    reserved_db_instances_offering_id: option.Option(String),
    db_instance_class: option.Option(String),
    duration: option.Option(String),
    product_description: option.Option(String),
    offering_type: option.Option(String),
    multi_az: option.Option(Bool),
    lease_id: option.Option(String),
    filters: option.Option(List(Filter)),
    max_records: option.Option(Int),
    marker: option.Option(String),
  )
}

pub fn describe_reserved_db_instances_input_default() -> DescribeReservedDBInstancesInput {
  DescribeReservedDBInstancesInput(
    reserved_db_instance_id: option.None,
    reserved_db_instances_offering_id: option.None,
    db_instance_class: option.None,
    duration: option.None,
    product_description: option.None,
    offering_type: option.None,
    multi_az: option.None,
    lease_id: option.None,
    filters: option.None,
    max_records: option.None,
    marker: option.None,
  )
}

pub type DescribeReservedDBInstancesOutput {
  DescribeReservedDBInstancesOutput
}

pub fn decode_describe_reserved_db_instances_input_struct() -> decode.Decoder(
  DescribeReservedDBInstancesInput,
) {
  use <- decode.recursive
  use reserved_db_instance_id <- decode.optional_field(
    "ReservedDBInstanceId",
    option.None,
    decode.optional(decode.string),
  )
  use reserved_db_instances_offering_id <- decode.optional_field(
    "ReservedDBInstancesOfferingId",
    option.None,
    decode.optional(decode.string),
  )
  use db_instance_class <- decode.optional_field(
    "DBInstanceClass",
    option.None,
    decode.optional(decode.string),
  )
  use duration <- decode.optional_field(
    "Duration",
    option.None,
    decode.optional(decode.string),
  )
  use product_description <- decode.optional_field(
    "ProductDescription",
    option.None,
    decode.optional(decode.string),
  )
  use offering_type <- decode.optional_field(
    "OfferingType",
    option.None,
    decode.optional(decode.string),
  )
  use multi_az <- decode.optional_field(
    "MultiAZ",
    option.None,
    decode.optional(decode.bool),
  )
  use lease_id <- decode.optional_field(
    "LeaseId",
    option.None,
    decode.optional(decode.string),
  )
  use filters <- decode.optional_field(
    "Filters",
    option.None,
    decode.optional(decode.list(decode_filter_struct_params())),
  )
  use max_records <- decode.optional_field(
    "MaxRecords",
    option.None,
    decode.optional(decode.int),
  )
  use marker <- decode.optional_field(
    "Marker",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(DescribeReservedDBInstancesInput(
    reserved_db_instance_id: reserved_db_instance_id,
    reserved_db_instances_offering_id: reserved_db_instances_offering_id,
    db_instance_class: db_instance_class,
    duration: duration,
    product_description: product_description,
    offering_type: offering_type,
    multi_az: multi_az,
    lease_id: lease_id,
    filters: filters,
    max_records: max_records,
    marker: marker,
  ))
}

pub fn decode_describe_reserved_db_instances_input(
  json_string: String,
) -> Result(DescribeReservedDBInstancesInput, String) {
  result.map_error(
    json.parse(
      json_string,
      decode_describe_reserved_db_instances_input_struct(),
    ),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_describe_reserved_db_instances_request(
  input: DescribeReservedDBInstancesInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DescribeReservedDBInstances&Version=2014-10-31"
  let body = case input.reserved_db_instance_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "ReservedDBInstanceId",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.reserved_db_instances_offering_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "ReservedDBInstancesOfferingId",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.db_instance_class {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DBInstanceClass", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.duration {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Duration", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.product_description {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "ProductDescription", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.offering_type {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "OfferingType", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.multi_az {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "MultiAZ",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.lease_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "LeaseId", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.filters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Filters", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_filter_at(
                  string.concat(["Filters", ".Filter.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.max_records {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxRecords", "=", int.to_string(v)]),
      ])
  }
  let body = case input.marker {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Marker", "=", uri.encode_component(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_describe_reserved_db_instances_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribeReservedDBInstancesOutput, String) {
  Ok(DescribeReservedDBInstancesOutput)
}

pub type DescribeReservedDBInstancesOfferingsInput {
  DescribeReservedDBInstancesOfferingsInput(
    reserved_db_instances_offering_id: option.Option(String),
    db_instance_class: option.Option(String),
    duration: option.Option(String),
    product_description: option.Option(String),
    offering_type: option.Option(String),
    multi_az: option.Option(Bool),
    filters: option.Option(List(Filter)),
    max_records: option.Option(Int),
    marker: option.Option(String),
  )
}

pub fn describe_reserved_db_instances_offerings_input_default() -> DescribeReservedDBInstancesOfferingsInput {
  DescribeReservedDBInstancesOfferingsInput(
    reserved_db_instances_offering_id: option.None,
    db_instance_class: option.None,
    duration: option.None,
    product_description: option.None,
    offering_type: option.None,
    multi_az: option.None,
    filters: option.None,
    max_records: option.None,
    marker: option.None,
  )
}

pub type DescribeReservedDBInstancesOfferingsOutput {
  DescribeReservedDBInstancesOfferingsOutput
}

pub fn decode_describe_reserved_db_instances_offerings_input_struct() -> decode.Decoder(
  DescribeReservedDBInstancesOfferingsInput,
) {
  use <- decode.recursive
  use reserved_db_instances_offering_id <- decode.optional_field(
    "ReservedDBInstancesOfferingId",
    option.None,
    decode.optional(decode.string),
  )
  use db_instance_class <- decode.optional_field(
    "DBInstanceClass",
    option.None,
    decode.optional(decode.string),
  )
  use duration <- decode.optional_field(
    "Duration",
    option.None,
    decode.optional(decode.string),
  )
  use product_description <- decode.optional_field(
    "ProductDescription",
    option.None,
    decode.optional(decode.string),
  )
  use offering_type <- decode.optional_field(
    "OfferingType",
    option.None,
    decode.optional(decode.string),
  )
  use multi_az <- decode.optional_field(
    "MultiAZ",
    option.None,
    decode.optional(decode.bool),
  )
  use filters <- decode.optional_field(
    "Filters",
    option.None,
    decode.optional(decode.list(decode_filter_struct_params())),
  )
  use max_records <- decode.optional_field(
    "MaxRecords",
    option.None,
    decode.optional(decode.int),
  )
  use marker <- decode.optional_field(
    "Marker",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(DescribeReservedDBInstancesOfferingsInput(
    reserved_db_instances_offering_id: reserved_db_instances_offering_id,
    db_instance_class: db_instance_class,
    duration: duration,
    product_description: product_description,
    offering_type: offering_type,
    multi_az: multi_az,
    filters: filters,
    max_records: max_records,
    marker: marker,
  ))
}

pub fn decode_describe_reserved_db_instances_offerings_input(
  json_string: String,
) -> Result(DescribeReservedDBInstancesOfferingsInput, String) {
  result.map_error(
    json.parse(
      json_string,
      decode_describe_reserved_db_instances_offerings_input_struct(),
    ),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_describe_reserved_db_instances_offerings_request(
  input: DescribeReservedDBInstancesOfferingsInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DescribeReservedDBInstancesOfferings&Version=2014-10-31"
  let body = case input.reserved_db_instances_offering_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "ReservedDBInstancesOfferingId",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.db_instance_class {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DBInstanceClass", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.duration {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Duration", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.product_description {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "ProductDescription", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.offering_type {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "OfferingType", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.multi_az {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "MultiAZ",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.filters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Filters", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_filter_at(
                  string.concat(["Filters", ".Filter.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.max_records {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxRecords", "=", int.to_string(v)]),
      ])
  }
  let body = case input.marker {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Marker", "=", uri.encode_component(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_describe_reserved_db_instances_offerings_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribeReservedDBInstancesOfferingsOutput, String) {
  Ok(DescribeReservedDBInstancesOfferingsOutput)
}

pub type DescribeServerlessV2PlatformVersionsInput {
  DescribeServerlessV2PlatformVersionsInput(
    serverless_v2_platform_version: option.Option(String),
    engine: option.Option(String),
    filters: option.Option(List(Filter)),
    default_only: option.Option(Bool),
    include_all: option.Option(Bool),
    max_records: option.Option(Int),
    marker: option.Option(String),
  )
}

pub fn describe_serverless_v2_platform_versions_input_default() -> DescribeServerlessV2PlatformVersionsInput {
  DescribeServerlessV2PlatformVersionsInput(
    serverless_v2_platform_version: option.None,
    engine: option.None,
    filters: option.None,
    default_only: option.None,
    include_all: option.None,
    max_records: option.None,
    marker: option.None,
  )
}

pub type DescribeServerlessV2PlatformVersionsOutput {
  DescribeServerlessV2PlatformVersionsOutput
}

pub fn decode_describe_serverless_v2_platform_versions_input_struct() -> decode.Decoder(
  DescribeServerlessV2PlatformVersionsInput,
) {
  use <- decode.recursive
  use serverless_v2_platform_version <- decode.optional_field(
    "ServerlessV2PlatformVersion",
    option.None,
    decode.optional(decode.string),
  )
  use engine <- decode.optional_field(
    "Engine",
    option.None,
    decode.optional(decode.string),
  )
  use filters <- decode.optional_field(
    "Filters",
    option.None,
    decode.optional(decode.list(decode_filter_struct_params())),
  )
  use default_only <- decode.optional_field(
    "DefaultOnly",
    option.None,
    decode.optional(decode.bool),
  )
  use include_all <- decode.optional_field(
    "IncludeAll",
    option.None,
    decode.optional(decode.bool),
  )
  use max_records <- decode.optional_field(
    "MaxRecords",
    option.None,
    decode.optional(decode.int),
  )
  use marker <- decode.optional_field(
    "Marker",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(DescribeServerlessV2PlatformVersionsInput(
    serverless_v2_platform_version: serverless_v2_platform_version,
    engine: engine,
    filters: filters,
    default_only: default_only,
    include_all: include_all,
    max_records: max_records,
    marker: marker,
  ))
}

pub fn decode_describe_serverless_v2_platform_versions_input(
  json_string: String,
) -> Result(DescribeServerlessV2PlatformVersionsInput, String) {
  result.map_error(
    json.parse(
      json_string,
      decode_describe_serverless_v2_platform_versions_input_struct(),
    ),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_describe_serverless_v2_platform_versions_request(
  input: DescribeServerlessV2PlatformVersionsInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DescribeServerlessV2PlatformVersions&Version=2014-10-31"
  let body = case input.serverless_v2_platform_version {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "ServerlessV2PlatformVersion",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.engine {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Engine", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.filters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Filters", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_filter_at(
                  string.concat(["Filters", ".Filter.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.default_only {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DefaultOnly",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.include_all {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "IncludeAll",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.max_records {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxRecords", "=", int.to_string(v)]),
      ])
  }
  let body = case input.marker {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Marker", "=", uri.encode_component(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_describe_serverless_v2_platform_versions_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribeServerlessV2PlatformVersionsOutput, String) {
  Ok(DescribeServerlessV2PlatformVersionsOutput)
}

pub type DescribeSourceRegionsInput {
  DescribeSourceRegionsInput(
    region_name: option.Option(String),
    max_records: option.Option(Int),
    marker: option.Option(String),
    filters: option.Option(List(Filter)),
  )
}

pub fn describe_source_regions_input_default() -> DescribeSourceRegionsInput {
  DescribeSourceRegionsInput(
    region_name: option.None,
    max_records: option.None,
    marker: option.None,
    filters: option.None,
  )
}

pub type DescribeSourceRegionsOutput {
  DescribeSourceRegionsOutput
}

pub fn decode_describe_source_regions_input_struct() -> decode.Decoder(
  DescribeSourceRegionsInput,
) {
  use <- decode.recursive
  use region_name <- decode.optional_field(
    "RegionName",
    option.None,
    decode.optional(decode.string),
  )
  use max_records <- decode.optional_field(
    "MaxRecords",
    option.None,
    decode.optional(decode.int),
  )
  use marker <- decode.optional_field(
    "Marker",
    option.None,
    decode.optional(decode.string),
  )
  use filters <- decode.optional_field(
    "Filters",
    option.None,
    decode.optional(decode.list(decode_filter_struct_params())),
  )
  decode.success(DescribeSourceRegionsInput(
    region_name: region_name,
    max_records: max_records,
    marker: marker,
    filters: filters,
  ))
}

pub fn decode_describe_source_regions_input(
  json_string: String,
) -> Result(DescribeSourceRegionsInput, String) {
  result.map_error(
    json.parse(json_string, decode_describe_source_regions_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_describe_source_regions_request(
  input: DescribeSourceRegionsInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DescribeSourceRegions&Version=2014-10-31"
  let body = case input.region_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "RegionName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.max_records {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxRecords", "=", int.to_string(v)]),
      ])
  }
  let body = case input.marker {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Marker", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.filters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Filters", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_filter_at(
                  string.concat(["Filters", ".Filter.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_describe_source_regions_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribeSourceRegionsOutput, String) {
  Ok(DescribeSourceRegionsOutput)
}

pub type DescribeTenantDatabasesInput {
  DescribeTenantDatabasesInput(
    db_instance_identifier: option.Option(String),
    tenant_db_name: option.Option(String),
    filters: option.Option(List(Filter)),
    marker: option.Option(String),
    max_records: option.Option(Int),
  )
}

pub fn describe_tenant_databases_input_default() -> DescribeTenantDatabasesInput {
  DescribeTenantDatabasesInput(
    db_instance_identifier: option.None,
    tenant_db_name: option.None,
    filters: option.None,
    marker: option.None,
    max_records: option.None,
  )
}

pub type DescribeTenantDatabasesOutput {
  DescribeTenantDatabasesOutput
}

pub fn decode_describe_tenant_databases_input_struct() -> decode.Decoder(
  DescribeTenantDatabasesInput,
) {
  use <- decode.recursive
  use db_instance_identifier <- decode.optional_field(
    "DBInstanceIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use tenant_db_name <- decode.optional_field(
    "TenantDBName",
    option.None,
    decode.optional(decode.string),
  )
  use filters <- decode.optional_field(
    "Filters",
    option.None,
    decode.optional(decode.list(decode_filter_struct_params())),
  )
  use marker <- decode.optional_field(
    "Marker",
    option.None,
    decode.optional(decode.string),
  )
  use max_records <- decode.optional_field(
    "MaxRecords",
    option.None,
    decode.optional(decode.int),
  )
  decode.success(DescribeTenantDatabasesInput(
    db_instance_identifier: db_instance_identifier,
    tenant_db_name: tenant_db_name,
    filters: filters,
    marker: marker,
    max_records: max_records,
  ))
}

pub fn decode_describe_tenant_databases_input(
  json_string: String,
) -> Result(DescribeTenantDatabasesInput, String) {
  result.map_error(
    json.parse(json_string, decode_describe_tenant_databases_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_describe_tenant_databases_request(
  input: DescribeTenantDatabasesInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DescribeTenantDatabases&Version=2014-10-31"
  let body = case input.db_instance_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DBInstanceIdentifier",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.tenant_db_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "TenantDBName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.filters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Filters", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_filter_at(
                  string.concat(["Filters", ".Filter.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.marker {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Marker", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.max_records {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxRecords", "=", int.to_string(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_describe_tenant_databases_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribeTenantDatabasesOutput, String) {
  Ok(DescribeTenantDatabasesOutput)
}

pub type DescribeValidDBInstanceModificationsInput {
  DescribeValidDBInstanceModificationsInput(db_instance_identifier: String)
}

pub fn describe_valid_db_instance_modifications_input_default(
  db_instance_identifier db_instance_identifier: String,
) -> DescribeValidDBInstanceModificationsInput {
  DescribeValidDBInstanceModificationsInput(
    db_instance_identifier: db_instance_identifier,
  )
}

pub type DescribeValidDBInstanceModificationsOutput {
  DescribeValidDBInstanceModificationsOutput
}

pub fn decode_describe_valid_db_instance_modifications_input_struct() -> decode.Decoder(
  DescribeValidDBInstanceModificationsInput,
) {
  use <- decode.recursive
  use db_instance_identifier <- decode.field(
    "DBInstanceIdentifier",
    decode.string,
  )
  decode.success(DescribeValidDBInstanceModificationsInput(
    db_instance_identifier: db_instance_identifier,
  ))
}

pub fn decode_describe_valid_db_instance_modifications_input(
  json_string: String,
) -> Result(DescribeValidDBInstanceModificationsInput, String) {
  result.map_error(
    json.parse(
      json_string,
      decode_describe_valid_db_instance_modifications_input_struct(),
    ),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_describe_valid_db_instance_modifications_request(
  input: DescribeValidDBInstanceModificationsInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DescribeValidDBInstanceModifications&Version=2014-10-31"
  let body = {
    let v = input.db_instance_identifier
    string.concat([
      body,
      string.concat(["&", "DBInstanceIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_describe_valid_db_instance_modifications_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DescribeValidDBInstanceModificationsOutput, String) {
  Ok(DescribeValidDBInstanceModificationsOutput)
}

pub type DisableHttpEndpointInput {
  DisableHttpEndpointInput(resource_arn: String)
}

pub fn disable_http_endpoint_input_default(
  resource_arn resource_arn: String,
) -> DisableHttpEndpointInput {
  DisableHttpEndpointInput(resource_arn: resource_arn)
}

pub type DisableHttpEndpointOutput {
  DisableHttpEndpointOutput
}

pub fn decode_disable_http_endpoint_input_struct() -> decode.Decoder(
  DisableHttpEndpointInput,
) {
  use <- decode.recursive
  use resource_arn <- decode.field("ResourceArn", decode.string)
  decode.success(DisableHttpEndpointInput(resource_arn: resource_arn))
}

pub fn decode_disable_http_endpoint_input(
  json_string: String,
) -> Result(DisableHttpEndpointInput, String) {
  result.map_error(
    json.parse(json_string, decode_disable_http_endpoint_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_disable_http_endpoint_request(
  input: DisableHttpEndpointInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DisableHttpEndpoint&Version=2014-10-31"
  let body = {
    let v = input.resource_arn
    string.concat([
      body,
      string.concat(["&", "ResourceArn", "=", uri.encode_component(v)]),
    ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_disable_http_endpoint_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DisableHttpEndpointOutput, String) {
  Ok(DisableHttpEndpointOutput)
}

pub type DownloadDBLogFilePortionInput {
  DownloadDBLogFilePortionInput(
    db_instance_identifier: String,
    log_file_name: String,
    marker: option.Option(String),
    number_of_lines: option.Option(Int),
  )
}

pub fn download_db_log_file_portion_input_default(
  db_instance_identifier db_instance_identifier: String,
  log_file_name log_file_name: String,
) -> DownloadDBLogFilePortionInput {
  DownloadDBLogFilePortionInput(
    db_instance_identifier: db_instance_identifier,
    log_file_name: log_file_name,
    marker: option.None,
    number_of_lines: option.None,
  )
}

pub type DownloadDBLogFilePortionOutput {
  DownloadDBLogFilePortionOutput
}

pub fn decode_download_db_log_file_portion_input_struct() -> decode.Decoder(
  DownloadDBLogFilePortionInput,
) {
  use <- decode.recursive
  use db_instance_identifier <- decode.field(
    "DBInstanceIdentifier",
    decode.string,
  )
  use log_file_name <- decode.field("LogFileName", decode.string)
  use marker <- decode.optional_field(
    "Marker",
    option.None,
    decode.optional(decode.string),
  )
  use number_of_lines <- decode.optional_field(
    "NumberOfLines",
    option.None,
    decode.optional(decode.int),
  )
  decode.success(DownloadDBLogFilePortionInput(
    db_instance_identifier: db_instance_identifier,
    log_file_name: log_file_name,
    marker: marker,
    number_of_lines: number_of_lines,
  ))
}

pub fn decode_download_db_log_file_portion_input(
  json_string: String,
) -> Result(DownloadDBLogFilePortionInput, String) {
  result.map_error(
    json.parse(json_string, decode_download_db_log_file_portion_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_download_db_log_file_portion_request(
  input: DownloadDBLogFilePortionInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=DownloadDBLogFilePortion&Version=2014-10-31"
  let body = {
    let v = input.db_instance_identifier
    string.concat([
      body,
      string.concat(["&", "DBInstanceIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.log_file_name
    string.concat([
      body,
      string.concat(["&", "LogFileName", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.marker {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Marker", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.number_of_lines {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "NumberOfLines", "=", int.to_string(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_download_db_log_file_portion_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(DownloadDBLogFilePortionOutput, String) {
  Ok(DownloadDBLogFilePortionOutput)
}

pub type EnableHttpEndpointInput {
  EnableHttpEndpointInput(resource_arn: String)
}

pub fn enable_http_endpoint_input_default(
  resource_arn resource_arn: String,
) -> EnableHttpEndpointInput {
  EnableHttpEndpointInput(resource_arn: resource_arn)
}

pub type EnableHttpEndpointOutput {
  EnableHttpEndpointOutput
}

pub fn decode_enable_http_endpoint_input_struct() -> decode.Decoder(
  EnableHttpEndpointInput,
) {
  use <- decode.recursive
  use resource_arn <- decode.field("ResourceArn", decode.string)
  decode.success(EnableHttpEndpointInput(resource_arn: resource_arn))
}

pub fn decode_enable_http_endpoint_input(
  json_string: String,
) -> Result(EnableHttpEndpointInput, String) {
  result.map_error(
    json.parse(json_string, decode_enable_http_endpoint_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_enable_http_endpoint_request(
  input: EnableHttpEndpointInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=EnableHttpEndpoint&Version=2014-10-31"
  let body = {
    let v = input.resource_arn
    string.concat([
      body,
      string.concat(["&", "ResourceArn", "=", uri.encode_component(v)]),
    ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_enable_http_endpoint_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(EnableHttpEndpointOutput, String) {
  Ok(EnableHttpEndpointOutput)
}

pub type FailoverDBClusterInput {
  FailoverDBClusterInput(
    db_cluster_identifier: String,
    target_db_instance_identifier: option.Option(String),
  )
}

pub fn failover_db_cluster_input_default(
  db_cluster_identifier db_cluster_identifier: String,
) -> FailoverDBClusterInput {
  FailoverDBClusterInput(
    db_cluster_identifier: db_cluster_identifier,
    target_db_instance_identifier: option.None,
  )
}

pub type FailoverDBClusterOutput {
  FailoverDBClusterOutput
}

pub fn decode_failover_db_cluster_input_struct() -> decode.Decoder(
  FailoverDBClusterInput,
) {
  use <- decode.recursive
  use db_cluster_identifier <- decode.field(
    "DBClusterIdentifier",
    decode.string,
  )
  use target_db_instance_identifier <- decode.optional_field(
    "TargetDBInstanceIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(FailoverDBClusterInput(
    db_cluster_identifier: db_cluster_identifier,
    target_db_instance_identifier: target_db_instance_identifier,
  ))
}

pub fn decode_failover_db_cluster_input(
  json_string: String,
) -> Result(FailoverDBClusterInput, String) {
  result.map_error(
    json.parse(json_string, decode_failover_db_cluster_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_failover_db_cluster_request(
  input: FailoverDBClusterInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=FailoverDBCluster&Version=2014-10-31"
  let body = {
    let v = input.db_cluster_identifier
    string.concat([
      body,
      string.concat(["&", "DBClusterIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.target_db_instance_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "TargetDBInstanceIdentifier",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_failover_db_cluster_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(FailoverDBClusterOutput, String) {
  Ok(FailoverDBClusterOutput)
}

pub type FailoverGlobalClusterInput {
  FailoverGlobalClusterInput(
    global_cluster_identifier: String,
    target_db_cluster_identifier: String,
    allow_data_loss: option.Option(Bool),
    switchover: option.Option(Bool),
  )
}

pub fn failover_global_cluster_input_default(
  global_cluster_identifier global_cluster_identifier: String,
  target_db_cluster_identifier target_db_cluster_identifier: String,
) -> FailoverGlobalClusterInput {
  FailoverGlobalClusterInput(
    global_cluster_identifier: global_cluster_identifier,
    target_db_cluster_identifier: target_db_cluster_identifier,
    allow_data_loss: option.None,
    switchover: option.None,
  )
}

pub type FailoverGlobalClusterOutput {
  FailoverGlobalClusterOutput
}

pub fn decode_failover_global_cluster_input_struct() -> decode.Decoder(
  FailoverGlobalClusterInput,
) {
  use <- decode.recursive
  use global_cluster_identifier <- decode.field(
    "GlobalClusterIdentifier",
    decode.string,
  )
  use target_db_cluster_identifier <- decode.field(
    "TargetDbClusterIdentifier",
    decode.string,
  )
  use allow_data_loss <- decode.optional_field(
    "AllowDataLoss",
    option.None,
    decode.optional(decode.bool),
  )
  use switchover <- decode.optional_field(
    "Switchover",
    option.None,
    decode.optional(decode.bool),
  )
  decode.success(FailoverGlobalClusterInput(
    global_cluster_identifier: global_cluster_identifier,
    target_db_cluster_identifier: target_db_cluster_identifier,
    allow_data_loss: allow_data_loss,
    switchover: switchover,
  ))
}

pub fn decode_failover_global_cluster_input(
  json_string: String,
) -> Result(FailoverGlobalClusterInput, String) {
  result.map_error(
    json.parse(json_string, decode_failover_global_cluster_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_failover_global_cluster_request(
  input: FailoverGlobalClusterInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=FailoverGlobalCluster&Version=2014-10-31"
  let body = {
    let v = input.global_cluster_identifier
    string.concat([
      body,
      string.concat([
        "&",
        "GlobalClusterIdentifier",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body = {
    let v = input.target_db_cluster_identifier
    string.concat([
      body,
      string.concat([
        "&",
        "TargetDbClusterIdentifier",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body = case input.allow_data_loss {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "AllowDataLoss",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.switchover {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "Switchover",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_failover_global_cluster_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(FailoverGlobalClusterOutput, String) {
  Ok(FailoverGlobalClusterOutput)
}

pub type ListTagsForResourceInput {
  ListTagsForResourceInput(
    resource_name: String,
    filters: option.Option(List(Filter)),
  )
}

pub fn list_tags_for_resource_input_default(
  resource_name resource_name: String,
) -> ListTagsForResourceInput {
  ListTagsForResourceInput(resource_name: resource_name, filters: option.None)
}

pub type ListTagsForResourceOutput {
  ListTagsForResourceOutput
}

pub fn decode_list_tags_for_resource_input_struct() -> decode.Decoder(
  ListTagsForResourceInput,
) {
  use <- decode.recursive
  use resource_name <- decode.field("ResourceName", decode.string)
  use filters <- decode.optional_field(
    "Filters",
    option.None,
    decode.optional(decode.list(decode_filter_struct_params())),
  )
  decode.success(ListTagsForResourceInput(
    resource_name: resource_name,
    filters: filters,
  ))
}

pub fn decode_list_tags_for_resource_input(
  json_string: String,
) -> Result(ListTagsForResourceInput, String) {
  result.map_error(
    json.parse(json_string, decode_list_tags_for_resource_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_list_tags_for_resource_request(
  input: ListTagsForResourceInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=ListTagsForResource&Version=2014-10-31"
  let body = {
    let v = input.resource_name
    string.concat([
      body,
      string.concat(["&", "ResourceName", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.filters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Filters", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_filter_at(
                  string.concat(["Filters", ".Filter.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_list_tags_for_resource_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(ListTagsForResourceOutput, String) {
  Ok(ListTagsForResourceOutput)
}

pub type ModifyActivityStreamInput {
  ModifyActivityStreamInput(
    resource_arn: option.Option(String),
    audit_policy_state: option.Option(AuditPolicyState),
  )
}

pub fn modify_activity_stream_input_default() -> ModifyActivityStreamInput {
  ModifyActivityStreamInput(
    resource_arn: option.None,
    audit_policy_state: option.None,
  )
}

pub type ModifyActivityStreamOutput {
  ModifyActivityStreamOutput
}

pub fn decode_modify_activity_stream_input_struct() -> decode.Decoder(
  ModifyActivityStreamInput,
) {
  use <- decode.recursive
  use resource_arn <- decode.optional_field(
    "ResourceArn",
    option.None,
    decode.optional(decode.string),
  )
  use audit_policy_state <- decode.optional_field(
    "AuditPolicyState",
    option.None,
    decode.optional(decode_audit_policy_state_enum()),
  )
  decode.success(ModifyActivityStreamInput(
    resource_arn: resource_arn,
    audit_policy_state: audit_policy_state,
  ))
}

pub fn decode_modify_activity_stream_input(
  json_string: String,
) -> Result(ModifyActivityStreamInput, String) {
  result.map_error(
    json.parse(json_string, decode_modify_activity_stream_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_modify_activity_stream_request(
  input: ModifyActivityStreamInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=ModifyActivityStream&Version=2014-10-31"
  let body = case input.resource_arn {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "ResourceArn", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.audit_policy_state {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "AuditPolicyState",
          "=",
          uri.encode_component(audit_policy_state_to_wire(v)),
        ]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_modify_activity_stream_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(ModifyActivityStreamOutput, String) {
  Ok(ModifyActivityStreamOutput)
}

pub type ModifyCertificatesInput {
  ModifyCertificatesInput(
    certificate_identifier: option.Option(String),
    remove_customer_override: option.Option(Bool),
  )
}

pub fn modify_certificates_input_default() -> ModifyCertificatesInput {
  ModifyCertificatesInput(
    certificate_identifier: option.None,
    remove_customer_override: option.None,
  )
}

pub type ModifyCertificatesOutput {
  ModifyCertificatesOutput
}

pub fn decode_modify_certificates_input_struct() -> decode.Decoder(
  ModifyCertificatesInput,
) {
  use <- decode.recursive
  use certificate_identifier <- decode.optional_field(
    "CertificateIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use remove_customer_override <- decode.optional_field(
    "RemoveCustomerOverride",
    option.None,
    decode.optional(decode.bool),
  )
  decode.success(ModifyCertificatesInput(
    certificate_identifier: certificate_identifier,
    remove_customer_override: remove_customer_override,
  ))
}

pub fn decode_modify_certificates_input(
  json_string: String,
) -> Result(ModifyCertificatesInput, String) {
  result.map_error(
    json.parse(json_string, decode_modify_certificates_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_modify_certificates_request(
  input: ModifyCertificatesInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=ModifyCertificates&Version=2014-10-31"
  let body = case input.certificate_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "CertificateIdentifier",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.remove_customer_override {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "RemoveCustomerOverride",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_modify_certificates_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(ModifyCertificatesOutput, String) {
  Ok(ModifyCertificatesOutput)
}

pub type ModifyCurrentDBClusterCapacityInput {
  ModifyCurrentDBClusterCapacityInput(
    db_cluster_identifier: String,
    capacity: option.Option(Int),
    seconds_before_timeout: option.Option(Int),
    timeout_action: option.Option(String),
  )
}

pub fn modify_current_db_cluster_capacity_input_default(
  db_cluster_identifier db_cluster_identifier: String,
) -> ModifyCurrentDBClusterCapacityInput {
  ModifyCurrentDBClusterCapacityInput(
    db_cluster_identifier: db_cluster_identifier,
    capacity: option.None,
    seconds_before_timeout: option.None,
    timeout_action: option.None,
  )
}

pub type ModifyCurrentDBClusterCapacityOutput {
  ModifyCurrentDBClusterCapacityOutput
}

pub fn decode_modify_current_db_cluster_capacity_input_struct() -> decode.Decoder(
  ModifyCurrentDBClusterCapacityInput,
) {
  use <- decode.recursive
  use db_cluster_identifier <- decode.field(
    "DBClusterIdentifier",
    decode.string,
  )
  use capacity <- decode.optional_field(
    "Capacity",
    option.None,
    decode.optional(decode.int),
  )
  use seconds_before_timeout <- decode.optional_field(
    "SecondsBeforeTimeout",
    option.None,
    decode.optional(decode.int),
  )
  use timeout_action <- decode.optional_field(
    "TimeoutAction",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(ModifyCurrentDBClusterCapacityInput(
    db_cluster_identifier: db_cluster_identifier,
    capacity: capacity,
    seconds_before_timeout: seconds_before_timeout,
    timeout_action: timeout_action,
  ))
}

pub fn decode_modify_current_db_cluster_capacity_input(
  json_string: String,
) -> Result(ModifyCurrentDBClusterCapacityInput, String) {
  result.map_error(
    json.parse(
      json_string,
      decode_modify_current_db_cluster_capacity_input_struct(),
    ),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_modify_current_db_cluster_capacity_request(
  input: ModifyCurrentDBClusterCapacityInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=ModifyCurrentDBClusterCapacity&Version=2014-10-31"
  let body = {
    let v = input.db_cluster_identifier
    string.concat([
      body,
      string.concat(["&", "DBClusterIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.capacity {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Capacity", "=", int.to_string(v)]),
      ])
  }
  let body = case input.seconds_before_timeout {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "SecondsBeforeTimeout", "=", int.to_string(v)]),
      ])
  }
  let body = case input.timeout_action {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "TimeoutAction", "=", uri.encode_component(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_modify_current_db_cluster_capacity_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(ModifyCurrentDBClusterCapacityOutput, String) {
  Ok(ModifyCurrentDBClusterCapacityOutput)
}

pub type ModifyCustomDBEngineVersionInput {
  ModifyCustomDBEngineVersionInput(
    engine: String,
    engine_version: String,
    description: option.Option(String),
    status: option.Option(CustomEngineVersionStatus),
  )
}

pub fn modify_custom_db_engine_version_input_default(
  engine engine: String,
  engine_version engine_version: String,
) -> ModifyCustomDBEngineVersionInput {
  ModifyCustomDBEngineVersionInput(
    engine: engine,
    engine_version: engine_version,
    description: option.None,
    status: option.None,
  )
}

pub type ModifyCustomDBEngineVersionOutput {
  ModifyCustomDBEngineVersionOutput
}

pub fn decode_modify_custom_db_engine_version_input_struct() -> decode.Decoder(
  ModifyCustomDBEngineVersionInput,
) {
  use <- decode.recursive
  use engine <- decode.field("Engine", decode.string)
  use engine_version <- decode.field("EngineVersion", decode.string)
  use description <- decode.optional_field(
    "Description",
    option.None,
    decode.optional(decode.string),
  )
  use status <- decode.optional_field(
    "Status",
    option.None,
    decode.optional(decode_custom_engine_version_status_enum()),
  )
  decode.success(ModifyCustomDBEngineVersionInput(
    engine: engine,
    engine_version: engine_version,
    description: description,
    status: status,
  ))
}

pub fn decode_modify_custom_db_engine_version_input(
  json_string: String,
) -> Result(ModifyCustomDBEngineVersionInput, String) {
  result.map_error(
    json.parse(
      json_string,
      decode_modify_custom_db_engine_version_input_struct(),
    ),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_modify_custom_db_engine_version_request(
  input: ModifyCustomDBEngineVersionInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=ModifyCustomDBEngineVersion&Version=2014-10-31"
  let body = {
    let v = input.engine
    string.concat([
      body,
      string.concat(["&", "Engine", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.engine_version
    string.concat([
      body,
      string.concat(["&", "EngineVersion", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.description {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Description", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.status {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "Status",
          "=",
          uri.encode_component(custom_engine_version_status_to_wire(v)),
        ]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_modify_custom_db_engine_version_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(ModifyCustomDBEngineVersionOutput, String) {
  Ok(ModifyCustomDBEngineVersionOutput)
}

pub type ModifyDBClusterInput {
  ModifyDBClusterInput(
    db_cluster_identifier: String,
    new_db_cluster_identifier: option.Option(String),
    apply_immediately: option.Option(Bool),
    backup_retention_period: option.Option(Int),
    db_cluster_parameter_group_name: option.Option(String),
    vpc_security_group_ids: option.Option(List(String)),
    port: option.Option(Int),
    master_user_password: option.Option(String),
    option_group_name: option.Option(String),
    preferred_backup_window: option.Option(String),
    preferred_maintenance_window: option.Option(String),
    enable_iam_database_authentication: option.Option(Bool),
    backtrack_window: option.Option(Int),
    cloudwatch_logs_export_configuration: option.Option(
      CloudwatchLogsExportConfiguration,
    ),
    engine_version: option.Option(String),
    allow_major_version_upgrade: option.Option(Bool),
    db_instance_parameter_group_name: option.Option(String),
    domain: option.Option(String),
    domain_iam_role_name: option.Option(String),
    scaling_configuration: option.Option(ScalingConfiguration),
    deletion_protection: option.Option(Bool),
    enable_http_endpoint: option.Option(Bool),
    copy_tags_to_snapshot: option.Option(Bool),
    enable_global_write_forwarding: option.Option(Bool),
    db_cluster_instance_class: option.Option(String),
    allocated_storage: option.Option(Int),
    storage_type: option.Option(String),
    iops: option.Option(Int),
    auto_minor_version_upgrade: option.Option(Bool),
    network_type: option.Option(String),
    serverless_v2_scaling_configuration: option.Option(
      ServerlessV2ScalingConfiguration,
    ),
    monitoring_interval: option.Option(Int),
    monitoring_role_arn: option.Option(String),
    database_insights_mode: option.Option(DatabaseInsightsMode),
    enable_performance_insights: option.Option(Bool),
    performance_insights_kms_key_id: option.Option(String),
    performance_insights_retention_period: option.Option(Int),
    manage_master_user_password: option.Option(Bool),
    rotate_master_user_password: option.Option(Bool),
    enable_local_write_forwarding: option.Option(Bool),
    master_user_secret_kms_key_id: option.Option(String),
    engine_mode: option.Option(String),
    allow_engine_mode_change: option.Option(Bool),
    aws_backup_recovery_point_arn: option.Option(String),
    enable_limitless_database: option.Option(Bool),
    ca_certificate_identifier: option.Option(String),
    master_user_authentication_type: option.Option(MasterUserAuthenticationType),
  )
}

pub fn modify_db_cluster_input_default(
  db_cluster_identifier db_cluster_identifier: String,
) -> ModifyDBClusterInput {
  ModifyDBClusterInput(
    db_cluster_identifier: db_cluster_identifier,
    new_db_cluster_identifier: option.None,
    apply_immediately: option.None,
    backup_retention_period: option.None,
    db_cluster_parameter_group_name: option.None,
    vpc_security_group_ids: option.None,
    port: option.None,
    master_user_password: option.None,
    option_group_name: option.None,
    preferred_backup_window: option.None,
    preferred_maintenance_window: option.None,
    enable_iam_database_authentication: option.None,
    backtrack_window: option.None,
    cloudwatch_logs_export_configuration: option.None,
    engine_version: option.None,
    allow_major_version_upgrade: option.None,
    db_instance_parameter_group_name: option.None,
    domain: option.None,
    domain_iam_role_name: option.None,
    scaling_configuration: option.None,
    deletion_protection: option.None,
    enable_http_endpoint: option.None,
    copy_tags_to_snapshot: option.None,
    enable_global_write_forwarding: option.None,
    db_cluster_instance_class: option.None,
    allocated_storage: option.None,
    storage_type: option.None,
    iops: option.None,
    auto_minor_version_upgrade: option.None,
    network_type: option.None,
    serverless_v2_scaling_configuration: option.None,
    monitoring_interval: option.None,
    monitoring_role_arn: option.None,
    database_insights_mode: option.None,
    enable_performance_insights: option.None,
    performance_insights_kms_key_id: option.None,
    performance_insights_retention_period: option.None,
    manage_master_user_password: option.None,
    rotate_master_user_password: option.None,
    enable_local_write_forwarding: option.None,
    master_user_secret_kms_key_id: option.None,
    engine_mode: option.None,
    allow_engine_mode_change: option.None,
    aws_backup_recovery_point_arn: option.None,
    enable_limitless_database: option.None,
    ca_certificate_identifier: option.None,
    master_user_authentication_type: option.None,
  )
}

pub type ModifyDBClusterOutput {
  ModifyDBClusterOutput
}

pub fn decode_modify_db_cluster_input_struct() -> decode.Decoder(
  ModifyDBClusterInput,
) {
  use <- decode.recursive
  use db_cluster_identifier <- decode.field(
    "DBClusterIdentifier",
    decode.string,
  )
  use new_db_cluster_identifier <- decode.optional_field(
    "NewDBClusterIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use apply_immediately <- decode.optional_field(
    "ApplyImmediately",
    option.None,
    decode.optional(decode.bool),
  )
  use backup_retention_period <- decode.optional_field(
    "BackupRetentionPeriod",
    option.None,
    decode.optional(decode.int),
  )
  use db_cluster_parameter_group_name <- decode.optional_field(
    "DBClusterParameterGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use vpc_security_group_ids <- decode.optional_field(
    "VpcSecurityGroupIds",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use port <- decode.optional_field(
    "Port",
    option.None,
    decode.optional(decode.int),
  )
  use master_user_password <- decode.optional_field(
    "MasterUserPassword",
    option.None,
    decode.optional(decode.string),
  )
  use option_group_name <- decode.optional_field(
    "OptionGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use preferred_backup_window <- decode.optional_field(
    "PreferredBackupWindow",
    option.None,
    decode.optional(decode.string),
  )
  use preferred_maintenance_window <- decode.optional_field(
    "PreferredMaintenanceWindow",
    option.None,
    decode.optional(decode.string),
  )
  use enable_iam_database_authentication <- decode.optional_field(
    "EnableIAMDatabaseAuthentication",
    option.None,
    decode.optional(decode.bool),
  )
  use backtrack_window <- decode.optional_field(
    "BacktrackWindow",
    option.None,
    decode.optional(decode.int),
  )
  use cloudwatch_logs_export_configuration <- decode.optional_field(
    "CloudwatchLogsExportConfiguration",
    option.None,
    decode.optional(decode_cloudwatch_logs_export_configuration_struct_params()),
  )
  use engine_version <- decode.optional_field(
    "EngineVersion",
    option.None,
    decode.optional(decode.string),
  )
  use allow_major_version_upgrade <- decode.optional_field(
    "AllowMajorVersionUpgrade",
    option.None,
    decode.optional(decode.bool),
  )
  use db_instance_parameter_group_name <- decode.optional_field(
    "DBInstanceParameterGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use domain <- decode.optional_field(
    "Domain",
    option.None,
    decode.optional(decode.string),
  )
  use domain_iam_role_name <- decode.optional_field(
    "DomainIAMRoleName",
    option.None,
    decode.optional(decode.string),
  )
  use scaling_configuration <- decode.optional_field(
    "ScalingConfiguration",
    option.None,
    decode.optional(decode_scaling_configuration_struct_params()),
  )
  use deletion_protection <- decode.optional_field(
    "DeletionProtection",
    option.None,
    decode.optional(decode.bool),
  )
  use enable_http_endpoint <- decode.optional_field(
    "EnableHttpEndpoint",
    option.None,
    decode.optional(decode.bool),
  )
  use copy_tags_to_snapshot <- decode.optional_field(
    "CopyTagsToSnapshot",
    option.None,
    decode.optional(decode.bool),
  )
  use enable_global_write_forwarding <- decode.optional_field(
    "EnableGlobalWriteForwarding",
    option.None,
    decode.optional(decode.bool),
  )
  use db_cluster_instance_class <- decode.optional_field(
    "DBClusterInstanceClass",
    option.None,
    decode.optional(decode.string),
  )
  use allocated_storage <- decode.optional_field(
    "AllocatedStorage",
    option.None,
    decode.optional(decode.int),
  )
  use storage_type <- decode.optional_field(
    "StorageType",
    option.None,
    decode.optional(decode.string),
  )
  use iops <- decode.optional_field(
    "Iops",
    option.None,
    decode.optional(decode.int),
  )
  use auto_minor_version_upgrade <- decode.optional_field(
    "AutoMinorVersionUpgrade",
    option.None,
    decode.optional(decode.bool),
  )
  use network_type <- decode.optional_field(
    "NetworkType",
    option.None,
    decode.optional(decode.string),
  )
  use serverless_v2_scaling_configuration <- decode.optional_field(
    "ServerlessV2ScalingConfiguration",
    option.None,
    decode.optional(decode_serverless_v2_scaling_configuration_struct_params()),
  )
  use monitoring_interval <- decode.optional_field(
    "MonitoringInterval",
    option.None,
    decode.optional(decode.int),
  )
  use monitoring_role_arn <- decode.optional_field(
    "MonitoringRoleArn",
    option.None,
    decode.optional(decode.string),
  )
  use database_insights_mode <- decode.optional_field(
    "DatabaseInsightsMode",
    option.None,
    decode.optional(decode_database_insights_mode_enum()),
  )
  use enable_performance_insights <- decode.optional_field(
    "EnablePerformanceInsights",
    option.None,
    decode.optional(decode.bool),
  )
  use performance_insights_kms_key_id <- decode.optional_field(
    "PerformanceInsightsKMSKeyId",
    option.None,
    decode.optional(decode.string),
  )
  use performance_insights_retention_period <- decode.optional_field(
    "PerformanceInsightsRetentionPeriod",
    option.None,
    decode.optional(decode.int),
  )
  use manage_master_user_password <- decode.optional_field(
    "ManageMasterUserPassword",
    option.None,
    decode.optional(decode.bool),
  )
  use rotate_master_user_password <- decode.optional_field(
    "RotateMasterUserPassword",
    option.None,
    decode.optional(decode.bool),
  )
  use enable_local_write_forwarding <- decode.optional_field(
    "EnableLocalWriteForwarding",
    option.None,
    decode.optional(decode.bool),
  )
  use master_user_secret_kms_key_id <- decode.optional_field(
    "MasterUserSecretKmsKeyId",
    option.None,
    decode.optional(decode.string),
  )
  use engine_mode <- decode.optional_field(
    "EngineMode",
    option.None,
    decode.optional(decode.string),
  )
  use allow_engine_mode_change <- decode.optional_field(
    "AllowEngineModeChange",
    option.None,
    decode.optional(decode.bool),
  )
  use aws_backup_recovery_point_arn <- decode.optional_field(
    "AwsBackupRecoveryPointArn",
    option.None,
    decode.optional(decode.string),
  )
  use enable_limitless_database <- decode.optional_field(
    "EnableLimitlessDatabase",
    option.None,
    decode.optional(decode.bool),
  )
  use ca_certificate_identifier <- decode.optional_field(
    "CACertificateIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use master_user_authentication_type <- decode.optional_field(
    "MasterUserAuthenticationType",
    option.None,
    decode.optional(decode_master_user_authentication_type_enum()),
  )
  decode.success(ModifyDBClusterInput(
    db_cluster_identifier: db_cluster_identifier,
    new_db_cluster_identifier: new_db_cluster_identifier,
    apply_immediately: apply_immediately,
    backup_retention_period: backup_retention_period,
    db_cluster_parameter_group_name: db_cluster_parameter_group_name,
    vpc_security_group_ids: vpc_security_group_ids,
    port: port,
    master_user_password: master_user_password,
    option_group_name: option_group_name,
    preferred_backup_window: preferred_backup_window,
    preferred_maintenance_window: preferred_maintenance_window,
    enable_iam_database_authentication: enable_iam_database_authentication,
    backtrack_window: backtrack_window,
    cloudwatch_logs_export_configuration: cloudwatch_logs_export_configuration,
    engine_version: engine_version,
    allow_major_version_upgrade: allow_major_version_upgrade,
    db_instance_parameter_group_name: db_instance_parameter_group_name,
    domain: domain,
    domain_iam_role_name: domain_iam_role_name,
    scaling_configuration: scaling_configuration,
    deletion_protection: deletion_protection,
    enable_http_endpoint: enable_http_endpoint,
    copy_tags_to_snapshot: copy_tags_to_snapshot,
    enable_global_write_forwarding: enable_global_write_forwarding,
    db_cluster_instance_class: db_cluster_instance_class,
    allocated_storage: allocated_storage,
    storage_type: storage_type,
    iops: iops,
    auto_minor_version_upgrade: auto_minor_version_upgrade,
    network_type: network_type,
    serverless_v2_scaling_configuration: serverless_v2_scaling_configuration,
    monitoring_interval: monitoring_interval,
    monitoring_role_arn: monitoring_role_arn,
    database_insights_mode: database_insights_mode,
    enable_performance_insights: enable_performance_insights,
    performance_insights_kms_key_id: performance_insights_kms_key_id,
    performance_insights_retention_period: performance_insights_retention_period,
    manage_master_user_password: manage_master_user_password,
    rotate_master_user_password: rotate_master_user_password,
    enable_local_write_forwarding: enable_local_write_forwarding,
    master_user_secret_kms_key_id: master_user_secret_kms_key_id,
    engine_mode: engine_mode,
    allow_engine_mode_change: allow_engine_mode_change,
    aws_backup_recovery_point_arn: aws_backup_recovery_point_arn,
    enable_limitless_database: enable_limitless_database,
    ca_certificate_identifier: ca_certificate_identifier,
    master_user_authentication_type: master_user_authentication_type,
  ))
}

pub fn decode_modify_db_cluster_input(
  json_string: String,
) -> Result(ModifyDBClusterInput, String) {
  result.map_error(
    json.parse(json_string, decode_modify_db_cluster_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_modify_db_cluster_request(
  input: ModifyDBClusterInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=ModifyDBCluster&Version=2014-10-31"
  let body = {
    let v = input.db_cluster_identifier
    string.concat([
      body,
      string.concat(["&", "DBClusterIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.new_db_cluster_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "NewDBClusterIdentifier",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.apply_immediately {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "ApplyImmediately",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.backup_retention_period {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "BackupRetentionPeriod", "=", int.to_string(v)]),
      ])
  }
  let body = case input.db_cluster_parameter_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DBClusterParameterGroupName",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.vpc_security_group_ids {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "VpcSecurityGroupIds", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "VpcSecurityGroupIds",
                    ".VpcSecurityGroupId.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body = case input.port {
    option.None -> body
    option.Some(v) ->
      string.concat([body, string.concat(["&", "Port", "=", int.to_string(v)])])
  }
  let body = case input.master_user_password {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MasterUserPassword", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.option_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "OptionGroupName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.preferred_backup_window {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "PreferredBackupWindow",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.preferred_maintenance_window {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "PreferredMaintenanceWindow",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.enable_iam_database_authentication {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EnableIAMDatabaseAuthentication",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.backtrack_window {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "BacktrackWindow", "=", int.to_string(v)]),
      ])
  }
  let body = case input.cloudwatch_logs_export_configuration {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        encode_cloudwatch_logs_export_configuration_at(
          "CloudwatchLogsExportConfiguration",
          v,
        ),
      ])
  }
  let body = case input.engine_version {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "EngineVersion", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.allow_major_version_upgrade {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "AllowMajorVersionUpgrade",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.db_instance_parameter_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DBInstanceParameterGroupName",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.domain {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Domain", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.domain_iam_role_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DomainIAMRoleName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.scaling_configuration {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        encode_scaling_configuration_at("ScalingConfiguration", v),
      ])
  }
  let body = case input.deletion_protection {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DeletionProtection",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.enable_http_endpoint {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EnableHttpEndpoint",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.copy_tags_to_snapshot {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "CopyTagsToSnapshot",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.enable_global_write_forwarding {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EnableGlobalWriteForwarding",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.db_cluster_instance_class {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DBClusterInstanceClass",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.allocated_storage {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "AllocatedStorage", "=", int.to_string(v)]),
      ])
  }
  let body = case input.storage_type {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "StorageType", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.iops {
    option.None -> body
    option.Some(v) ->
      string.concat([body, string.concat(["&", "Iops", "=", int.to_string(v)])])
  }
  let body = case input.auto_minor_version_upgrade {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "AutoMinorVersionUpgrade",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.network_type {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "NetworkType", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.serverless_v2_scaling_configuration {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        encode_serverless_v2_scaling_configuration_at(
          "ServerlessV2ScalingConfiguration",
          v,
        ),
      ])
  }
  let body = case input.monitoring_interval {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MonitoringInterval", "=", int.to_string(v)]),
      ])
  }
  let body = case input.monitoring_role_arn {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MonitoringRoleArn", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.database_insights_mode {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DatabaseInsightsMode",
          "=",
          uri.encode_component(database_insights_mode_to_wire(v)),
        ]),
      ])
  }
  let body = case input.enable_performance_insights {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EnablePerformanceInsights",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.performance_insights_kms_key_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "PerformanceInsightsKMSKeyId",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.performance_insights_retention_period {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "PerformanceInsightsRetentionPeriod",
          "=",
          int.to_string(v),
        ]),
      ])
  }
  let body = case input.manage_master_user_password {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "ManageMasterUserPassword",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.rotate_master_user_password {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "RotateMasterUserPassword",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.enable_local_write_forwarding {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EnableLocalWriteForwarding",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.master_user_secret_kms_key_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "MasterUserSecretKmsKeyId",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.engine_mode {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "EngineMode", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.allow_engine_mode_change {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "AllowEngineModeChange",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.aws_backup_recovery_point_arn {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "AwsBackupRecoveryPointArn",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.enable_limitless_database {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EnableLimitlessDatabase",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.ca_certificate_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "CACertificateIdentifier",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.master_user_authentication_type {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "MasterUserAuthenticationType",
          "=",
          uri.encode_component(master_user_authentication_type_to_wire(v)),
        ]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_modify_db_cluster_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(ModifyDBClusterOutput, String) {
  Ok(ModifyDBClusterOutput)
}

pub type ModifyDBClusterEndpointInput {
  ModifyDBClusterEndpointInput(
    db_cluster_endpoint_identifier: String,
    endpoint_type: option.Option(String),
    static_members: option.Option(List(String)),
    excluded_members: option.Option(List(String)),
  )
}

pub fn modify_db_cluster_endpoint_input_default(
  db_cluster_endpoint_identifier db_cluster_endpoint_identifier: String,
) -> ModifyDBClusterEndpointInput {
  ModifyDBClusterEndpointInput(
    db_cluster_endpoint_identifier: db_cluster_endpoint_identifier,
    endpoint_type: option.None,
    static_members: option.None,
    excluded_members: option.None,
  )
}

pub type ModifyDBClusterEndpointOutput {
  ModifyDBClusterEndpointOutput
}

pub fn decode_modify_db_cluster_endpoint_input_struct() -> decode.Decoder(
  ModifyDBClusterEndpointInput,
) {
  use <- decode.recursive
  use db_cluster_endpoint_identifier <- decode.field(
    "DBClusterEndpointIdentifier",
    decode.string,
  )
  use endpoint_type <- decode.optional_field(
    "EndpointType",
    option.None,
    decode.optional(decode.string),
  )
  use static_members <- decode.optional_field(
    "StaticMembers",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use excluded_members <- decode.optional_field(
    "ExcludedMembers",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  decode.success(ModifyDBClusterEndpointInput(
    db_cluster_endpoint_identifier: db_cluster_endpoint_identifier,
    endpoint_type: endpoint_type,
    static_members: static_members,
    excluded_members: excluded_members,
  ))
}

pub fn decode_modify_db_cluster_endpoint_input(
  json_string: String,
) -> Result(ModifyDBClusterEndpointInput, String) {
  result.map_error(
    json.parse(json_string, decode_modify_db_cluster_endpoint_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_modify_db_cluster_endpoint_request(
  input: ModifyDBClusterEndpointInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=ModifyDBClusterEndpoint&Version=2014-10-31"
  let body = {
    let v = input.db_cluster_endpoint_identifier
    string.concat([
      body,
      string.concat([
        "&",
        "DBClusterEndpointIdentifier",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body = case input.endpoint_type {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "EndpointType", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.static_members {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "StaticMembers", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "StaticMembers",
                    ".member.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body = case input.excluded_members {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "ExcludedMembers", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "ExcludedMembers",
                    ".member.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_modify_db_cluster_endpoint_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(ModifyDBClusterEndpointOutput, String) {
  Ok(ModifyDBClusterEndpointOutput)
}

pub type ModifyDBClusterParameterGroupInput {
  ModifyDBClusterParameterGroupInput(
    db_cluster_parameter_group_name: String,
    parameters: List(Parameter),
  )
}

pub fn modify_db_cluster_parameter_group_input_default(
  db_cluster_parameter_group_name db_cluster_parameter_group_name: String,
  parameters parameters: List(Parameter),
) -> ModifyDBClusterParameterGroupInput {
  ModifyDBClusterParameterGroupInput(
    db_cluster_parameter_group_name: db_cluster_parameter_group_name,
    parameters: parameters,
  )
}

pub type ModifyDBClusterParameterGroupOutput {
  ModifyDBClusterParameterGroupOutput
}

pub fn decode_modify_db_cluster_parameter_group_input_struct() -> decode.Decoder(
  ModifyDBClusterParameterGroupInput,
) {
  use <- decode.recursive
  use db_cluster_parameter_group_name <- decode.field(
    "DBClusterParameterGroupName",
    decode.string,
  )
  use parameters <- decode.field(
    "Parameters",
    decode.list(decode_parameter_struct_params()),
  )
  decode.success(ModifyDBClusterParameterGroupInput(
    db_cluster_parameter_group_name: db_cluster_parameter_group_name,
    parameters: parameters,
  ))
}

pub fn decode_modify_db_cluster_parameter_group_input(
  json_string: String,
) -> Result(ModifyDBClusterParameterGroupInput, String) {
  result.map_error(
    json.parse(
      json_string,
      decode_modify_db_cluster_parameter_group_input_struct(),
    ),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_modify_db_cluster_parameter_group_request(
  input: ModifyDBClusterParameterGroupInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=ModifyDBClusterParameterGroup&Version=2014-10-31"
  let body = {
    let v = input.db_cluster_parameter_group_name
    string.concat([
      body,
      string.concat([
        "&",
        "DBClusterParameterGroupName",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body = {
    let v = input.parameters
    string.concat([
      body,
      case v {
        [] -> string.concat(["&", "Parameters", "=", ""])
        _ ->
          list.index_fold(v, "", fn(acc, item, idx) {
            string.concat([
              acc,
              encode_parameter_at(
                string.concat([
                  "Parameters",
                  ".Parameter.",
                  int.to_string(idx + 1),
                ]),
                item,
              ),
            ])
          })
      },
    ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_modify_db_cluster_parameter_group_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(ModifyDBClusterParameterGroupOutput, String) {
  Ok(ModifyDBClusterParameterGroupOutput)
}

pub type ModifyDBClusterSnapshotAttributeInput {
  ModifyDBClusterSnapshotAttributeInput(
    db_cluster_snapshot_identifier: String,
    attribute_name: String,
    values_to_add: option.Option(List(String)),
    values_to_remove: option.Option(List(String)),
  )
}

pub fn modify_db_cluster_snapshot_attribute_input_default(
  db_cluster_snapshot_identifier db_cluster_snapshot_identifier: String,
  attribute_name attribute_name: String,
) -> ModifyDBClusterSnapshotAttributeInput {
  ModifyDBClusterSnapshotAttributeInput(
    db_cluster_snapshot_identifier: db_cluster_snapshot_identifier,
    attribute_name: attribute_name,
    values_to_add: option.None,
    values_to_remove: option.None,
  )
}

pub type ModifyDBClusterSnapshotAttributeOutput {
  ModifyDBClusterSnapshotAttributeOutput
}

pub fn decode_modify_db_cluster_snapshot_attribute_input_struct() -> decode.Decoder(
  ModifyDBClusterSnapshotAttributeInput,
) {
  use <- decode.recursive
  use db_cluster_snapshot_identifier <- decode.field(
    "DBClusterSnapshotIdentifier",
    decode.string,
  )
  use attribute_name <- decode.field("AttributeName", decode.string)
  use values_to_add <- decode.optional_field(
    "ValuesToAdd",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use values_to_remove <- decode.optional_field(
    "ValuesToRemove",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  decode.success(ModifyDBClusterSnapshotAttributeInput(
    db_cluster_snapshot_identifier: db_cluster_snapshot_identifier,
    attribute_name: attribute_name,
    values_to_add: values_to_add,
    values_to_remove: values_to_remove,
  ))
}

pub fn decode_modify_db_cluster_snapshot_attribute_input(
  json_string: String,
) -> Result(ModifyDBClusterSnapshotAttributeInput, String) {
  result.map_error(
    json.parse(
      json_string,
      decode_modify_db_cluster_snapshot_attribute_input_struct(),
    ),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_modify_db_cluster_snapshot_attribute_request(
  input: ModifyDBClusterSnapshotAttributeInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=ModifyDBClusterSnapshotAttribute&Version=2014-10-31"
  let body = {
    let v = input.db_cluster_snapshot_identifier
    string.concat([
      body,
      string.concat([
        "&",
        "DBClusterSnapshotIdentifier",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body = {
    let v = input.attribute_name
    string.concat([
      body,
      string.concat(["&", "AttributeName", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.values_to_add {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "ValuesToAdd", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "ValuesToAdd",
                    ".AttributeValue.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body = case input.values_to_remove {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "ValuesToRemove", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "ValuesToRemove",
                    ".AttributeValue.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_modify_db_cluster_snapshot_attribute_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(ModifyDBClusterSnapshotAttributeOutput, String) {
  Ok(ModifyDBClusterSnapshotAttributeOutput)
}

pub type ModifyDBInstanceInput {
  ModifyDBInstanceInput(
    db_instance_identifier: String,
    allocated_storage: option.Option(Int),
    db_instance_class: option.Option(String),
    db_subnet_group_name: option.Option(String),
    db_security_groups: option.Option(List(String)),
    vpc_security_group_ids: option.Option(List(String)),
    apply_immediately: option.Option(Bool),
    master_user_password: option.Option(String),
    db_parameter_group_name: option.Option(String),
    backup_retention_period: option.Option(Int),
    preferred_backup_window: option.Option(String),
    preferred_maintenance_window: option.Option(String),
    multi_az: option.Option(Bool),
    engine_version: option.Option(String),
    allow_major_version_upgrade: option.Option(Bool),
    auto_minor_version_upgrade: option.Option(Bool),
    license_model: option.Option(String),
    iops: option.Option(Int),
    storage_throughput: option.Option(Int),
    option_group_name: option.Option(String),
    new_db_instance_identifier: option.Option(String),
    storage_type: option.Option(String),
    tde_credential_arn: option.Option(String),
    tde_credential_password: option.Option(String),
    ca_certificate_identifier: option.Option(String),
    domain: option.Option(String),
    domain_fqdn: option.Option(String),
    domain_ou: option.Option(String),
    domain_auth_secret_arn: option.Option(String),
    domain_dns_ips: option.Option(List(String)),
    disable_domain: option.Option(Bool),
    copy_tags_to_snapshot: option.Option(Bool),
    monitoring_interval: option.Option(Int),
    db_port_number: option.Option(Int),
    publicly_accessible: option.Option(Bool),
    monitoring_role_arn: option.Option(String),
    domain_iam_role_name: option.Option(String),
    promotion_tier: option.Option(Int),
    enable_iam_database_authentication: option.Option(Bool),
    database_insights_mode: option.Option(DatabaseInsightsMode),
    enable_performance_insights: option.Option(Bool),
    performance_insights_kms_key_id: option.Option(String),
    performance_insights_retention_period: option.Option(Int),
    cloudwatch_logs_export_configuration: option.Option(
      CloudwatchLogsExportConfiguration,
    ),
    processor_features: option.Option(List(ProcessorFeature)),
    use_default_processor_features: option.Option(Bool),
    deletion_protection: option.Option(Bool),
    max_allocated_storage: option.Option(Int),
    certificate_rotation_restart: option.Option(Bool),
    replica_mode: option.Option(ReplicaMode),
    automation_mode: option.Option(AutomationMode),
    resume_full_automation_mode_minutes: option.Option(Int),
    enable_customer_owned_ip: option.Option(Bool),
    network_type: option.Option(String),
    aws_backup_recovery_point_arn: option.Option(String),
    manage_master_user_password: option.Option(Bool),
    rotate_master_user_password: option.Option(Bool),
    master_user_secret_kms_key_id: option.Option(String),
    multi_tenant: option.Option(Bool),
    dedicated_log_volume: option.Option(Bool),
    engine: option.Option(String),
    additional_storage_volumes: option.Option(
      List(ModifyAdditionalStorageVolume),
    ),
    tag_specifications: option.Option(List(TagSpecification)),
    master_user_authentication_type: option.Option(MasterUserAuthenticationType),
  )
}

pub fn modify_db_instance_input_default(
  db_instance_identifier db_instance_identifier: String,
) -> ModifyDBInstanceInput {
  ModifyDBInstanceInput(
    db_instance_identifier: db_instance_identifier,
    allocated_storage: option.None,
    db_instance_class: option.None,
    db_subnet_group_name: option.None,
    db_security_groups: option.None,
    vpc_security_group_ids: option.None,
    apply_immediately: option.None,
    master_user_password: option.None,
    db_parameter_group_name: option.None,
    backup_retention_period: option.None,
    preferred_backup_window: option.None,
    preferred_maintenance_window: option.None,
    multi_az: option.None,
    engine_version: option.None,
    allow_major_version_upgrade: option.None,
    auto_minor_version_upgrade: option.None,
    license_model: option.None,
    iops: option.None,
    storage_throughput: option.None,
    option_group_name: option.None,
    new_db_instance_identifier: option.None,
    storage_type: option.None,
    tde_credential_arn: option.None,
    tde_credential_password: option.None,
    ca_certificate_identifier: option.None,
    domain: option.None,
    domain_fqdn: option.None,
    domain_ou: option.None,
    domain_auth_secret_arn: option.None,
    domain_dns_ips: option.None,
    disable_domain: option.None,
    copy_tags_to_snapshot: option.None,
    monitoring_interval: option.None,
    db_port_number: option.None,
    publicly_accessible: option.None,
    monitoring_role_arn: option.None,
    domain_iam_role_name: option.None,
    promotion_tier: option.None,
    enable_iam_database_authentication: option.None,
    database_insights_mode: option.None,
    enable_performance_insights: option.None,
    performance_insights_kms_key_id: option.None,
    performance_insights_retention_period: option.None,
    cloudwatch_logs_export_configuration: option.None,
    processor_features: option.None,
    use_default_processor_features: option.None,
    deletion_protection: option.None,
    max_allocated_storage: option.None,
    certificate_rotation_restart: option.None,
    replica_mode: option.None,
    automation_mode: option.None,
    resume_full_automation_mode_minutes: option.None,
    enable_customer_owned_ip: option.None,
    network_type: option.None,
    aws_backup_recovery_point_arn: option.None,
    manage_master_user_password: option.None,
    rotate_master_user_password: option.None,
    master_user_secret_kms_key_id: option.None,
    multi_tenant: option.None,
    dedicated_log_volume: option.None,
    engine: option.None,
    additional_storage_volumes: option.None,
    tag_specifications: option.None,
    master_user_authentication_type: option.None,
  )
}

pub type ModifyDBInstanceOutput {
  ModifyDBInstanceOutput
}

pub fn decode_modify_db_instance_input_struct() -> decode.Decoder(
  ModifyDBInstanceInput,
) {
  use <- decode.recursive
  use db_instance_identifier <- decode.field(
    "DBInstanceIdentifier",
    decode.string,
  )
  use allocated_storage <- decode.optional_field(
    "AllocatedStorage",
    option.None,
    decode.optional(decode.int),
  )
  use db_instance_class <- decode.optional_field(
    "DBInstanceClass",
    option.None,
    decode.optional(decode.string),
  )
  use db_subnet_group_name <- decode.optional_field(
    "DBSubnetGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use db_security_groups <- decode.optional_field(
    "DBSecurityGroups",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use vpc_security_group_ids <- decode.optional_field(
    "VpcSecurityGroupIds",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use apply_immediately <- decode.optional_field(
    "ApplyImmediately",
    option.None,
    decode.optional(decode.bool),
  )
  use master_user_password <- decode.optional_field(
    "MasterUserPassword",
    option.None,
    decode.optional(decode.string),
  )
  use db_parameter_group_name <- decode.optional_field(
    "DBParameterGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use backup_retention_period <- decode.optional_field(
    "BackupRetentionPeriod",
    option.None,
    decode.optional(decode.int),
  )
  use preferred_backup_window <- decode.optional_field(
    "PreferredBackupWindow",
    option.None,
    decode.optional(decode.string),
  )
  use preferred_maintenance_window <- decode.optional_field(
    "PreferredMaintenanceWindow",
    option.None,
    decode.optional(decode.string),
  )
  use multi_az <- decode.optional_field(
    "MultiAZ",
    option.None,
    decode.optional(decode.bool),
  )
  use engine_version <- decode.optional_field(
    "EngineVersion",
    option.None,
    decode.optional(decode.string),
  )
  use allow_major_version_upgrade <- decode.optional_field(
    "AllowMajorVersionUpgrade",
    option.None,
    decode.optional(decode.bool),
  )
  use auto_minor_version_upgrade <- decode.optional_field(
    "AutoMinorVersionUpgrade",
    option.None,
    decode.optional(decode.bool),
  )
  use license_model <- decode.optional_field(
    "LicenseModel",
    option.None,
    decode.optional(decode.string),
  )
  use iops <- decode.optional_field(
    "Iops",
    option.None,
    decode.optional(decode.int),
  )
  use storage_throughput <- decode.optional_field(
    "StorageThroughput",
    option.None,
    decode.optional(decode.int),
  )
  use option_group_name <- decode.optional_field(
    "OptionGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use new_db_instance_identifier <- decode.optional_field(
    "NewDBInstanceIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use storage_type <- decode.optional_field(
    "StorageType",
    option.None,
    decode.optional(decode.string),
  )
  use tde_credential_arn <- decode.optional_field(
    "TdeCredentialArn",
    option.None,
    decode.optional(decode.string),
  )
  use tde_credential_password <- decode.optional_field(
    "TdeCredentialPassword",
    option.None,
    decode.optional(decode.string),
  )
  use ca_certificate_identifier <- decode.optional_field(
    "CACertificateIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use domain <- decode.optional_field(
    "Domain",
    option.None,
    decode.optional(decode.string),
  )
  use domain_fqdn <- decode.optional_field(
    "DomainFqdn",
    option.None,
    decode.optional(decode.string),
  )
  use domain_ou <- decode.optional_field(
    "DomainOu",
    option.None,
    decode.optional(decode.string),
  )
  use domain_auth_secret_arn <- decode.optional_field(
    "DomainAuthSecretArn",
    option.None,
    decode.optional(decode.string),
  )
  use domain_dns_ips <- decode.optional_field(
    "DomainDnsIps",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use disable_domain <- decode.optional_field(
    "DisableDomain",
    option.None,
    decode.optional(decode.bool),
  )
  use copy_tags_to_snapshot <- decode.optional_field(
    "CopyTagsToSnapshot",
    option.None,
    decode.optional(decode.bool),
  )
  use monitoring_interval <- decode.optional_field(
    "MonitoringInterval",
    option.None,
    decode.optional(decode.int),
  )
  use db_port_number <- decode.optional_field(
    "DBPortNumber",
    option.None,
    decode.optional(decode.int),
  )
  use publicly_accessible <- decode.optional_field(
    "PubliclyAccessible",
    option.None,
    decode.optional(decode.bool),
  )
  use monitoring_role_arn <- decode.optional_field(
    "MonitoringRoleArn",
    option.None,
    decode.optional(decode.string),
  )
  use domain_iam_role_name <- decode.optional_field(
    "DomainIAMRoleName",
    option.None,
    decode.optional(decode.string),
  )
  use promotion_tier <- decode.optional_field(
    "PromotionTier",
    option.None,
    decode.optional(decode.int),
  )
  use enable_iam_database_authentication <- decode.optional_field(
    "EnableIAMDatabaseAuthentication",
    option.None,
    decode.optional(decode.bool),
  )
  use database_insights_mode <- decode.optional_field(
    "DatabaseInsightsMode",
    option.None,
    decode.optional(decode_database_insights_mode_enum()),
  )
  use enable_performance_insights <- decode.optional_field(
    "EnablePerformanceInsights",
    option.None,
    decode.optional(decode.bool),
  )
  use performance_insights_kms_key_id <- decode.optional_field(
    "PerformanceInsightsKMSKeyId",
    option.None,
    decode.optional(decode.string),
  )
  use performance_insights_retention_period <- decode.optional_field(
    "PerformanceInsightsRetentionPeriod",
    option.None,
    decode.optional(decode.int),
  )
  use cloudwatch_logs_export_configuration <- decode.optional_field(
    "CloudwatchLogsExportConfiguration",
    option.None,
    decode.optional(decode_cloudwatch_logs_export_configuration_struct_params()),
  )
  use processor_features <- decode.optional_field(
    "ProcessorFeatures",
    option.None,
    decode.optional(decode.list(decode_processor_feature_struct_params())),
  )
  use use_default_processor_features <- decode.optional_field(
    "UseDefaultProcessorFeatures",
    option.None,
    decode.optional(decode.bool),
  )
  use deletion_protection <- decode.optional_field(
    "DeletionProtection",
    option.None,
    decode.optional(decode.bool),
  )
  use max_allocated_storage <- decode.optional_field(
    "MaxAllocatedStorage",
    option.None,
    decode.optional(decode.int),
  )
  use certificate_rotation_restart <- decode.optional_field(
    "CertificateRotationRestart",
    option.None,
    decode.optional(decode.bool),
  )
  use replica_mode <- decode.optional_field(
    "ReplicaMode",
    option.None,
    decode.optional(decode_replica_mode_enum()),
  )
  use automation_mode <- decode.optional_field(
    "AutomationMode",
    option.None,
    decode.optional(decode_automation_mode_enum()),
  )
  use resume_full_automation_mode_minutes <- decode.optional_field(
    "ResumeFullAutomationModeMinutes",
    option.None,
    decode.optional(decode.int),
  )
  use enable_customer_owned_ip <- decode.optional_field(
    "EnableCustomerOwnedIp",
    option.None,
    decode.optional(decode.bool),
  )
  use network_type <- decode.optional_field(
    "NetworkType",
    option.None,
    decode.optional(decode.string),
  )
  use aws_backup_recovery_point_arn <- decode.optional_field(
    "AwsBackupRecoveryPointArn",
    option.None,
    decode.optional(decode.string),
  )
  use manage_master_user_password <- decode.optional_field(
    "ManageMasterUserPassword",
    option.None,
    decode.optional(decode.bool),
  )
  use rotate_master_user_password <- decode.optional_field(
    "RotateMasterUserPassword",
    option.None,
    decode.optional(decode.bool),
  )
  use master_user_secret_kms_key_id <- decode.optional_field(
    "MasterUserSecretKmsKeyId",
    option.None,
    decode.optional(decode.string),
  )
  use multi_tenant <- decode.optional_field(
    "MultiTenant",
    option.None,
    decode.optional(decode.bool),
  )
  use dedicated_log_volume <- decode.optional_field(
    "DedicatedLogVolume",
    option.None,
    decode.optional(decode.bool),
  )
  use engine <- decode.optional_field(
    "Engine",
    option.None,
    decode.optional(decode.string),
  )
  use additional_storage_volumes <- decode.optional_field(
    "AdditionalStorageVolumes",
    option.None,
    decode.optional(
      decode.list(decode_modify_additional_storage_volume_struct_params()),
    ),
  )
  use tag_specifications <- decode.optional_field(
    "TagSpecifications",
    option.None,
    decode.optional(decode.list(decode_tag_specification_struct_params())),
  )
  use master_user_authentication_type <- decode.optional_field(
    "MasterUserAuthenticationType",
    option.None,
    decode.optional(decode_master_user_authentication_type_enum()),
  )
  decode.success(ModifyDBInstanceInput(
    db_instance_identifier: db_instance_identifier,
    allocated_storage: allocated_storage,
    db_instance_class: db_instance_class,
    db_subnet_group_name: db_subnet_group_name,
    db_security_groups: db_security_groups,
    vpc_security_group_ids: vpc_security_group_ids,
    apply_immediately: apply_immediately,
    master_user_password: master_user_password,
    db_parameter_group_name: db_parameter_group_name,
    backup_retention_period: backup_retention_period,
    preferred_backup_window: preferred_backup_window,
    preferred_maintenance_window: preferred_maintenance_window,
    multi_az: multi_az,
    engine_version: engine_version,
    allow_major_version_upgrade: allow_major_version_upgrade,
    auto_minor_version_upgrade: auto_minor_version_upgrade,
    license_model: license_model,
    iops: iops,
    storage_throughput: storage_throughput,
    option_group_name: option_group_name,
    new_db_instance_identifier: new_db_instance_identifier,
    storage_type: storage_type,
    tde_credential_arn: tde_credential_arn,
    tde_credential_password: tde_credential_password,
    ca_certificate_identifier: ca_certificate_identifier,
    domain: domain,
    domain_fqdn: domain_fqdn,
    domain_ou: domain_ou,
    domain_auth_secret_arn: domain_auth_secret_arn,
    domain_dns_ips: domain_dns_ips,
    disable_domain: disable_domain,
    copy_tags_to_snapshot: copy_tags_to_snapshot,
    monitoring_interval: monitoring_interval,
    db_port_number: db_port_number,
    publicly_accessible: publicly_accessible,
    monitoring_role_arn: monitoring_role_arn,
    domain_iam_role_name: domain_iam_role_name,
    promotion_tier: promotion_tier,
    enable_iam_database_authentication: enable_iam_database_authentication,
    database_insights_mode: database_insights_mode,
    enable_performance_insights: enable_performance_insights,
    performance_insights_kms_key_id: performance_insights_kms_key_id,
    performance_insights_retention_period: performance_insights_retention_period,
    cloudwatch_logs_export_configuration: cloudwatch_logs_export_configuration,
    processor_features: processor_features,
    use_default_processor_features: use_default_processor_features,
    deletion_protection: deletion_protection,
    max_allocated_storage: max_allocated_storage,
    certificate_rotation_restart: certificate_rotation_restart,
    replica_mode: replica_mode,
    automation_mode: automation_mode,
    resume_full_automation_mode_minutes: resume_full_automation_mode_minutes,
    enable_customer_owned_ip: enable_customer_owned_ip,
    network_type: network_type,
    aws_backup_recovery_point_arn: aws_backup_recovery_point_arn,
    manage_master_user_password: manage_master_user_password,
    rotate_master_user_password: rotate_master_user_password,
    master_user_secret_kms_key_id: master_user_secret_kms_key_id,
    multi_tenant: multi_tenant,
    dedicated_log_volume: dedicated_log_volume,
    engine: engine,
    additional_storage_volumes: additional_storage_volumes,
    tag_specifications: tag_specifications,
    master_user_authentication_type: master_user_authentication_type,
  ))
}

pub fn decode_modify_db_instance_input(
  json_string: String,
) -> Result(ModifyDBInstanceInput, String) {
  result.map_error(
    json.parse(json_string, decode_modify_db_instance_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_modify_db_instance_request(
  input: ModifyDBInstanceInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=ModifyDBInstance&Version=2014-10-31"
  let body = {
    let v = input.db_instance_identifier
    string.concat([
      body,
      string.concat(["&", "DBInstanceIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.allocated_storage {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "AllocatedStorage", "=", int.to_string(v)]),
      ])
  }
  let body = case input.db_instance_class {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DBInstanceClass", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.db_subnet_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DBSubnetGroupName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.db_security_groups {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "DBSecurityGroups", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "DBSecurityGroups",
                    ".DBSecurityGroupName.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body = case input.vpc_security_group_ids {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "VpcSecurityGroupIds", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "VpcSecurityGroupIds",
                    ".VpcSecurityGroupId.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body = case input.apply_immediately {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "ApplyImmediately",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.master_user_password {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MasterUserPassword", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.db_parameter_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DBParameterGroupName",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.backup_retention_period {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "BackupRetentionPeriod", "=", int.to_string(v)]),
      ])
  }
  let body = case input.preferred_backup_window {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "PreferredBackupWindow",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.preferred_maintenance_window {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "PreferredMaintenanceWindow",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.multi_az {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "MultiAZ",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.engine_version {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "EngineVersion", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.allow_major_version_upgrade {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "AllowMajorVersionUpgrade",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.auto_minor_version_upgrade {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "AutoMinorVersionUpgrade",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.license_model {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "LicenseModel", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.iops {
    option.None -> body
    option.Some(v) ->
      string.concat([body, string.concat(["&", "Iops", "=", int.to_string(v)])])
  }
  let body = case input.storage_throughput {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "StorageThroughput", "=", int.to_string(v)]),
      ])
  }
  let body = case input.option_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "OptionGroupName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.new_db_instance_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "NewDBInstanceIdentifier",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.storage_type {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "StorageType", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.tde_credential_arn {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "TdeCredentialArn", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.tde_credential_password {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "TdeCredentialPassword",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.ca_certificate_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "CACertificateIdentifier",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.domain {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Domain", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.domain_fqdn {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DomainFqdn", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.domain_ou {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DomainOu", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.domain_auth_secret_arn {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DomainAuthSecretArn", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.domain_dns_ips {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "DomainDnsIps", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "DomainDnsIps",
                    ".member.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body = case input.disable_domain {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DisableDomain",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.copy_tags_to_snapshot {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "CopyTagsToSnapshot",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.monitoring_interval {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MonitoringInterval", "=", int.to_string(v)]),
      ])
  }
  let body = case input.db_port_number {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DBPortNumber", "=", int.to_string(v)]),
      ])
  }
  let body = case input.publicly_accessible {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "PubliclyAccessible",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.monitoring_role_arn {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MonitoringRoleArn", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.domain_iam_role_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DomainIAMRoleName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.promotion_tier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "PromotionTier", "=", int.to_string(v)]),
      ])
  }
  let body = case input.enable_iam_database_authentication {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EnableIAMDatabaseAuthentication",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.database_insights_mode {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DatabaseInsightsMode",
          "=",
          uri.encode_component(database_insights_mode_to_wire(v)),
        ]),
      ])
  }
  let body = case input.enable_performance_insights {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EnablePerformanceInsights",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.performance_insights_kms_key_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "PerformanceInsightsKMSKeyId",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.performance_insights_retention_period {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "PerformanceInsightsRetentionPeriod",
          "=",
          int.to_string(v),
        ]),
      ])
  }
  let body = case input.cloudwatch_logs_export_configuration {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        encode_cloudwatch_logs_export_configuration_at(
          "CloudwatchLogsExportConfiguration",
          v,
        ),
      ])
  }
  let body = case input.processor_features {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "ProcessorFeatures", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_processor_feature_at(
                  string.concat([
                    "ProcessorFeatures",
                    ".ProcessorFeature.",
                    int.to_string(idx + 1),
                  ]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.use_default_processor_features {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "UseDefaultProcessorFeatures",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.deletion_protection {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DeletionProtection",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.max_allocated_storage {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxAllocatedStorage", "=", int.to_string(v)]),
      ])
  }
  let body = case input.certificate_rotation_restart {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "CertificateRotationRestart",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.replica_mode {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "ReplicaMode",
          "=",
          uri.encode_component(replica_mode_to_wire(v)),
        ]),
      ])
  }
  let body = case input.automation_mode {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "AutomationMode",
          "=",
          uri.encode_component(automation_mode_to_wire(v)),
        ]),
      ])
  }
  let body = case input.resume_full_automation_mode_minutes {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "ResumeFullAutomationModeMinutes",
          "=",
          int.to_string(v),
        ]),
      ])
  }
  let body = case input.enable_customer_owned_ip {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EnableCustomerOwnedIp",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.network_type {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "NetworkType", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.aws_backup_recovery_point_arn {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "AwsBackupRecoveryPointArn",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.manage_master_user_password {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "ManageMasterUserPassword",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.rotate_master_user_password {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "RotateMasterUserPassword",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.master_user_secret_kms_key_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "MasterUserSecretKmsKeyId",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.multi_tenant {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "MultiTenant",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.dedicated_log_volume {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DedicatedLogVolume",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.engine {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Engine", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.additional_storage_volumes {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "AdditionalStorageVolumes", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_modify_additional_storage_volume_at(
                  string.concat([
                    "AdditionalStorageVolumes",
                    ".member.",
                    int.to_string(idx + 1),
                  ]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.tag_specifications {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "TagSpecifications", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_tag_specification_at(
                  string.concat([
                    "TagSpecifications",
                    ".item.",
                    int.to_string(idx + 1),
                  ]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.master_user_authentication_type {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "MasterUserAuthenticationType",
          "=",
          uri.encode_component(master_user_authentication_type_to_wire(v)),
        ]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_modify_db_instance_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(ModifyDBInstanceOutput, String) {
  Ok(ModifyDBInstanceOutput)
}

pub type ModifyDBParameterGroupInput {
  ModifyDBParameterGroupInput(
    db_parameter_group_name: String,
    parameters: List(Parameter),
  )
}

pub fn modify_db_parameter_group_input_default(
  db_parameter_group_name db_parameter_group_name: String,
  parameters parameters: List(Parameter),
) -> ModifyDBParameterGroupInput {
  ModifyDBParameterGroupInput(
    db_parameter_group_name: db_parameter_group_name,
    parameters: parameters,
  )
}

pub type ModifyDBParameterGroupOutput {
  ModifyDBParameterGroupOutput
}

pub fn decode_modify_db_parameter_group_input_struct() -> decode.Decoder(
  ModifyDBParameterGroupInput,
) {
  use <- decode.recursive
  use db_parameter_group_name <- decode.field(
    "DBParameterGroupName",
    decode.string,
  )
  use parameters <- decode.field(
    "Parameters",
    decode.list(decode_parameter_struct_params()),
  )
  decode.success(ModifyDBParameterGroupInput(
    db_parameter_group_name: db_parameter_group_name,
    parameters: parameters,
  ))
}

pub fn decode_modify_db_parameter_group_input(
  json_string: String,
) -> Result(ModifyDBParameterGroupInput, String) {
  result.map_error(
    json.parse(json_string, decode_modify_db_parameter_group_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_modify_db_parameter_group_request(
  input: ModifyDBParameterGroupInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=ModifyDBParameterGroup&Version=2014-10-31"
  let body = {
    let v = input.db_parameter_group_name
    string.concat([
      body,
      string.concat(["&", "DBParameterGroupName", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.parameters
    string.concat([
      body,
      case v {
        [] -> string.concat(["&", "Parameters", "=", ""])
        _ ->
          list.index_fold(v, "", fn(acc, item, idx) {
            string.concat([
              acc,
              encode_parameter_at(
                string.concat([
                  "Parameters",
                  ".Parameter.",
                  int.to_string(idx + 1),
                ]),
                item,
              ),
            ])
          })
      },
    ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_modify_db_parameter_group_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(ModifyDBParameterGroupOutput, String) {
  Ok(ModifyDBParameterGroupOutput)
}

pub type ModifyDBProxyInput {
  ModifyDBProxyInput(
    db_proxy_name: String,
    new_db_proxy_name: option.Option(String),
    default_auth_scheme: option.Option(DefaultAuthScheme),
    auth: option.Option(List(UserAuthConfig)),
    require_tls: option.Option(Bool),
    idle_client_timeout: option.Option(Int),
    debug_logging: option.Option(Bool),
    role_arn: option.Option(String),
    security_groups: option.Option(List(String)),
  )
}

pub fn modify_db_proxy_input_default(
  db_proxy_name db_proxy_name: String,
) -> ModifyDBProxyInput {
  ModifyDBProxyInput(
    db_proxy_name: db_proxy_name,
    new_db_proxy_name: option.None,
    default_auth_scheme: option.None,
    auth: option.None,
    require_tls: option.None,
    idle_client_timeout: option.None,
    debug_logging: option.None,
    role_arn: option.None,
    security_groups: option.None,
  )
}

pub type ModifyDBProxyOutput {
  ModifyDBProxyOutput
}

pub fn decode_modify_db_proxy_input_struct() -> decode.Decoder(
  ModifyDBProxyInput,
) {
  use <- decode.recursive
  use db_proxy_name <- decode.field("DBProxyName", decode.string)
  use new_db_proxy_name <- decode.optional_field(
    "NewDBProxyName",
    option.None,
    decode.optional(decode.string),
  )
  use default_auth_scheme <- decode.optional_field(
    "DefaultAuthScheme",
    option.None,
    decode.optional(decode_default_auth_scheme_enum()),
  )
  use auth <- decode.optional_field(
    "Auth",
    option.None,
    decode.optional(decode.list(decode_user_auth_config_struct_params())),
  )
  use require_tls <- decode.optional_field(
    "RequireTLS",
    option.None,
    decode.optional(decode.bool),
  )
  use idle_client_timeout <- decode.optional_field(
    "IdleClientTimeout",
    option.None,
    decode.optional(decode.int),
  )
  use debug_logging <- decode.optional_field(
    "DebugLogging",
    option.None,
    decode.optional(decode.bool),
  )
  use role_arn <- decode.optional_field(
    "RoleArn",
    option.None,
    decode.optional(decode.string),
  )
  use security_groups <- decode.optional_field(
    "SecurityGroups",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  decode.success(ModifyDBProxyInput(
    db_proxy_name: db_proxy_name,
    new_db_proxy_name: new_db_proxy_name,
    default_auth_scheme: default_auth_scheme,
    auth: auth,
    require_tls: require_tls,
    idle_client_timeout: idle_client_timeout,
    debug_logging: debug_logging,
    role_arn: role_arn,
    security_groups: security_groups,
  ))
}

pub fn decode_modify_db_proxy_input(
  json_string: String,
) -> Result(ModifyDBProxyInput, String) {
  result.map_error(
    json.parse(json_string, decode_modify_db_proxy_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_modify_db_proxy_request(
  input: ModifyDBProxyInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=ModifyDBProxy&Version=2014-10-31"
  let body = {
    let v = input.db_proxy_name
    string.concat([
      body,
      string.concat(["&", "DBProxyName", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.new_db_proxy_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "NewDBProxyName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.default_auth_scheme {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DefaultAuthScheme",
          "=",
          uri.encode_component(default_auth_scheme_to_wire(v)),
        ]),
      ])
  }
  let body = case input.auth {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Auth", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_user_auth_config_at(
                  string.concat(["Auth", ".member.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.require_tls {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "RequireTLS",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.idle_client_timeout {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "IdleClientTimeout", "=", int.to_string(v)]),
      ])
  }
  let body = case input.debug_logging {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DebugLogging",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.role_arn {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "RoleArn", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.security_groups {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "SecurityGroups", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "SecurityGroups",
                    ".member.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_modify_db_proxy_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(ModifyDBProxyOutput, String) {
  Ok(ModifyDBProxyOutput)
}

pub type ModifyDBProxyEndpointInput {
  ModifyDBProxyEndpointInput(
    db_proxy_endpoint_name: String,
    new_db_proxy_endpoint_name: option.Option(String),
    vpc_security_group_ids: option.Option(List(String)),
  )
}

pub fn modify_db_proxy_endpoint_input_default(
  db_proxy_endpoint_name db_proxy_endpoint_name: String,
) -> ModifyDBProxyEndpointInput {
  ModifyDBProxyEndpointInput(
    db_proxy_endpoint_name: db_proxy_endpoint_name,
    new_db_proxy_endpoint_name: option.None,
    vpc_security_group_ids: option.None,
  )
}

pub type ModifyDBProxyEndpointOutput {
  ModifyDBProxyEndpointOutput
}

pub fn decode_modify_db_proxy_endpoint_input_struct() -> decode.Decoder(
  ModifyDBProxyEndpointInput,
) {
  use <- decode.recursive
  use db_proxy_endpoint_name <- decode.field(
    "DBProxyEndpointName",
    decode.string,
  )
  use new_db_proxy_endpoint_name <- decode.optional_field(
    "NewDBProxyEndpointName",
    option.None,
    decode.optional(decode.string),
  )
  use vpc_security_group_ids <- decode.optional_field(
    "VpcSecurityGroupIds",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  decode.success(ModifyDBProxyEndpointInput(
    db_proxy_endpoint_name: db_proxy_endpoint_name,
    new_db_proxy_endpoint_name: new_db_proxy_endpoint_name,
    vpc_security_group_ids: vpc_security_group_ids,
  ))
}

pub fn decode_modify_db_proxy_endpoint_input(
  json_string: String,
) -> Result(ModifyDBProxyEndpointInput, String) {
  result.map_error(
    json.parse(json_string, decode_modify_db_proxy_endpoint_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_modify_db_proxy_endpoint_request(
  input: ModifyDBProxyEndpointInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=ModifyDBProxyEndpoint&Version=2014-10-31"
  let body = {
    let v = input.db_proxy_endpoint_name
    string.concat([
      body,
      string.concat(["&", "DBProxyEndpointName", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.new_db_proxy_endpoint_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "NewDBProxyEndpointName",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.vpc_security_group_ids {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "VpcSecurityGroupIds", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "VpcSecurityGroupIds",
                    ".member.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_modify_db_proxy_endpoint_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(ModifyDBProxyEndpointOutput, String) {
  Ok(ModifyDBProxyEndpointOutput)
}

pub type ModifyDBProxyTargetGroupInput {
  ModifyDBProxyTargetGroupInput(
    target_group_name: String,
    db_proxy_name: String,
    connection_pool_config: option.Option(ConnectionPoolConfiguration),
    new_name: option.Option(String),
  )
}

pub fn modify_db_proxy_target_group_input_default(
  target_group_name target_group_name: String,
  db_proxy_name db_proxy_name: String,
) -> ModifyDBProxyTargetGroupInput {
  ModifyDBProxyTargetGroupInput(
    target_group_name: target_group_name,
    db_proxy_name: db_proxy_name,
    connection_pool_config: option.None,
    new_name: option.None,
  )
}

pub type ModifyDBProxyTargetGroupOutput {
  ModifyDBProxyTargetGroupOutput
}

pub fn decode_modify_db_proxy_target_group_input_struct() -> decode.Decoder(
  ModifyDBProxyTargetGroupInput,
) {
  use <- decode.recursive
  use target_group_name <- decode.field("TargetGroupName", decode.string)
  use db_proxy_name <- decode.field("DBProxyName", decode.string)
  use connection_pool_config <- decode.optional_field(
    "ConnectionPoolConfig",
    option.None,
    decode.optional(decode_connection_pool_configuration_struct_params()),
  )
  use new_name <- decode.optional_field(
    "NewName",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(ModifyDBProxyTargetGroupInput(
    target_group_name: target_group_name,
    db_proxy_name: db_proxy_name,
    connection_pool_config: connection_pool_config,
    new_name: new_name,
  ))
}

pub fn decode_modify_db_proxy_target_group_input(
  json_string: String,
) -> Result(ModifyDBProxyTargetGroupInput, String) {
  result.map_error(
    json.parse(json_string, decode_modify_db_proxy_target_group_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_modify_db_proxy_target_group_request(
  input: ModifyDBProxyTargetGroupInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=ModifyDBProxyTargetGroup&Version=2014-10-31"
  let body = {
    let v = input.target_group_name
    string.concat([
      body,
      string.concat(["&", "TargetGroupName", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.db_proxy_name
    string.concat([
      body,
      string.concat(["&", "DBProxyName", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.connection_pool_config {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        encode_connection_pool_configuration_at("ConnectionPoolConfig", v),
      ])
  }
  let body = case input.new_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "NewName", "=", uri.encode_component(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_modify_db_proxy_target_group_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(ModifyDBProxyTargetGroupOutput, String) {
  Ok(ModifyDBProxyTargetGroupOutput)
}

pub type ModifyDBRecommendationInput {
  ModifyDBRecommendationInput(
    recommendation_id: String,
    locale: option.Option(String),
    status: option.Option(String),
    recommended_action_updates: option.Option(List(RecommendedActionUpdate)),
  )
}

pub fn modify_db_recommendation_input_default(
  recommendation_id recommendation_id: String,
) -> ModifyDBRecommendationInput {
  ModifyDBRecommendationInput(
    recommendation_id: recommendation_id,
    locale: option.None,
    status: option.None,
    recommended_action_updates: option.None,
  )
}

pub type ModifyDBRecommendationOutput {
  ModifyDBRecommendationOutput
}

pub fn decode_modify_db_recommendation_input_struct() -> decode.Decoder(
  ModifyDBRecommendationInput,
) {
  use <- decode.recursive
  use recommendation_id <- decode.field("RecommendationId", decode.string)
  use locale <- decode.optional_field(
    "Locale",
    option.None,
    decode.optional(decode.string),
  )
  use status <- decode.optional_field(
    "Status",
    option.None,
    decode.optional(decode.string),
  )
  use recommended_action_updates <- decode.optional_field(
    "RecommendedActionUpdates",
    option.None,
    decode.optional(
      decode.list(decode_recommended_action_update_struct_params()),
    ),
  )
  decode.success(ModifyDBRecommendationInput(
    recommendation_id: recommendation_id,
    locale: locale,
    status: status,
    recommended_action_updates: recommended_action_updates,
  ))
}

pub fn decode_modify_db_recommendation_input(
  json_string: String,
) -> Result(ModifyDBRecommendationInput, String) {
  result.map_error(
    json.parse(json_string, decode_modify_db_recommendation_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_modify_db_recommendation_request(
  input: ModifyDBRecommendationInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=ModifyDBRecommendation&Version=2014-10-31"
  let body = {
    let v = input.recommendation_id
    string.concat([
      body,
      string.concat(["&", "RecommendationId", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.locale {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Locale", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.status {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Status", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.recommended_action_updates {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "RecommendedActionUpdates", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_recommended_action_update_at(
                  string.concat([
                    "RecommendedActionUpdates",
                    ".member.",
                    int.to_string(idx + 1),
                  ]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_modify_db_recommendation_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(ModifyDBRecommendationOutput, String) {
  Ok(ModifyDBRecommendationOutput)
}

pub type ModifyDBShardGroupInput {
  ModifyDBShardGroupInput(
    db_shard_group_identifier: String,
    max_acu: option.Option(json_float.SmithyFloat),
    min_acu: option.Option(json_float.SmithyFloat),
    compute_redundancy: option.Option(Int),
  )
}

pub fn modify_db_shard_group_input_default(
  db_shard_group_identifier db_shard_group_identifier: String,
) -> ModifyDBShardGroupInput {
  ModifyDBShardGroupInput(
    db_shard_group_identifier: db_shard_group_identifier,
    max_acu: option.None,
    min_acu: option.None,
    compute_redundancy: option.None,
  )
}

pub type ModifyDBShardGroupOutput {
  ModifyDBShardGroupOutput
}

pub fn decode_modify_db_shard_group_input_struct() -> decode.Decoder(
  ModifyDBShardGroupInput,
) {
  use <- decode.recursive
  use db_shard_group_identifier <- decode.field(
    "DBShardGroupIdentifier",
    decode.string,
  )
  use max_acu <- decode.optional_field(
    "MaxACU",
    option.None,
    decode.optional(json_float.decoder()),
  )
  use min_acu <- decode.optional_field(
    "MinACU",
    option.None,
    decode.optional(json_float.decoder()),
  )
  use compute_redundancy <- decode.optional_field(
    "ComputeRedundancy",
    option.None,
    decode.optional(decode.int),
  )
  decode.success(ModifyDBShardGroupInput(
    db_shard_group_identifier: db_shard_group_identifier,
    max_acu: max_acu,
    min_acu: min_acu,
    compute_redundancy: compute_redundancy,
  ))
}

pub fn decode_modify_db_shard_group_input(
  json_string: String,
) -> Result(ModifyDBShardGroupInput, String) {
  result.map_error(
    json.parse(json_string, decode_modify_db_shard_group_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_modify_db_shard_group_request(
  input: ModifyDBShardGroupInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=ModifyDBShardGroup&Version=2014-10-31"
  let body = {
    let v = input.db_shard_group_identifier
    string.concat([
      body,
      string.concat([
        "&",
        "DBShardGroupIdentifier",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body = case input.max_acu {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxACU", "=", format_smithy_float(v)]),
      ])
  }
  let body = case input.min_acu {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MinACU", "=", format_smithy_float(v)]),
      ])
  }
  let body = case input.compute_redundancy {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "ComputeRedundancy", "=", int.to_string(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_modify_db_shard_group_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(ModifyDBShardGroupOutput, String) {
  Ok(ModifyDBShardGroupOutput)
}

pub type ModifyDBSnapshotInput {
  ModifyDBSnapshotInput(
    db_snapshot_identifier: String,
    engine_version: option.Option(String),
    option_group_name: option.Option(String),
  )
}

pub fn modify_db_snapshot_input_default(
  db_snapshot_identifier db_snapshot_identifier: String,
) -> ModifyDBSnapshotInput {
  ModifyDBSnapshotInput(
    db_snapshot_identifier: db_snapshot_identifier,
    engine_version: option.None,
    option_group_name: option.None,
  )
}

pub type ModifyDBSnapshotOutput {
  ModifyDBSnapshotOutput
}

pub fn decode_modify_db_snapshot_input_struct() -> decode.Decoder(
  ModifyDBSnapshotInput,
) {
  use <- decode.recursive
  use db_snapshot_identifier <- decode.field(
    "DBSnapshotIdentifier",
    decode.string,
  )
  use engine_version <- decode.optional_field(
    "EngineVersion",
    option.None,
    decode.optional(decode.string),
  )
  use option_group_name <- decode.optional_field(
    "OptionGroupName",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(ModifyDBSnapshotInput(
    db_snapshot_identifier: db_snapshot_identifier,
    engine_version: engine_version,
    option_group_name: option_group_name,
  ))
}

pub fn decode_modify_db_snapshot_input(
  json_string: String,
) -> Result(ModifyDBSnapshotInput, String) {
  result.map_error(
    json.parse(json_string, decode_modify_db_snapshot_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_modify_db_snapshot_request(
  input: ModifyDBSnapshotInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=ModifyDBSnapshot&Version=2014-10-31"
  let body = {
    let v = input.db_snapshot_identifier
    string.concat([
      body,
      string.concat(["&", "DBSnapshotIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.engine_version {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "EngineVersion", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.option_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "OptionGroupName", "=", uri.encode_component(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_modify_db_snapshot_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(ModifyDBSnapshotOutput, String) {
  Ok(ModifyDBSnapshotOutput)
}

pub type ModifyDBSnapshotAttributeInput {
  ModifyDBSnapshotAttributeInput(
    db_snapshot_identifier: String,
    attribute_name: String,
    values_to_add: option.Option(List(String)),
    values_to_remove: option.Option(List(String)),
  )
}

pub fn modify_db_snapshot_attribute_input_default(
  db_snapshot_identifier db_snapshot_identifier: String,
  attribute_name attribute_name: String,
) -> ModifyDBSnapshotAttributeInput {
  ModifyDBSnapshotAttributeInput(
    db_snapshot_identifier: db_snapshot_identifier,
    attribute_name: attribute_name,
    values_to_add: option.None,
    values_to_remove: option.None,
  )
}

pub type ModifyDBSnapshotAttributeOutput {
  ModifyDBSnapshotAttributeOutput
}

pub fn decode_modify_db_snapshot_attribute_input_struct() -> decode.Decoder(
  ModifyDBSnapshotAttributeInput,
) {
  use <- decode.recursive
  use db_snapshot_identifier <- decode.field(
    "DBSnapshotIdentifier",
    decode.string,
  )
  use attribute_name <- decode.field("AttributeName", decode.string)
  use values_to_add <- decode.optional_field(
    "ValuesToAdd",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use values_to_remove <- decode.optional_field(
    "ValuesToRemove",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  decode.success(ModifyDBSnapshotAttributeInput(
    db_snapshot_identifier: db_snapshot_identifier,
    attribute_name: attribute_name,
    values_to_add: values_to_add,
    values_to_remove: values_to_remove,
  ))
}

pub fn decode_modify_db_snapshot_attribute_input(
  json_string: String,
) -> Result(ModifyDBSnapshotAttributeInput, String) {
  result.map_error(
    json.parse(json_string, decode_modify_db_snapshot_attribute_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_modify_db_snapshot_attribute_request(
  input: ModifyDBSnapshotAttributeInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=ModifyDBSnapshotAttribute&Version=2014-10-31"
  let body = {
    let v = input.db_snapshot_identifier
    string.concat([
      body,
      string.concat(["&", "DBSnapshotIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.attribute_name
    string.concat([
      body,
      string.concat(["&", "AttributeName", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.values_to_add {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "ValuesToAdd", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "ValuesToAdd",
                    ".AttributeValue.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body = case input.values_to_remove {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "ValuesToRemove", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "ValuesToRemove",
                    ".AttributeValue.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_modify_db_snapshot_attribute_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(ModifyDBSnapshotAttributeOutput, String) {
  Ok(ModifyDBSnapshotAttributeOutput)
}

pub type ModifyDBSubnetGroupInput {
  ModifyDBSubnetGroupInput(
    db_subnet_group_name: String,
    db_subnet_group_description: option.Option(String),
    subnet_ids: List(String),
  )
}

pub fn modify_db_subnet_group_input_default(
  db_subnet_group_name db_subnet_group_name: String,
  subnet_ids subnet_ids: List(String),
) -> ModifyDBSubnetGroupInput {
  ModifyDBSubnetGroupInput(
    db_subnet_group_name: db_subnet_group_name,
    db_subnet_group_description: option.None,
    subnet_ids: subnet_ids,
  )
}

pub type ModifyDBSubnetGroupOutput {
  ModifyDBSubnetGroupOutput
}

pub fn decode_modify_db_subnet_group_input_struct() -> decode.Decoder(
  ModifyDBSubnetGroupInput,
) {
  use <- decode.recursive
  use db_subnet_group_name <- decode.field("DBSubnetGroupName", decode.string)
  use db_subnet_group_description <- decode.optional_field(
    "DBSubnetGroupDescription",
    option.None,
    decode.optional(decode.string),
  )
  use subnet_ids <- decode.field("SubnetIds", decode.list(decode.string))
  decode.success(ModifyDBSubnetGroupInput(
    db_subnet_group_name: db_subnet_group_name,
    db_subnet_group_description: db_subnet_group_description,
    subnet_ids: subnet_ids,
  ))
}

pub fn decode_modify_db_subnet_group_input(
  json_string: String,
) -> Result(ModifyDBSubnetGroupInput, String) {
  result.map_error(
    json.parse(json_string, decode_modify_db_subnet_group_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_modify_db_subnet_group_request(
  input: ModifyDBSubnetGroupInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=ModifyDBSubnetGroup&Version=2014-10-31"
  let body = {
    let v = input.db_subnet_group_name
    string.concat([
      body,
      string.concat(["&", "DBSubnetGroupName", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.db_subnet_group_description {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DBSubnetGroupDescription",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = {
    let v = input.subnet_ids
    string.concat([
      body,
      case v {
        [] -> string.concat(["&", "SubnetIds", "=", ""])
        _ ->
          list.index_fold(v, "", fn(acc, item, idx) {
            string.concat([
              acc,
              string.concat([
                "&",
                string.concat([
                  "SubnetIds",
                  ".SubnetIdentifier.",
                  int.to_string(idx + 1),
                ]),
                "=",
                uri.encode_component(item),
              ]),
            ])
          })
      },
    ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_modify_db_subnet_group_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(ModifyDBSubnetGroupOutput, String) {
  Ok(ModifyDBSubnetGroupOutput)
}

pub type ModifyEventSubscriptionInput {
  ModifyEventSubscriptionInput(
    subscription_name: String,
    sns_topic_arn: option.Option(String),
    source_type: option.Option(String),
    event_categories: option.Option(List(String)),
    enabled: option.Option(Bool),
  )
}

pub fn modify_event_subscription_input_default(
  subscription_name subscription_name: String,
) -> ModifyEventSubscriptionInput {
  ModifyEventSubscriptionInput(
    subscription_name: subscription_name,
    sns_topic_arn: option.None,
    source_type: option.None,
    event_categories: option.None,
    enabled: option.None,
  )
}

pub type ModifyEventSubscriptionOutput {
  ModifyEventSubscriptionOutput
}

pub fn decode_modify_event_subscription_input_struct() -> decode.Decoder(
  ModifyEventSubscriptionInput,
) {
  use <- decode.recursive
  use subscription_name <- decode.field("SubscriptionName", decode.string)
  use sns_topic_arn <- decode.optional_field(
    "SnsTopicArn",
    option.None,
    decode.optional(decode.string),
  )
  use source_type <- decode.optional_field(
    "SourceType",
    option.None,
    decode.optional(decode.string),
  )
  use event_categories <- decode.optional_field(
    "EventCategories",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use enabled <- decode.optional_field(
    "Enabled",
    option.None,
    decode.optional(decode.bool),
  )
  decode.success(ModifyEventSubscriptionInput(
    subscription_name: subscription_name,
    sns_topic_arn: sns_topic_arn,
    source_type: source_type,
    event_categories: event_categories,
    enabled: enabled,
  ))
}

pub fn decode_modify_event_subscription_input(
  json_string: String,
) -> Result(ModifyEventSubscriptionInput, String) {
  result.map_error(
    json.parse(json_string, decode_modify_event_subscription_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_modify_event_subscription_request(
  input: ModifyEventSubscriptionInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=ModifyEventSubscription&Version=2014-10-31"
  let body = {
    let v = input.subscription_name
    string.concat([
      body,
      string.concat(["&", "SubscriptionName", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.sns_topic_arn {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "SnsTopicArn", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.source_type {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "SourceType", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.event_categories {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "EventCategories", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "EventCategories",
                    ".EventCategory.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body = case input.enabled {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "Enabled",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_modify_event_subscription_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(ModifyEventSubscriptionOutput, String) {
  Ok(ModifyEventSubscriptionOutput)
}

pub type ModifyGlobalClusterInput {
  ModifyGlobalClusterInput(
    global_cluster_identifier: String,
    new_global_cluster_identifier: option.Option(String),
    deletion_protection: option.Option(Bool),
    engine_version: option.Option(String),
    allow_major_version_upgrade: option.Option(Bool),
  )
}

pub fn modify_global_cluster_input_default(
  global_cluster_identifier global_cluster_identifier: String,
) -> ModifyGlobalClusterInput {
  ModifyGlobalClusterInput(
    global_cluster_identifier: global_cluster_identifier,
    new_global_cluster_identifier: option.None,
    deletion_protection: option.None,
    engine_version: option.None,
    allow_major_version_upgrade: option.None,
  )
}

pub type ModifyGlobalClusterOutput {
  ModifyGlobalClusterOutput
}

pub fn decode_modify_global_cluster_input_struct() -> decode.Decoder(
  ModifyGlobalClusterInput,
) {
  use <- decode.recursive
  use global_cluster_identifier <- decode.field(
    "GlobalClusterIdentifier",
    decode.string,
  )
  use new_global_cluster_identifier <- decode.optional_field(
    "NewGlobalClusterIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use deletion_protection <- decode.optional_field(
    "DeletionProtection",
    option.None,
    decode.optional(decode.bool),
  )
  use engine_version <- decode.optional_field(
    "EngineVersion",
    option.None,
    decode.optional(decode.string),
  )
  use allow_major_version_upgrade <- decode.optional_field(
    "AllowMajorVersionUpgrade",
    option.None,
    decode.optional(decode.bool),
  )
  decode.success(ModifyGlobalClusterInput(
    global_cluster_identifier: global_cluster_identifier,
    new_global_cluster_identifier: new_global_cluster_identifier,
    deletion_protection: deletion_protection,
    engine_version: engine_version,
    allow_major_version_upgrade: allow_major_version_upgrade,
  ))
}

pub fn decode_modify_global_cluster_input(
  json_string: String,
) -> Result(ModifyGlobalClusterInput, String) {
  result.map_error(
    json.parse(json_string, decode_modify_global_cluster_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_modify_global_cluster_request(
  input: ModifyGlobalClusterInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=ModifyGlobalCluster&Version=2014-10-31"
  let body = {
    let v = input.global_cluster_identifier
    string.concat([
      body,
      string.concat([
        "&",
        "GlobalClusterIdentifier",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body = case input.new_global_cluster_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "NewGlobalClusterIdentifier",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.deletion_protection {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DeletionProtection",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.engine_version {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "EngineVersion", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.allow_major_version_upgrade {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "AllowMajorVersionUpgrade",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_modify_global_cluster_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(ModifyGlobalClusterOutput, String) {
  Ok(ModifyGlobalClusterOutput)
}

pub type ModifyIntegrationInput {
  ModifyIntegrationInput(
    integration_identifier: String,
    integration_name: option.Option(String),
    data_filter: option.Option(String),
    description: option.Option(String),
  )
}

pub fn modify_integration_input_default(
  integration_identifier integration_identifier: String,
) -> ModifyIntegrationInput {
  ModifyIntegrationInput(
    integration_identifier: integration_identifier,
    integration_name: option.None,
    data_filter: option.None,
    description: option.None,
  )
}

pub type ModifyIntegrationOutput {
  ModifyIntegrationOutput
}

pub fn decode_modify_integration_input_struct() -> decode.Decoder(
  ModifyIntegrationInput,
) {
  use <- decode.recursive
  use integration_identifier <- decode.field(
    "IntegrationIdentifier",
    decode.string,
  )
  use integration_name <- decode.optional_field(
    "IntegrationName",
    option.None,
    decode.optional(decode.string),
  )
  use data_filter <- decode.optional_field(
    "DataFilter",
    option.None,
    decode.optional(decode.string),
  )
  use description <- decode.optional_field(
    "Description",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(ModifyIntegrationInput(
    integration_identifier: integration_identifier,
    integration_name: integration_name,
    data_filter: data_filter,
    description: description,
  ))
}

pub fn decode_modify_integration_input(
  json_string: String,
) -> Result(ModifyIntegrationInput, String) {
  result.map_error(
    json.parse(json_string, decode_modify_integration_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_modify_integration_request(
  input: ModifyIntegrationInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=ModifyIntegration&Version=2014-10-31"
  let body = {
    let v = input.integration_identifier
    string.concat([
      body,
      string.concat(["&", "IntegrationIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.integration_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "IntegrationName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.data_filter {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DataFilter", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.description {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Description", "=", uri.encode_component(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_modify_integration_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(ModifyIntegrationOutput, String) {
  Ok(ModifyIntegrationOutput)
}

pub type ModifyOptionGroupInput {
  ModifyOptionGroupInput(
    option_group_name: String,
    options_to_include: option.Option(List(OptionConfiguration)),
    options_to_remove: option.Option(List(String)),
    apply_immediately: option.Option(Bool),
  )
}

pub fn modify_option_group_input_default(
  option_group_name option_group_name: String,
) -> ModifyOptionGroupInput {
  ModifyOptionGroupInput(
    option_group_name: option_group_name,
    options_to_include: option.None,
    options_to_remove: option.None,
    apply_immediately: option.None,
  )
}

pub type ModifyOptionGroupOutput {
  ModifyOptionGroupOutput
}

pub fn decode_modify_option_group_input_struct() -> decode.Decoder(
  ModifyOptionGroupInput,
) {
  use <- decode.recursive
  use option_group_name <- decode.field("OptionGroupName", decode.string)
  use options_to_include <- decode.optional_field(
    "OptionsToInclude",
    option.None,
    decode.optional(decode.list(decode_option_configuration_struct_params())),
  )
  use options_to_remove <- decode.optional_field(
    "OptionsToRemove",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use apply_immediately <- decode.optional_field(
    "ApplyImmediately",
    option.None,
    decode.optional(decode.bool),
  )
  decode.success(ModifyOptionGroupInput(
    option_group_name: option_group_name,
    options_to_include: options_to_include,
    options_to_remove: options_to_remove,
    apply_immediately: apply_immediately,
  ))
}

pub fn decode_modify_option_group_input(
  json_string: String,
) -> Result(ModifyOptionGroupInput, String) {
  result.map_error(
    json.parse(json_string, decode_modify_option_group_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_modify_option_group_request(
  input: ModifyOptionGroupInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=ModifyOptionGroup&Version=2014-10-31"
  let body = {
    let v = input.option_group_name
    string.concat([
      body,
      string.concat(["&", "OptionGroupName", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.options_to_include {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "OptionsToInclude", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_option_configuration_at(
                  string.concat([
                    "OptionsToInclude",
                    ".OptionConfiguration.",
                    int.to_string(idx + 1),
                  ]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.options_to_remove {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "OptionsToRemove", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "OptionsToRemove",
                    ".member.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body = case input.apply_immediately {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "ApplyImmediately",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_modify_option_group_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(ModifyOptionGroupOutput, String) {
  Ok(ModifyOptionGroupOutput)
}

pub type ModifyTenantDatabaseInput {
  ModifyTenantDatabaseInput(
    db_instance_identifier: String,
    tenant_db_name: String,
    master_user_password: option.Option(String),
    new_tenant_db_name: option.Option(String),
    manage_master_user_password: option.Option(Bool),
    rotate_master_user_password: option.Option(Bool),
    master_user_secret_kms_key_id: option.Option(String),
  )
}

pub fn modify_tenant_database_input_default(
  db_instance_identifier db_instance_identifier: String,
  tenant_db_name tenant_db_name: String,
) -> ModifyTenantDatabaseInput {
  ModifyTenantDatabaseInput(
    db_instance_identifier: db_instance_identifier,
    tenant_db_name: tenant_db_name,
    master_user_password: option.None,
    new_tenant_db_name: option.None,
    manage_master_user_password: option.None,
    rotate_master_user_password: option.None,
    master_user_secret_kms_key_id: option.None,
  )
}

pub type ModifyTenantDatabaseOutput {
  ModifyTenantDatabaseOutput
}

pub fn decode_modify_tenant_database_input_struct() -> decode.Decoder(
  ModifyTenantDatabaseInput,
) {
  use <- decode.recursive
  use db_instance_identifier <- decode.field(
    "DBInstanceIdentifier",
    decode.string,
  )
  use tenant_db_name <- decode.field("TenantDBName", decode.string)
  use master_user_password <- decode.optional_field(
    "MasterUserPassword",
    option.None,
    decode.optional(decode.string),
  )
  use new_tenant_db_name <- decode.optional_field(
    "NewTenantDBName",
    option.None,
    decode.optional(decode.string),
  )
  use manage_master_user_password <- decode.optional_field(
    "ManageMasterUserPassword",
    option.None,
    decode.optional(decode.bool),
  )
  use rotate_master_user_password <- decode.optional_field(
    "RotateMasterUserPassword",
    option.None,
    decode.optional(decode.bool),
  )
  use master_user_secret_kms_key_id <- decode.optional_field(
    "MasterUserSecretKmsKeyId",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(ModifyTenantDatabaseInput(
    db_instance_identifier: db_instance_identifier,
    tenant_db_name: tenant_db_name,
    master_user_password: master_user_password,
    new_tenant_db_name: new_tenant_db_name,
    manage_master_user_password: manage_master_user_password,
    rotate_master_user_password: rotate_master_user_password,
    master_user_secret_kms_key_id: master_user_secret_kms_key_id,
  ))
}

pub fn decode_modify_tenant_database_input(
  json_string: String,
) -> Result(ModifyTenantDatabaseInput, String) {
  result.map_error(
    json.parse(json_string, decode_modify_tenant_database_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_modify_tenant_database_request(
  input: ModifyTenantDatabaseInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=ModifyTenantDatabase&Version=2014-10-31"
  let body = {
    let v = input.db_instance_identifier
    string.concat([
      body,
      string.concat(["&", "DBInstanceIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.tenant_db_name
    string.concat([
      body,
      string.concat(["&", "TenantDBName", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.master_user_password {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MasterUserPassword", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.new_tenant_db_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "NewTenantDBName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.manage_master_user_password {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "ManageMasterUserPassword",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.rotate_master_user_password {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "RotateMasterUserPassword",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.master_user_secret_kms_key_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "MasterUserSecretKmsKeyId",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_modify_tenant_database_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(ModifyTenantDatabaseOutput, String) {
  Ok(ModifyTenantDatabaseOutput)
}

pub type PromoteReadReplicaInput {
  PromoteReadReplicaInput(
    db_instance_identifier: String,
    backup_retention_period: option.Option(Int),
    preferred_backup_window: option.Option(String),
    tag_specifications: option.Option(List(TagSpecification)),
  )
}

pub fn promote_read_replica_input_default(
  db_instance_identifier db_instance_identifier: String,
) -> PromoteReadReplicaInput {
  PromoteReadReplicaInput(
    db_instance_identifier: db_instance_identifier,
    backup_retention_period: option.None,
    preferred_backup_window: option.None,
    tag_specifications: option.None,
  )
}

pub type PromoteReadReplicaOutput {
  PromoteReadReplicaOutput
}

pub fn decode_promote_read_replica_input_struct() -> decode.Decoder(
  PromoteReadReplicaInput,
) {
  use <- decode.recursive
  use db_instance_identifier <- decode.field(
    "DBInstanceIdentifier",
    decode.string,
  )
  use backup_retention_period <- decode.optional_field(
    "BackupRetentionPeriod",
    option.None,
    decode.optional(decode.int),
  )
  use preferred_backup_window <- decode.optional_field(
    "PreferredBackupWindow",
    option.None,
    decode.optional(decode.string),
  )
  use tag_specifications <- decode.optional_field(
    "TagSpecifications",
    option.None,
    decode.optional(decode.list(decode_tag_specification_struct_params())),
  )
  decode.success(PromoteReadReplicaInput(
    db_instance_identifier: db_instance_identifier,
    backup_retention_period: backup_retention_period,
    preferred_backup_window: preferred_backup_window,
    tag_specifications: tag_specifications,
  ))
}

pub fn decode_promote_read_replica_input(
  json_string: String,
) -> Result(PromoteReadReplicaInput, String) {
  result.map_error(
    json.parse(json_string, decode_promote_read_replica_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_promote_read_replica_request(
  input: PromoteReadReplicaInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=PromoteReadReplica&Version=2014-10-31"
  let body = {
    let v = input.db_instance_identifier
    string.concat([
      body,
      string.concat(["&", "DBInstanceIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.backup_retention_period {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "BackupRetentionPeriod", "=", int.to_string(v)]),
      ])
  }
  let body = case input.preferred_backup_window {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "PreferredBackupWindow",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.tag_specifications {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "TagSpecifications", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_tag_specification_at(
                  string.concat([
                    "TagSpecifications",
                    ".item.",
                    int.to_string(idx + 1),
                  ]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_promote_read_replica_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(PromoteReadReplicaOutput, String) {
  Ok(PromoteReadReplicaOutput)
}

pub type PromoteReadReplicaDBClusterInput {
  PromoteReadReplicaDBClusterInput(db_cluster_identifier: String)
}

pub fn promote_read_replica_db_cluster_input_default(
  db_cluster_identifier db_cluster_identifier: String,
) -> PromoteReadReplicaDBClusterInput {
  PromoteReadReplicaDBClusterInput(db_cluster_identifier: db_cluster_identifier)
}

pub type PromoteReadReplicaDBClusterOutput {
  PromoteReadReplicaDBClusterOutput
}

pub fn decode_promote_read_replica_db_cluster_input_struct() -> decode.Decoder(
  PromoteReadReplicaDBClusterInput,
) {
  use <- decode.recursive
  use db_cluster_identifier <- decode.field(
    "DBClusterIdentifier",
    decode.string,
  )
  decode.success(PromoteReadReplicaDBClusterInput(
    db_cluster_identifier: db_cluster_identifier,
  ))
}

pub fn decode_promote_read_replica_db_cluster_input(
  json_string: String,
) -> Result(PromoteReadReplicaDBClusterInput, String) {
  result.map_error(
    json.parse(
      json_string,
      decode_promote_read_replica_db_cluster_input_struct(),
    ),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_promote_read_replica_db_cluster_request(
  input: PromoteReadReplicaDBClusterInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=PromoteReadReplicaDBCluster&Version=2014-10-31"
  let body = {
    let v = input.db_cluster_identifier
    string.concat([
      body,
      string.concat(["&", "DBClusterIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_promote_read_replica_db_cluster_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(PromoteReadReplicaDBClusterOutput, String) {
  Ok(PromoteReadReplicaDBClusterOutput)
}

pub type PurchaseReservedDBInstancesOfferingInput {
  PurchaseReservedDBInstancesOfferingInput(
    reserved_db_instances_offering_id: String,
    reserved_db_instance_id: option.Option(String),
    db_instance_count: option.Option(Int),
    tags: option.Option(List(Tag)),
  )
}

pub fn purchase_reserved_db_instances_offering_input_default(
  reserved_db_instances_offering_id reserved_db_instances_offering_id: String,
) -> PurchaseReservedDBInstancesOfferingInput {
  PurchaseReservedDBInstancesOfferingInput(
    reserved_db_instances_offering_id: reserved_db_instances_offering_id,
    reserved_db_instance_id: option.None,
    db_instance_count: option.None,
    tags: option.None,
  )
}

pub type PurchaseReservedDBInstancesOfferingOutput {
  PurchaseReservedDBInstancesOfferingOutput
}

pub fn decode_purchase_reserved_db_instances_offering_input_struct() -> decode.Decoder(
  PurchaseReservedDBInstancesOfferingInput,
) {
  use <- decode.recursive
  use reserved_db_instances_offering_id <- decode.field(
    "ReservedDBInstancesOfferingId",
    decode.string,
  )
  use reserved_db_instance_id <- decode.optional_field(
    "ReservedDBInstanceId",
    option.None,
    decode.optional(decode.string),
  )
  use db_instance_count <- decode.optional_field(
    "DBInstanceCount",
    option.None,
    decode.optional(decode.int),
  )
  use tags <- decode.optional_field(
    "Tags",
    option.None,
    decode.optional(decode.list(decode_tag_struct_params())),
  )
  decode.success(PurchaseReservedDBInstancesOfferingInput(
    reserved_db_instances_offering_id: reserved_db_instances_offering_id,
    reserved_db_instance_id: reserved_db_instance_id,
    db_instance_count: db_instance_count,
    tags: tags,
  ))
}

pub fn decode_purchase_reserved_db_instances_offering_input(
  json_string: String,
) -> Result(PurchaseReservedDBInstancesOfferingInput, String) {
  result.map_error(
    json.parse(
      json_string,
      decode_purchase_reserved_db_instances_offering_input_struct(),
    ),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_purchase_reserved_db_instances_offering_request(
  input: PurchaseReservedDBInstancesOfferingInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=PurchaseReservedDBInstancesOffering&Version=2014-10-31"
  let body = {
    let v = input.reserved_db_instances_offering_id
    string.concat([
      body,
      string.concat([
        "&",
        "ReservedDBInstancesOfferingId",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body = case input.reserved_db_instance_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "ReservedDBInstanceId",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.db_instance_count {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DBInstanceCount", "=", int.to_string(v)]),
      ])
  }
  let body = case input.tags {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Tags", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_tag_at(
                  string.concat(["Tags", ".Tag.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_purchase_reserved_db_instances_offering_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(PurchaseReservedDBInstancesOfferingOutput, String) {
  Ok(PurchaseReservedDBInstancesOfferingOutput)
}

pub type RebootDBClusterInput {
  RebootDBClusterInput(db_cluster_identifier: String)
}

pub fn reboot_db_cluster_input_default(
  db_cluster_identifier db_cluster_identifier: String,
) -> RebootDBClusterInput {
  RebootDBClusterInput(db_cluster_identifier: db_cluster_identifier)
}

pub type RebootDBClusterOutput {
  RebootDBClusterOutput
}

pub fn decode_reboot_db_cluster_input_struct() -> decode.Decoder(
  RebootDBClusterInput,
) {
  use <- decode.recursive
  use db_cluster_identifier <- decode.field(
    "DBClusterIdentifier",
    decode.string,
  )
  decode.success(RebootDBClusterInput(
    db_cluster_identifier: db_cluster_identifier,
  ))
}

pub fn decode_reboot_db_cluster_input(
  json_string: String,
) -> Result(RebootDBClusterInput, String) {
  result.map_error(
    json.parse(json_string, decode_reboot_db_cluster_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_reboot_db_cluster_request(
  input: RebootDBClusterInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=RebootDBCluster&Version=2014-10-31"
  let body = {
    let v = input.db_cluster_identifier
    string.concat([
      body,
      string.concat(["&", "DBClusterIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_reboot_db_cluster_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(RebootDBClusterOutput, String) {
  Ok(RebootDBClusterOutput)
}

pub type RebootDBInstanceInput {
  RebootDBInstanceInput(
    db_instance_identifier: String,
    force_failover: option.Option(Bool),
  )
}

pub fn reboot_db_instance_input_default(
  db_instance_identifier db_instance_identifier: String,
) -> RebootDBInstanceInput {
  RebootDBInstanceInput(
    db_instance_identifier: db_instance_identifier,
    force_failover: option.None,
  )
}

pub type RebootDBInstanceOutput {
  RebootDBInstanceOutput
}

pub fn decode_reboot_db_instance_input_struct() -> decode.Decoder(
  RebootDBInstanceInput,
) {
  use <- decode.recursive
  use db_instance_identifier <- decode.field(
    "DBInstanceIdentifier",
    decode.string,
  )
  use force_failover <- decode.optional_field(
    "ForceFailover",
    option.None,
    decode.optional(decode.bool),
  )
  decode.success(RebootDBInstanceInput(
    db_instance_identifier: db_instance_identifier,
    force_failover: force_failover,
  ))
}

pub fn decode_reboot_db_instance_input(
  json_string: String,
) -> Result(RebootDBInstanceInput, String) {
  result.map_error(
    json.parse(json_string, decode_reboot_db_instance_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_reboot_db_instance_request(
  input: RebootDBInstanceInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=RebootDBInstance&Version=2014-10-31"
  let body = {
    let v = input.db_instance_identifier
    string.concat([
      body,
      string.concat(["&", "DBInstanceIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.force_failover {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "ForceFailover",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_reboot_db_instance_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(RebootDBInstanceOutput, String) {
  Ok(RebootDBInstanceOutput)
}

pub type RebootDBShardGroupInput {
  RebootDBShardGroupInput(db_shard_group_identifier: String)
}

pub fn reboot_db_shard_group_input_default(
  db_shard_group_identifier db_shard_group_identifier: String,
) -> RebootDBShardGroupInput {
  RebootDBShardGroupInput(db_shard_group_identifier: db_shard_group_identifier)
}

pub type RebootDBShardGroupOutput {
  RebootDBShardGroupOutput
}

pub fn decode_reboot_db_shard_group_input_struct() -> decode.Decoder(
  RebootDBShardGroupInput,
) {
  use <- decode.recursive
  use db_shard_group_identifier <- decode.field(
    "DBShardGroupIdentifier",
    decode.string,
  )
  decode.success(RebootDBShardGroupInput(
    db_shard_group_identifier: db_shard_group_identifier,
  ))
}

pub fn decode_reboot_db_shard_group_input(
  json_string: String,
) -> Result(RebootDBShardGroupInput, String) {
  result.map_error(
    json.parse(json_string, decode_reboot_db_shard_group_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_reboot_db_shard_group_request(
  input: RebootDBShardGroupInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=RebootDBShardGroup&Version=2014-10-31"
  let body = {
    let v = input.db_shard_group_identifier
    string.concat([
      body,
      string.concat([
        "&",
        "DBShardGroupIdentifier",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_reboot_db_shard_group_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(RebootDBShardGroupOutput, String) {
  Ok(RebootDBShardGroupOutput)
}

pub type RegisterDBProxyTargetsInput {
  RegisterDBProxyTargetsInput(
    db_proxy_name: String,
    target_group_name: option.Option(String),
    db_instance_identifiers: option.Option(List(String)),
    db_cluster_identifiers: option.Option(List(String)),
  )
}

pub fn register_db_proxy_targets_input_default(
  db_proxy_name db_proxy_name: String,
) -> RegisterDBProxyTargetsInput {
  RegisterDBProxyTargetsInput(
    db_proxy_name: db_proxy_name,
    target_group_name: option.None,
    db_instance_identifiers: option.None,
    db_cluster_identifiers: option.None,
  )
}

pub type RegisterDBProxyTargetsOutput {
  RegisterDBProxyTargetsOutput
}

pub fn decode_register_db_proxy_targets_input_struct() -> decode.Decoder(
  RegisterDBProxyTargetsInput,
) {
  use <- decode.recursive
  use db_proxy_name <- decode.field("DBProxyName", decode.string)
  use target_group_name <- decode.optional_field(
    "TargetGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use db_instance_identifiers <- decode.optional_field(
    "DBInstanceIdentifiers",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use db_cluster_identifiers <- decode.optional_field(
    "DBClusterIdentifiers",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  decode.success(RegisterDBProxyTargetsInput(
    db_proxy_name: db_proxy_name,
    target_group_name: target_group_name,
    db_instance_identifiers: db_instance_identifiers,
    db_cluster_identifiers: db_cluster_identifiers,
  ))
}

pub fn decode_register_db_proxy_targets_input(
  json_string: String,
) -> Result(RegisterDBProxyTargetsInput, String) {
  result.map_error(
    json.parse(json_string, decode_register_db_proxy_targets_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_register_db_proxy_targets_request(
  input: RegisterDBProxyTargetsInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=RegisterDBProxyTargets&Version=2014-10-31"
  let body = {
    let v = input.db_proxy_name
    string.concat([
      body,
      string.concat(["&", "DBProxyName", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.target_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "TargetGroupName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.db_instance_identifiers {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "DBInstanceIdentifiers", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "DBInstanceIdentifiers",
                    ".member.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body = case input.db_cluster_identifiers {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "DBClusterIdentifiers", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "DBClusterIdentifiers",
                    ".member.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_register_db_proxy_targets_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(RegisterDBProxyTargetsOutput, String) {
  Ok(RegisterDBProxyTargetsOutput)
}

pub type RemoveFromGlobalClusterInput {
  RemoveFromGlobalClusterInput(
    global_cluster_identifier: String,
    db_cluster_identifier: String,
  )
}

pub fn remove_from_global_cluster_input_default(
  global_cluster_identifier global_cluster_identifier: String,
  db_cluster_identifier db_cluster_identifier: String,
) -> RemoveFromGlobalClusterInput {
  RemoveFromGlobalClusterInput(
    global_cluster_identifier: global_cluster_identifier,
    db_cluster_identifier: db_cluster_identifier,
  )
}

pub type RemoveFromGlobalClusterOutput {
  RemoveFromGlobalClusterOutput
}

pub fn decode_remove_from_global_cluster_input_struct() -> decode.Decoder(
  RemoveFromGlobalClusterInput,
) {
  use <- decode.recursive
  use global_cluster_identifier <- decode.field(
    "GlobalClusterIdentifier",
    decode.string,
  )
  use db_cluster_identifier <- decode.field(
    "DbClusterIdentifier",
    decode.string,
  )
  decode.success(RemoveFromGlobalClusterInput(
    global_cluster_identifier: global_cluster_identifier,
    db_cluster_identifier: db_cluster_identifier,
  ))
}

pub fn decode_remove_from_global_cluster_input(
  json_string: String,
) -> Result(RemoveFromGlobalClusterInput, String) {
  result.map_error(
    json.parse(json_string, decode_remove_from_global_cluster_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_remove_from_global_cluster_request(
  input: RemoveFromGlobalClusterInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=RemoveFromGlobalCluster&Version=2014-10-31"
  let body = {
    let v = input.global_cluster_identifier
    string.concat([
      body,
      string.concat([
        "&",
        "GlobalClusterIdentifier",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body = {
    let v = input.db_cluster_identifier
    string.concat([
      body,
      string.concat(["&", "DbClusterIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_remove_from_global_cluster_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(RemoveFromGlobalClusterOutput, String) {
  Ok(RemoveFromGlobalClusterOutput)
}

pub type RemoveRoleFromDBClusterInput {
  RemoveRoleFromDBClusterInput(
    db_cluster_identifier: String,
    role_arn: String,
    feature_name: option.Option(String),
  )
}

pub fn remove_role_from_db_cluster_input_default(
  db_cluster_identifier db_cluster_identifier: String,
  role_arn role_arn: String,
) -> RemoveRoleFromDBClusterInput {
  RemoveRoleFromDBClusterInput(
    db_cluster_identifier: db_cluster_identifier,
    role_arn: role_arn,
    feature_name: option.None,
  )
}

pub type RemoveRoleFromDBClusterOutput {
  RemoveRoleFromDBClusterOutput
}

pub fn decode_remove_role_from_db_cluster_input_struct() -> decode.Decoder(
  RemoveRoleFromDBClusterInput,
) {
  use <- decode.recursive
  use db_cluster_identifier <- decode.field(
    "DBClusterIdentifier",
    decode.string,
  )
  use role_arn <- decode.field("RoleArn", decode.string)
  use feature_name <- decode.optional_field(
    "FeatureName",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(RemoveRoleFromDBClusterInput(
    db_cluster_identifier: db_cluster_identifier,
    role_arn: role_arn,
    feature_name: feature_name,
  ))
}

pub fn decode_remove_role_from_db_cluster_input(
  json_string: String,
) -> Result(RemoveRoleFromDBClusterInput, String) {
  result.map_error(
    json.parse(json_string, decode_remove_role_from_db_cluster_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_remove_role_from_db_cluster_request(
  input: RemoveRoleFromDBClusterInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=RemoveRoleFromDBCluster&Version=2014-10-31"
  let body = {
    let v = input.db_cluster_identifier
    string.concat([
      body,
      string.concat(["&", "DBClusterIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.role_arn
    string.concat([
      body,
      string.concat(["&", "RoleArn", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.feature_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "FeatureName", "=", uri.encode_component(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_remove_role_from_db_cluster_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(RemoveRoleFromDBClusterOutput, String) {
  Ok(RemoveRoleFromDBClusterOutput)
}

pub type RemoveRoleFromDBInstanceInput {
  RemoveRoleFromDBInstanceInput(
    db_instance_identifier: String,
    role_arn: String,
    feature_name: String,
  )
}

pub fn remove_role_from_db_instance_input_default(
  db_instance_identifier db_instance_identifier: String,
  role_arn role_arn: String,
  feature_name feature_name: String,
) -> RemoveRoleFromDBInstanceInput {
  RemoveRoleFromDBInstanceInput(
    db_instance_identifier: db_instance_identifier,
    role_arn: role_arn,
    feature_name: feature_name,
  )
}

pub type RemoveRoleFromDBInstanceOutput {
  RemoveRoleFromDBInstanceOutput
}

pub fn decode_remove_role_from_db_instance_input_struct() -> decode.Decoder(
  RemoveRoleFromDBInstanceInput,
) {
  use <- decode.recursive
  use db_instance_identifier <- decode.field(
    "DBInstanceIdentifier",
    decode.string,
  )
  use role_arn <- decode.field("RoleArn", decode.string)
  use feature_name <- decode.field("FeatureName", decode.string)
  decode.success(RemoveRoleFromDBInstanceInput(
    db_instance_identifier: db_instance_identifier,
    role_arn: role_arn,
    feature_name: feature_name,
  ))
}

pub fn decode_remove_role_from_db_instance_input(
  json_string: String,
) -> Result(RemoveRoleFromDBInstanceInput, String) {
  result.map_error(
    json.parse(json_string, decode_remove_role_from_db_instance_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_remove_role_from_db_instance_request(
  input: RemoveRoleFromDBInstanceInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=RemoveRoleFromDBInstance&Version=2014-10-31"
  let body = {
    let v = input.db_instance_identifier
    string.concat([
      body,
      string.concat(["&", "DBInstanceIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.role_arn
    string.concat([
      body,
      string.concat(["&", "RoleArn", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.feature_name
    string.concat([
      body,
      string.concat(["&", "FeatureName", "=", uri.encode_component(v)]),
    ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_remove_role_from_db_instance_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(RemoveRoleFromDBInstanceOutput, String) {
  Ok(RemoveRoleFromDBInstanceOutput)
}

pub type RemoveSourceIdentifierFromSubscriptionInput {
  RemoveSourceIdentifierFromSubscriptionInput(
    subscription_name: String,
    source_identifier: String,
  )
}

pub fn remove_source_identifier_from_subscription_input_default(
  subscription_name subscription_name: String,
  source_identifier source_identifier: String,
) -> RemoveSourceIdentifierFromSubscriptionInput {
  RemoveSourceIdentifierFromSubscriptionInput(
    subscription_name: subscription_name,
    source_identifier: source_identifier,
  )
}

pub type RemoveSourceIdentifierFromSubscriptionOutput {
  RemoveSourceIdentifierFromSubscriptionOutput
}

pub fn decode_remove_source_identifier_from_subscription_input_struct() -> decode.Decoder(
  RemoveSourceIdentifierFromSubscriptionInput,
) {
  use <- decode.recursive
  use subscription_name <- decode.field("SubscriptionName", decode.string)
  use source_identifier <- decode.field("SourceIdentifier", decode.string)
  decode.success(RemoveSourceIdentifierFromSubscriptionInput(
    subscription_name: subscription_name,
    source_identifier: source_identifier,
  ))
}

pub fn decode_remove_source_identifier_from_subscription_input(
  json_string: String,
) -> Result(RemoveSourceIdentifierFromSubscriptionInput, String) {
  result.map_error(
    json.parse(
      json_string,
      decode_remove_source_identifier_from_subscription_input_struct(),
    ),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_remove_source_identifier_from_subscription_request(
  input: RemoveSourceIdentifierFromSubscriptionInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=RemoveSourceIdentifierFromSubscription&Version=2014-10-31"
  let body = {
    let v = input.subscription_name
    string.concat([
      body,
      string.concat(["&", "SubscriptionName", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.source_identifier
    string.concat([
      body,
      string.concat(["&", "SourceIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_remove_source_identifier_from_subscription_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(RemoveSourceIdentifierFromSubscriptionOutput, String) {
  Ok(RemoveSourceIdentifierFromSubscriptionOutput)
}

pub type RemoveTagsFromResourceInput {
  RemoveTagsFromResourceInput(resource_name: String, tag_keys: List(String))
}

pub fn remove_tags_from_resource_input_default(
  resource_name resource_name: String,
  tag_keys tag_keys: List(String),
) -> RemoveTagsFromResourceInput {
  RemoveTagsFromResourceInput(resource_name: resource_name, tag_keys: tag_keys)
}

pub type RemoveTagsFromResourceOutput {
  RemoveTagsFromResourceOutput
}

pub fn decode_remove_tags_from_resource_input_struct() -> decode.Decoder(
  RemoveTagsFromResourceInput,
) {
  use <- decode.recursive
  use resource_name <- decode.field("ResourceName", decode.string)
  use tag_keys <- decode.field("TagKeys", decode.list(decode.string))
  decode.success(RemoveTagsFromResourceInput(
    resource_name: resource_name,
    tag_keys: tag_keys,
  ))
}

pub fn decode_remove_tags_from_resource_input(
  json_string: String,
) -> Result(RemoveTagsFromResourceInput, String) {
  result.map_error(
    json.parse(json_string, decode_remove_tags_from_resource_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_remove_tags_from_resource_request(
  input: RemoveTagsFromResourceInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=RemoveTagsFromResource&Version=2014-10-31"
  let body = {
    let v = input.resource_name
    string.concat([
      body,
      string.concat(["&", "ResourceName", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.tag_keys
    string.concat([
      body,
      case v {
        [] -> string.concat(["&", "TagKeys", "=", ""])
        _ ->
          list.index_fold(v, "", fn(acc, item, idx) {
            string.concat([
              acc,
              string.concat([
                "&",
                string.concat(["TagKeys", ".member.", int.to_string(idx + 1)]),
                "=",
                uri.encode_component(item),
              ]),
            ])
          })
      },
    ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_remove_tags_from_resource_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(RemoveTagsFromResourceOutput, String) {
  Ok(RemoveTagsFromResourceOutput)
}

pub type ResetDBClusterParameterGroupInput {
  ResetDBClusterParameterGroupInput(
    db_cluster_parameter_group_name: String,
    reset_all_parameters: option.Option(Bool),
    parameters: option.Option(List(Parameter)),
  )
}

pub fn reset_db_cluster_parameter_group_input_default(
  db_cluster_parameter_group_name db_cluster_parameter_group_name: String,
) -> ResetDBClusterParameterGroupInput {
  ResetDBClusterParameterGroupInput(
    db_cluster_parameter_group_name: db_cluster_parameter_group_name,
    reset_all_parameters: option.None,
    parameters: option.None,
  )
}

pub type ResetDBClusterParameterGroupOutput {
  ResetDBClusterParameterGroupOutput
}

pub fn decode_reset_db_cluster_parameter_group_input_struct() -> decode.Decoder(
  ResetDBClusterParameterGroupInput,
) {
  use <- decode.recursive
  use db_cluster_parameter_group_name <- decode.field(
    "DBClusterParameterGroupName",
    decode.string,
  )
  use reset_all_parameters <- decode.optional_field(
    "ResetAllParameters",
    option.None,
    decode.optional(decode.bool),
  )
  use parameters <- decode.optional_field(
    "Parameters",
    option.None,
    decode.optional(decode.list(decode_parameter_struct_params())),
  )
  decode.success(ResetDBClusterParameterGroupInput(
    db_cluster_parameter_group_name: db_cluster_parameter_group_name,
    reset_all_parameters: reset_all_parameters,
    parameters: parameters,
  ))
}

pub fn decode_reset_db_cluster_parameter_group_input(
  json_string: String,
) -> Result(ResetDBClusterParameterGroupInput, String) {
  result.map_error(
    json.parse(
      json_string,
      decode_reset_db_cluster_parameter_group_input_struct(),
    ),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_reset_db_cluster_parameter_group_request(
  input: ResetDBClusterParameterGroupInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=ResetDBClusterParameterGroup&Version=2014-10-31"
  let body = {
    let v = input.db_cluster_parameter_group_name
    string.concat([
      body,
      string.concat([
        "&",
        "DBClusterParameterGroupName",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body = case input.reset_all_parameters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "ResetAllParameters",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.parameters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Parameters", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_parameter_at(
                  string.concat([
                    "Parameters",
                    ".Parameter.",
                    int.to_string(idx + 1),
                  ]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_reset_db_cluster_parameter_group_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(ResetDBClusterParameterGroupOutput, String) {
  Ok(ResetDBClusterParameterGroupOutput)
}

pub type ResetDBParameterGroupInput {
  ResetDBParameterGroupInput(
    db_parameter_group_name: String,
    reset_all_parameters: option.Option(Bool),
    parameters: option.Option(List(Parameter)),
  )
}

pub fn reset_db_parameter_group_input_default(
  db_parameter_group_name db_parameter_group_name: String,
) -> ResetDBParameterGroupInput {
  ResetDBParameterGroupInput(
    db_parameter_group_name: db_parameter_group_name,
    reset_all_parameters: option.None,
    parameters: option.None,
  )
}

pub type ResetDBParameterGroupOutput {
  ResetDBParameterGroupOutput
}

pub fn decode_reset_db_parameter_group_input_struct() -> decode.Decoder(
  ResetDBParameterGroupInput,
) {
  use <- decode.recursive
  use db_parameter_group_name <- decode.field(
    "DBParameterGroupName",
    decode.string,
  )
  use reset_all_parameters <- decode.optional_field(
    "ResetAllParameters",
    option.None,
    decode.optional(decode.bool),
  )
  use parameters <- decode.optional_field(
    "Parameters",
    option.None,
    decode.optional(decode.list(decode_parameter_struct_params())),
  )
  decode.success(ResetDBParameterGroupInput(
    db_parameter_group_name: db_parameter_group_name,
    reset_all_parameters: reset_all_parameters,
    parameters: parameters,
  ))
}

pub fn decode_reset_db_parameter_group_input(
  json_string: String,
) -> Result(ResetDBParameterGroupInput, String) {
  result.map_error(
    json.parse(json_string, decode_reset_db_parameter_group_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_reset_db_parameter_group_request(
  input: ResetDBParameterGroupInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=ResetDBParameterGroup&Version=2014-10-31"
  let body = {
    let v = input.db_parameter_group_name
    string.concat([
      body,
      string.concat(["&", "DBParameterGroupName", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.reset_all_parameters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "ResetAllParameters",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.parameters {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Parameters", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_parameter_at(
                  string.concat([
                    "Parameters",
                    ".Parameter.",
                    int.to_string(idx + 1),
                  ]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_reset_db_parameter_group_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(ResetDBParameterGroupOutput, String) {
  Ok(ResetDBParameterGroupOutput)
}

pub type RestoreDBClusterFromS3Input {
  RestoreDBClusterFromS3Input(
    availability_zones: option.Option(List(String)),
    backup_retention_period: option.Option(Int),
    character_set_name: option.Option(String),
    database_name: option.Option(String),
    db_cluster_identifier: String,
    db_cluster_parameter_group_name: option.Option(String),
    vpc_security_group_ids: option.Option(List(String)),
    db_subnet_group_name: option.Option(String),
    engine: String,
    engine_version: option.Option(String),
    port: option.Option(Int),
    master_username: String,
    master_user_password: option.Option(String),
    option_group_name: option.Option(String),
    preferred_backup_window: option.Option(String),
    preferred_maintenance_window: option.Option(String),
    tags: option.Option(List(Tag)),
    storage_encrypted: option.Option(Bool),
    kms_key_id: option.Option(String),
    enable_iam_database_authentication: option.Option(Bool),
    source_engine: String,
    source_engine_version: String,
    s3_bucket_name: String,
    s3_prefix: option.Option(String),
    s3_ingestion_role_arn: String,
    backtrack_window: option.Option(Int),
    enable_cloudwatch_logs_exports: option.Option(List(String)),
    deletion_protection: option.Option(Bool),
    copy_tags_to_snapshot: option.Option(Bool),
    domain: option.Option(String),
    domain_iam_role_name: option.Option(String),
    storage_type: option.Option(String),
    network_type: option.Option(String),
    serverless_v2_scaling_configuration: option.Option(
      ServerlessV2ScalingConfiguration,
    ),
    manage_master_user_password: option.Option(Bool),
    master_user_secret_kms_key_id: option.Option(String),
    engine_lifecycle_support: option.Option(String),
    tag_specifications: option.Option(List(TagSpecification)),
  )
}

pub fn restore_db_cluster_from_s3_input_default(
  db_cluster_identifier db_cluster_identifier: String,
  engine engine: String,
  master_username master_username: String,
  source_engine source_engine: String,
  source_engine_version source_engine_version: String,
  s3_bucket_name s3_bucket_name: String,
  s3_ingestion_role_arn s3_ingestion_role_arn: String,
) -> RestoreDBClusterFromS3Input {
  RestoreDBClusterFromS3Input(
    availability_zones: option.None,
    backup_retention_period: option.None,
    character_set_name: option.None,
    database_name: option.None,
    db_cluster_identifier: db_cluster_identifier,
    db_cluster_parameter_group_name: option.None,
    vpc_security_group_ids: option.None,
    db_subnet_group_name: option.None,
    engine: engine,
    engine_version: option.None,
    port: option.None,
    master_username: master_username,
    master_user_password: option.None,
    option_group_name: option.None,
    preferred_backup_window: option.None,
    preferred_maintenance_window: option.None,
    tags: option.None,
    storage_encrypted: option.None,
    kms_key_id: option.None,
    enable_iam_database_authentication: option.None,
    source_engine: source_engine,
    source_engine_version: source_engine_version,
    s3_bucket_name: s3_bucket_name,
    s3_prefix: option.None,
    s3_ingestion_role_arn: s3_ingestion_role_arn,
    backtrack_window: option.None,
    enable_cloudwatch_logs_exports: option.None,
    deletion_protection: option.None,
    copy_tags_to_snapshot: option.None,
    domain: option.None,
    domain_iam_role_name: option.None,
    storage_type: option.None,
    network_type: option.None,
    serverless_v2_scaling_configuration: option.None,
    manage_master_user_password: option.None,
    master_user_secret_kms_key_id: option.None,
    engine_lifecycle_support: option.None,
    tag_specifications: option.None,
  )
}

pub type RestoreDBClusterFromS3Output {
  RestoreDBClusterFromS3Output
}

pub fn decode_restore_db_cluster_from_s3_input_struct() -> decode.Decoder(
  RestoreDBClusterFromS3Input,
) {
  use <- decode.recursive
  use availability_zones <- decode.optional_field(
    "AvailabilityZones",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use backup_retention_period <- decode.optional_field(
    "BackupRetentionPeriod",
    option.None,
    decode.optional(decode.int),
  )
  use character_set_name <- decode.optional_field(
    "CharacterSetName",
    option.None,
    decode.optional(decode.string),
  )
  use database_name <- decode.optional_field(
    "DatabaseName",
    option.None,
    decode.optional(decode.string),
  )
  use db_cluster_identifier <- decode.field(
    "DBClusterIdentifier",
    decode.string,
  )
  use db_cluster_parameter_group_name <- decode.optional_field(
    "DBClusterParameterGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use vpc_security_group_ids <- decode.optional_field(
    "VpcSecurityGroupIds",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use db_subnet_group_name <- decode.optional_field(
    "DBSubnetGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use engine <- decode.field("Engine", decode.string)
  use engine_version <- decode.optional_field(
    "EngineVersion",
    option.None,
    decode.optional(decode.string),
  )
  use port <- decode.optional_field(
    "Port",
    option.None,
    decode.optional(decode.int),
  )
  use master_username <- decode.field("MasterUsername", decode.string)
  use master_user_password <- decode.optional_field(
    "MasterUserPassword",
    option.None,
    decode.optional(decode.string),
  )
  use option_group_name <- decode.optional_field(
    "OptionGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use preferred_backup_window <- decode.optional_field(
    "PreferredBackupWindow",
    option.None,
    decode.optional(decode.string),
  )
  use preferred_maintenance_window <- decode.optional_field(
    "PreferredMaintenanceWindow",
    option.None,
    decode.optional(decode.string),
  )
  use tags <- decode.optional_field(
    "Tags",
    option.None,
    decode.optional(decode.list(decode_tag_struct_params())),
  )
  use storage_encrypted <- decode.optional_field(
    "StorageEncrypted",
    option.None,
    decode.optional(decode.bool),
  )
  use kms_key_id <- decode.optional_field(
    "KmsKeyId",
    option.None,
    decode.optional(decode.string),
  )
  use enable_iam_database_authentication <- decode.optional_field(
    "EnableIAMDatabaseAuthentication",
    option.None,
    decode.optional(decode.bool),
  )
  use source_engine <- decode.field("SourceEngine", decode.string)
  use source_engine_version <- decode.field(
    "SourceEngineVersion",
    decode.string,
  )
  use s3_bucket_name <- decode.field("S3BucketName", decode.string)
  use s3_prefix <- decode.optional_field(
    "S3Prefix",
    option.None,
    decode.optional(decode.string),
  )
  use s3_ingestion_role_arn <- decode.field("S3IngestionRoleArn", decode.string)
  use backtrack_window <- decode.optional_field(
    "BacktrackWindow",
    option.None,
    decode.optional(decode.int),
  )
  use enable_cloudwatch_logs_exports <- decode.optional_field(
    "EnableCloudwatchLogsExports",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use deletion_protection <- decode.optional_field(
    "DeletionProtection",
    option.None,
    decode.optional(decode.bool),
  )
  use copy_tags_to_snapshot <- decode.optional_field(
    "CopyTagsToSnapshot",
    option.None,
    decode.optional(decode.bool),
  )
  use domain <- decode.optional_field(
    "Domain",
    option.None,
    decode.optional(decode.string),
  )
  use domain_iam_role_name <- decode.optional_field(
    "DomainIAMRoleName",
    option.None,
    decode.optional(decode.string),
  )
  use storage_type <- decode.optional_field(
    "StorageType",
    option.None,
    decode.optional(decode.string),
  )
  use network_type <- decode.optional_field(
    "NetworkType",
    option.None,
    decode.optional(decode.string),
  )
  use serverless_v2_scaling_configuration <- decode.optional_field(
    "ServerlessV2ScalingConfiguration",
    option.None,
    decode.optional(decode_serverless_v2_scaling_configuration_struct_params()),
  )
  use manage_master_user_password <- decode.optional_field(
    "ManageMasterUserPassword",
    option.None,
    decode.optional(decode.bool),
  )
  use master_user_secret_kms_key_id <- decode.optional_field(
    "MasterUserSecretKmsKeyId",
    option.None,
    decode.optional(decode.string),
  )
  use engine_lifecycle_support <- decode.optional_field(
    "EngineLifecycleSupport",
    option.None,
    decode.optional(decode.string),
  )
  use tag_specifications <- decode.optional_field(
    "TagSpecifications",
    option.None,
    decode.optional(decode.list(decode_tag_specification_struct_params())),
  )
  decode.success(RestoreDBClusterFromS3Input(
    availability_zones: availability_zones,
    backup_retention_period: backup_retention_period,
    character_set_name: character_set_name,
    database_name: database_name,
    db_cluster_identifier: db_cluster_identifier,
    db_cluster_parameter_group_name: db_cluster_parameter_group_name,
    vpc_security_group_ids: vpc_security_group_ids,
    db_subnet_group_name: db_subnet_group_name,
    engine: engine,
    engine_version: engine_version,
    port: port,
    master_username: master_username,
    master_user_password: master_user_password,
    option_group_name: option_group_name,
    preferred_backup_window: preferred_backup_window,
    preferred_maintenance_window: preferred_maintenance_window,
    tags: tags,
    storage_encrypted: storage_encrypted,
    kms_key_id: kms_key_id,
    enable_iam_database_authentication: enable_iam_database_authentication,
    source_engine: source_engine,
    source_engine_version: source_engine_version,
    s3_bucket_name: s3_bucket_name,
    s3_prefix: s3_prefix,
    s3_ingestion_role_arn: s3_ingestion_role_arn,
    backtrack_window: backtrack_window,
    enable_cloudwatch_logs_exports: enable_cloudwatch_logs_exports,
    deletion_protection: deletion_protection,
    copy_tags_to_snapshot: copy_tags_to_snapshot,
    domain: domain,
    domain_iam_role_name: domain_iam_role_name,
    storage_type: storage_type,
    network_type: network_type,
    serverless_v2_scaling_configuration: serverless_v2_scaling_configuration,
    manage_master_user_password: manage_master_user_password,
    master_user_secret_kms_key_id: master_user_secret_kms_key_id,
    engine_lifecycle_support: engine_lifecycle_support,
    tag_specifications: tag_specifications,
  ))
}

pub fn decode_restore_db_cluster_from_s3_input(
  json_string: String,
) -> Result(RestoreDBClusterFromS3Input, String) {
  result.map_error(
    json.parse(json_string, decode_restore_db_cluster_from_s3_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_restore_db_cluster_from_s3_request(
  input: RestoreDBClusterFromS3Input,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=RestoreDBClusterFromS3&Version=2014-10-31"
  let body = case input.availability_zones {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "AvailabilityZones", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "AvailabilityZones",
                    ".AvailabilityZone.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body = case input.backup_retention_period {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "BackupRetentionPeriod", "=", int.to_string(v)]),
      ])
  }
  let body = case input.character_set_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "CharacterSetName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.database_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DatabaseName", "=", uri.encode_component(v)]),
      ])
  }
  let body = {
    let v = input.db_cluster_identifier
    string.concat([
      body,
      string.concat(["&", "DBClusterIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.db_cluster_parameter_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DBClusterParameterGroupName",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.vpc_security_group_ids {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "VpcSecurityGroupIds", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "VpcSecurityGroupIds",
                    ".VpcSecurityGroupId.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body = case input.db_subnet_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DBSubnetGroupName", "=", uri.encode_component(v)]),
      ])
  }
  let body = {
    let v = input.engine
    string.concat([
      body,
      string.concat(["&", "Engine", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.engine_version {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "EngineVersion", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.port {
    option.None -> body
    option.Some(v) ->
      string.concat([body, string.concat(["&", "Port", "=", int.to_string(v)])])
  }
  let body = {
    let v = input.master_username
    string.concat([
      body,
      string.concat(["&", "MasterUsername", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.master_user_password {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MasterUserPassword", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.option_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "OptionGroupName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.preferred_backup_window {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "PreferredBackupWindow",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.preferred_maintenance_window {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "PreferredMaintenanceWindow",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.tags {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Tags", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_tag_at(
                  string.concat(["Tags", ".Tag.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.storage_encrypted {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "StorageEncrypted",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.kms_key_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "KmsKeyId", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.enable_iam_database_authentication {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EnableIAMDatabaseAuthentication",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = {
    let v = input.source_engine
    string.concat([
      body,
      string.concat(["&", "SourceEngine", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.source_engine_version
    string.concat([
      body,
      string.concat(["&", "SourceEngineVersion", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.s3_bucket_name
    string.concat([
      body,
      string.concat(["&", "S3BucketName", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.s3_prefix {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "S3Prefix", "=", uri.encode_component(v)]),
      ])
  }
  let body = {
    let v = input.s3_ingestion_role_arn
    string.concat([
      body,
      string.concat(["&", "S3IngestionRoleArn", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.backtrack_window {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "BacktrackWindow", "=", int.to_string(v)]),
      ])
  }
  let body = case input.enable_cloudwatch_logs_exports {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "EnableCloudwatchLogsExports", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "EnableCloudwatchLogsExports",
                    ".member.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body = case input.deletion_protection {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DeletionProtection",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.copy_tags_to_snapshot {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "CopyTagsToSnapshot",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.domain {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Domain", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.domain_iam_role_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DomainIAMRoleName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.storage_type {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "StorageType", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.network_type {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "NetworkType", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.serverless_v2_scaling_configuration {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        encode_serverless_v2_scaling_configuration_at(
          "ServerlessV2ScalingConfiguration",
          v,
        ),
      ])
  }
  let body = case input.manage_master_user_password {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "ManageMasterUserPassword",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.master_user_secret_kms_key_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "MasterUserSecretKmsKeyId",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.engine_lifecycle_support {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EngineLifecycleSupport",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.tag_specifications {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "TagSpecifications", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_tag_specification_at(
                  string.concat([
                    "TagSpecifications",
                    ".item.",
                    int.to_string(idx + 1),
                  ]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_restore_db_cluster_from_s3_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(RestoreDBClusterFromS3Output, String) {
  Ok(RestoreDBClusterFromS3Output)
}

pub type RestoreDBClusterFromSnapshotInput {
  RestoreDBClusterFromSnapshotInput(
    availability_zones: option.Option(List(String)),
    db_cluster_identifier: String,
    snapshot_identifier: String,
    engine: String,
    engine_version: option.Option(String),
    port: option.Option(Int),
    db_subnet_group_name: option.Option(String),
    database_name: option.Option(String),
    option_group_name: option.Option(String),
    vpc_security_group_ids: option.Option(List(String)),
    tags: option.Option(List(Tag)),
    kms_key_id: option.Option(String),
    enable_iam_database_authentication: option.Option(Bool),
    backtrack_window: option.Option(Int),
    enable_cloudwatch_logs_exports: option.Option(List(String)),
    engine_mode: option.Option(String),
    scaling_configuration: option.Option(ScalingConfiguration),
    db_cluster_parameter_group_name: option.Option(String),
    deletion_protection: option.Option(Bool),
    copy_tags_to_snapshot: option.Option(Bool),
    domain: option.Option(String),
    domain_iam_role_name: option.Option(String),
    db_cluster_instance_class: option.Option(String),
    storage_type: option.Option(String),
    iops: option.Option(Int),
    publicly_accessible: option.Option(Bool),
    network_type: option.Option(String),
    serverless_v2_scaling_configuration: option.Option(
      ServerlessV2ScalingConfiguration,
    ),
    rds_custom_cluster_configuration: option.Option(
      RdsCustomClusterConfiguration,
    ),
    monitoring_interval: option.Option(Int),
    monitoring_role_arn: option.Option(String),
    enable_performance_insights: option.Option(Bool),
    performance_insights_kms_key_id: option.Option(String),
    performance_insights_retention_period: option.Option(Int),
    backup_retention_period: option.Option(Int),
    preferred_backup_window: option.Option(String),
    engine_lifecycle_support: option.Option(String),
    tag_specifications: option.Option(List(TagSpecification)),
    enable_vpc_networking: option.Option(Bool),
    enable_internet_access_gateway: option.Option(Bool),
  )
}

pub fn restore_db_cluster_from_snapshot_input_default(
  db_cluster_identifier db_cluster_identifier: String,
  snapshot_identifier snapshot_identifier: String,
  engine engine: String,
) -> RestoreDBClusterFromSnapshotInput {
  RestoreDBClusterFromSnapshotInput(
    availability_zones: option.None,
    db_cluster_identifier: db_cluster_identifier,
    snapshot_identifier: snapshot_identifier,
    engine: engine,
    engine_version: option.None,
    port: option.None,
    db_subnet_group_name: option.None,
    database_name: option.None,
    option_group_name: option.None,
    vpc_security_group_ids: option.None,
    tags: option.None,
    kms_key_id: option.None,
    enable_iam_database_authentication: option.None,
    backtrack_window: option.None,
    enable_cloudwatch_logs_exports: option.None,
    engine_mode: option.None,
    scaling_configuration: option.None,
    db_cluster_parameter_group_name: option.None,
    deletion_protection: option.None,
    copy_tags_to_snapshot: option.None,
    domain: option.None,
    domain_iam_role_name: option.None,
    db_cluster_instance_class: option.None,
    storage_type: option.None,
    iops: option.None,
    publicly_accessible: option.None,
    network_type: option.None,
    serverless_v2_scaling_configuration: option.None,
    rds_custom_cluster_configuration: option.None,
    monitoring_interval: option.None,
    monitoring_role_arn: option.None,
    enable_performance_insights: option.None,
    performance_insights_kms_key_id: option.None,
    performance_insights_retention_period: option.None,
    backup_retention_period: option.None,
    preferred_backup_window: option.None,
    engine_lifecycle_support: option.None,
    tag_specifications: option.None,
    enable_vpc_networking: option.None,
    enable_internet_access_gateway: option.None,
  )
}

pub type RestoreDBClusterFromSnapshotOutput {
  RestoreDBClusterFromSnapshotOutput
}

pub fn decode_restore_db_cluster_from_snapshot_input_struct() -> decode.Decoder(
  RestoreDBClusterFromSnapshotInput,
) {
  use <- decode.recursive
  use availability_zones <- decode.optional_field(
    "AvailabilityZones",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use db_cluster_identifier <- decode.field(
    "DBClusterIdentifier",
    decode.string,
  )
  use snapshot_identifier <- decode.field("SnapshotIdentifier", decode.string)
  use engine <- decode.field("Engine", decode.string)
  use engine_version <- decode.optional_field(
    "EngineVersion",
    option.None,
    decode.optional(decode.string),
  )
  use port <- decode.optional_field(
    "Port",
    option.None,
    decode.optional(decode.int),
  )
  use db_subnet_group_name <- decode.optional_field(
    "DBSubnetGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use database_name <- decode.optional_field(
    "DatabaseName",
    option.None,
    decode.optional(decode.string),
  )
  use option_group_name <- decode.optional_field(
    "OptionGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use vpc_security_group_ids <- decode.optional_field(
    "VpcSecurityGroupIds",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use tags <- decode.optional_field(
    "Tags",
    option.None,
    decode.optional(decode.list(decode_tag_struct_params())),
  )
  use kms_key_id <- decode.optional_field(
    "KmsKeyId",
    option.None,
    decode.optional(decode.string),
  )
  use enable_iam_database_authentication <- decode.optional_field(
    "EnableIAMDatabaseAuthentication",
    option.None,
    decode.optional(decode.bool),
  )
  use backtrack_window <- decode.optional_field(
    "BacktrackWindow",
    option.None,
    decode.optional(decode.int),
  )
  use enable_cloudwatch_logs_exports <- decode.optional_field(
    "EnableCloudwatchLogsExports",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use engine_mode <- decode.optional_field(
    "EngineMode",
    option.None,
    decode.optional(decode.string),
  )
  use scaling_configuration <- decode.optional_field(
    "ScalingConfiguration",
    option.None,
    decode.optional(decode_scaling_configuration_struct_params()),
  )
  use db_cluster_parameter_group_name <- decode.optional_field(
    "DBClusterParameterGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use deletion_protection <- decode.optional_field(
    "DeletionProtection",
    option.None,
    decode.optional(decode.bool),
  )
  use copy_tags_to_snapshot <- decode.optional_field(
    "CopyTagsToSnapshot",
    option.None,
    decode.optional(decode.bool),
  )
  use domain <- decode.optional_field(
    "Domain",
    option.None,
    decode.optional(decode.string),
  )
  use domain_iam_role_name <- decode.optional_field(
    "DomainIAMRoleName",
    option.None,
    decode.optional(decode.string),
  )
  use db_cluster_instance_class <- decode.optional_field(
    "DBClusterInstanceClass",
    option.None,
    decode.optional(decode.string),
  )
  use storage_type <- decode.optional_field(
    "StorageType",
    option.None,
    decode.optional(decode.string),
  )
  use iops <- decode.optional_field(
    "Iops",
    option.None,
    decode.optional(decode.int),
  )
  use publicly_accessible <- decode.optional_field(
    "PubliclyAccessible",
    option.None,
    decode.optional(decode.bool),
  )
  use network_type <- decode.optional_field(
    "NetworkType",
    option.None,
    decode.optional(decode.string),
  )
  use serverless_v2_scaling_configuration <- decode.optional_field(
    "ServerlessV2ScalingConfiguration",
    option.None,
    decode.optional(decode_serverless_v2_scaling_configuration_struct_params()),
  )
  use rds_custom_cluster_configuration <- decode.optional_field(
    "RdsCustomClusterConfiguration",
    option.None,
    decode.optional(decode_rds_custom_cluster_configuration_struct_params()),
  )
  use monitoring_interval <- decode.optional_field(
    "MonitoringInterval",
    option.None,
    decode.optional(decode.int),
  )
  use monitoring_role_arn <- decode.optional_field(
    "MonitoringRoleArn",
    option.None,
    decode.optional(decode.string),
  )
  use enable_performance_insights <- decode.optional_field(
    "EnablePerformanceInsights",
    option.None,
    decode.optional(decode.bool),
  )
  use performance_insights_kms_key_id <- decode.optional_field(
    "PerformanceInsightsKMSKeyId",
    option.None,
    decode.optional(decode.string),
  )
  use performance_insights_retention_period <- decode.optional_field(
    "PerformanceInsightsRetentionPeriod",
    option.None,
    decode.optional(decode.int),
  )
  use backup_retention_period <- decode.optional_field(
    "BackupRetentionPeriod",
    option.None,
    decode.optional(decode.int),
  )
  use preferred_backup_window <- decode.optional_field(
    "PreferredBackupWindow",
    option.None,
    decode.optional(decode.string),
  )
  use engine_lifecycle_support <- decode.optional_field(
    "EngineLifecycleSupport",
    option.None,
    decode.optional(decode.string),
  )
  use tag_specifications <- decode.optional_field(
    "TagSpecifications",
    option.None,
    decode.optional(decode.list(decode_tag_specification_struct_params())),
  )
  use enable_vpc_networking <- decode.optional_field(
    "EnableVPCNetworking",
    option.None,
    decode.optional(decode.bool),
  )
  use enable_internet_access_gateway <- decode.optional_field(
    "EnableInternetAccessGateway",
    option.None,
    decode.optional(decode.bool),
  )
  decode.success(RestoreDBClusterFromSnapshotInput(
    availability_zones: availability_zones,
    db_cluster_identifier: db_cluster_identifier,
    snapshot_identifier: snapshot_identifier,
    engine: engine,
    engine_version: engine_version,
    port: port,
    db_subnet_group_name: db_subnet_group_name,
    database_name: database_name,
    option_group_name: option_group_name,
    vpc_security_group_ids: vpc_security_group_ids,
    tags: tags,
    kms_key_id: kms_key_id,
    enable_iam_database_authentication: enable_iam_database_authentication,
    backtrack_window: backtrack_window,
    enable_cloudwatch_logs_exports: enable_cloudwatch_logs_exports,
    engine_mode: engine_mode,
    scaling_configuration: scaling_configuration,
    db_cluster_parameter_group_name: db_cluster_parameter_group_name,
    deletion_protection: deletion_protection,
    copy_tags_to_snapshot: copy_tags_to_snapshot,
    domain: domain,
    domain_iam_role_name: domain_iam_role_name,
    db_cluster_instance_class: db_cluster_instance_class,
    storage_type: storage_type,
    iops: iops,
    publicly_accessible: publicly_accessible,
    network_type: network_type,
    serverless_v2_scaling_configuration: serverless_v2_scaling_configuration,
    rds_custom_cluster_configuration: rds_custom_cluster_configuration,
    monitoring_interval: monitoring_interval,
    monitoring_role_arn: monitoring_role_arn,
    enable_performance_insights: enable_performance_insights,
    performance_insights_kms_key_id: performance_insights_kms_key_id,
    performance_insights_retention_period: performance_insights_retention_period,
    backup_retention_period: backup_retention_period,
    preferred_backup_window: preferred_backup_window,
    engine_lifecycle_support: engine_lifecycle_support,
    tag_specifications: tag_specifications,
    enable_vpc_networking: enable_vpc_networking,
    enable_internet_access_gateway: enable_internet_access_gateway,
  ))
}

pub fn decode_restore_db_cluster_from_snapshot_input(
  json_string: String,
) -> Result(RestoreDBClusterFromSnapshotInput, String) {
  result.map_error(
    json.parse(
      json_string,
      decode_restore_db_cluster_from_snapshot_input_struct(),
    ),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_restore_db_cluster_from_snapshot_request(
  input: RestoreDBClusterFromSnapshotInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=RestoreDBClusterFromSnapshot&Version=2014-10-31"
  let body = case input.availability_zones {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "AvailabilityZones", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "AvailabilityZones",
                    ".AvailabilityZone.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body = {
    let v = input.db_cluster_identifier
    string.concat([
      body,
      string.concat(["&", "DBClusterIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.snapshot_identifier
    string.concat([
      body,
      string.concat(["&", "SnapshotIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.engine
    string.concat([
      body,
      string.concat(["&", "Engine", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.engine_version {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "EngineVersion", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.port {
    option.None -> body
    option.Some(v) ->
      string.concat([body, string.concat(["&", "Port", "=", int.to_string(v)])])
  }
  let body = case input.db_subnet_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DBSubnetGroupName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.database_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DatabaseName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.option_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "OptionGroupName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.vpc_security_group_ids {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "VpcSecurityGroupIds", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "VpcSecurityGroupIds",
                    ".VpcSecurityGroupId.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body = case input.tags {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Tags", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_tag_at(
                  string.concat(["Tags", ".Tag.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.kms_key_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "KmsKeyId", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.enable_iam_database_authentication {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EnableIAMDatabaseAuthentication",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.backtrack_window {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "BacktrackWindow", "=", int.to_string(v)]),
      ])
  }
  let body = case input.enable_cloudwatch_logs_exports {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "EnableCloudwatchLogsExports", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "EnableCloudwatchLogsExports",
                    ".member.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body = case input.engine_mode {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "EngineMode", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.scaling_configuration {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        encode_scaling_configuration_at("ScalingConfiguration", v),
      ])
  }
  let body = case input.db_cluster_parameter_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DBClusterParameterGroupName",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.deletion_protection {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DeletionProtection",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.copy_tags_to_snapshot {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "CopyTagsToSnapshot",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.domain {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Domain", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.domain_iam_role_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DomainIAMRoleName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.db_cluster_instance_class {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DBClusterInstanceClass",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.storage_type {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "StorageType", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.iops {
    option.None -> body
    option.Some(v) ->
      string.concat([body, string.concat(["&", "Iops", "=", int.to_string(v)])])
  }
  let body = case input.publicly_accessible {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "PubliclyAccessible",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.network_type {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "NetworkType", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.serverless_v2_scaling_configuration {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        encode_serverless_v2_scaling_configuration_at(
          "ServerlessV2ScalingConfiguration",
          v,
        ),
      ])
  }
  let body = case input.rds_custom_cluster_configuration {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        encode_rds_custom_cluster_configuration_at(
          "RdsCustomClusterConfiguration",
          v,
        ),
      ])
  }
  let body = case input.monitoring_interval {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MonitoringInterval", "=", int.to_string(v)]),
      ])
  }
  let body = case input.monitoring_role_arn {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MonitoringRoleArn", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.enable_performance_insights {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EnablePerformanceInsights",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.performance_insights_kms_key_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "PerformanceInsightsKMSKeyId",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.performance_insights_retention_period {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "PerformanceInsightsRetentionPeriod",
          "=",
          int.to_string(v),
        ]),
      ])
  }
  let body = case input.backup_retention_period {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "BackupRetentionPeriod", "=", int.to_string(v)]),
      ])
  }
  let body = case input.preferred_backup_window {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "PreferredBackupWindow",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.engine_lifecycle_support {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EngineLifecycleSupport",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.tag_specifications {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "TagSpecifications", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_tag_specification_at(
                  string.concat([
                    "TagSpecifications",
                    ".item.",
                    int.to_string(idx + 1),
                  ]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.enable_vpc_networking {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EnableVPCNetworking",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.enable_internet_access_gateway {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EnableInternetAccessGateway",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_restore_db_cluster_from_snapshot_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(RestoreDBClusterFromSnapshotOutput, String) {
  Ok(RestoreDBClusterFromSnapshotOutput)
}

pub type RestoreDBClusterToPointInTimeInput {
  RestoreDBClusterToPointInTimeInput(
    db_cluster_identifier: String,
    restore_type: option.Option(String),
    source_db_cluster_identifier: option.Option(String),
    restore_to_time: option.Option(json_timestamp.Timestamp),
    use_latest_restorable_time: option.Option(Bool),
    port: option.Option(Int),
    db_subnet_group_name: option.Option(String),
    option_group_name: option.Option(String),
    vpc_security_group_ids: option.Option(List(String)),
    tags: option.Option(List(Tag)),
    kms_key_id: option.Option(String),
    enable_iam_database_authentication: option.Option(Bool),
    backtrack_window: option.Option(Int),
    enable_cloudwatch_logs_exports: option.Option(List(String)),
    db_cluster_parameter_group_name: option.Option(String),
    deletion_protection: option.Option(Bool),
    copy_tags_to_snapshot: option.Option(Bool),
    domain: option.Option(String),
    domain_iam_role_name: option.Option(String),
    db_cluster_instance_class: option.Option(String),
    storage_type: option.Option(String),
    publicly_accessible: option.Option(Bool),
    iops: option.Option(Int),
    network_type: option.Option(String),
    source_db_cluster_resource_id: option.Option(String),
    serverless_v2_scaling_configuration: option.Option(
      ServerlessV2ScalingConfiguration,
    ),
    scaling_configuration: option.Option(ScalingConfiguration),
    engine_mode: option.Option(String),
    rds_custom_cluster_configuration: option.Option(
      RdsCustomClusterConfiguration,
    ),
    monitoring_interval: option.Option(Int),
    monitoring_role_arn: option.Option(String),
    enable_performance_insights: option.Option(Bool),
    performance_insights_kms_key_id: option.Option(String),
    performance_insights_retention_period: option.Option(Int),
    backup_retention_period: option.Option(Int),
    preferred_backup_window: option.Option(String),
    engine_lifecycle_support: option.Option(String),
    tag_specifications: option.Option(List(TagSpecification)),
    enable_vpc_networking: option.Option(Bool),
    enable_internet_access_gateway: option.Option(Bool),
  )
}

pub fn restore_db_cluster_to_point_in_time_input_default(
  db_cluster_identifier db_cluster_identifier: String,
) -> RestoreDBClusterToPointInTimeInput {
  RestoreDBClusterToPointInTimeInput(
    db_cluster_identifier: db_cluster_identifier,
    restore_type: option.None,
    source_db_cluster_identifier: option.None,
    restore_to_time: option.None,
    use_latest_restorable_time: option.None,
    port: option.None,
    db_subnet_group_name: option.None,
    option_group_name: option.None,
    vpc_security_group_ids: option.None,
    tags: option.None,
    kms_key_id: option.None,
    enable_iam_database_authentication: option.None,
    backtrack_window: option.None,
    enable_cloudwatch_logs_exports: option.None,
    db_cluster_parameter_group_name: option.None,
    deletion_protection: option.None,
    copy_tags_to_snapshot: option.None,
    domain: option.None,
    domain_iam_role_name: option.None,
    db_cluster_instance_class: option.None,
    storage_type: option.None,
    publicly_accessible: option.None,
    iops: option.None,
    network_type: option.None,
    source_db_cluster_resource_id: option.None,
    serverless_v2_scaling_configuration: option.None,
    scaling_configuration: option.None,
    engine_mode: option.None,
    rds_custom_cluster_configuration: option.None,
    monitoring_interval: option.None,
    monitoring_role_arn: option.None,
    enable_performance_insights: option.None,
    performance_insights_kms_key_id: option.None,
    performance_insights_retention_period: option.None,
    backup_retention_period: option.None,
    preferred_backup_window: option.None,
    engine_lifecycle_support: option.None,
    tag_specifications: option.None,
    enable_vpc_networking: option.None,
    enable_internet_access_gateway: option.None,
  )
}

pub type RestoreDBClusterToPointInTimeOutput {
  RestoreDBClusterToPointInTimeOutput
}

pub fn decode_restore_db_cluster_to_point_in_time_input_struct() -> decode.Decoder(
  RestoreDBClusterToPointInTimeInput,
) {
  use <- decode.recursive
  use db_cluster_identifier <- decode.field(
    "DBClusterIdentifier",
    decode.string,
  )
  use restore_type <- decode.optional_field(
    "RestoreType",
    option.None,
    decode.optional(decode.string),
  )
  use source_db_cluster_identifier <- decode.optional_field(
    "SourceDBClusterIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use restore_to_time <- decode.optional_field(
    "RestoreToTime",
    option.None,
    decode.optional(json_timestamp.decoder_precise()),
  )
  use use_latest_restorable_time <- decode.optional_field(
    "UseLatestRestorableTime",
    option.None,
    decode.optional(decode.bool),
  )
  use port <- decode.optional_field(
    "Port",
    option.None,
    decode.optional(decode.int),
  )
  use db_subnet_group_name <- decode.optional_field(
    "DBSubnetGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use option_group_name <- decode.optional_field(
    "OptionGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use vpc_security_group_ids <- decode.optional_field(
    "VpcSecurityGroupIds",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use tags <- decode.optional_field(
    "Tags",
    option.None,
    decode.optional(decode.list(decode_tag_struct_params())),
  )
  use kms_key_id <- decode.optional_field(
    "KmsKeyId",
    option.None,
    decode.optional(decode.string),
  )
  use enable_iam_database_authentication <- decode.optional_field(
    "EnableIAMDatabaseAuthentication",
    option.None,
    decode.optional(decode.bool),
  )
  use backtrack_window <- decode.optional_field(
    "BacktrackWindow",
    option.None,
    decode.optional(decode.int),
  )
  use enable_cloudwatch_logs_exports <- decode.optional_field(
    "EnableCloudwatchLogsExports",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use db_cluster_parameter_group_name <- decode.optional_field(
    "DBClusterParameterGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use deletion_protection <- decode.optional_field(
    "DeletionProtection",
    option.None,
    decode.optional(decode.bool),
  )
  use copy_tags_to_snapshot <- decode.optional_field(
    "CopyTagsToSnapshot",
    option.None,
    decode.optional(decode.bool),
  )
  use domain <- decode.optional_field(
    "Domain",
    option.None,
    decode.optional(decode.string),
  )
  use domain_iam_role_name <- decode.optional_field(
    "DomainIAMRoleName",
    option.None,
    decode.optional(decode.string),
  )
  use db_cluster_instance_class <- decode.optional_field(
    "DBClusterInstanceClass",
    option.None,
    decode.optional(decode.string),
  )
  use storage_type <- decode.optional_field(
    "StorageType",
    option.None,
    decode.optional(decode.string),
  )
  use publicly_accessible <- decode.optional_field(
    "PubliclyAccessible",
    option.None,
    decode.optional(decode.bool),
  )
  use iops <- decode.optional_field(
    "Iops",
    option.None,
    decode.optional(decode.int),
  )
  use network_type <- decode.optional_field(
    "NetworkType",
    option.None,
    decode.optional(decode.string),
  )
  use source_db_cluster_resource_id <- decode.optional_field(
    "SourceDbClusterResourceId",
    option.None,
    decode.optional(decode.string),
  )
  use serverless_v2_scaling_configuration <- decode.optional_field(
    "ServerlessV2ScalingConfiguration",
    option.None,
    decode.optional(decode_serverless_v2_scaling_configuration_struct_params()),
  )
  use scaling_configuration <- decode.optional_field(
    "ScalingConfiguration",
    option.None,
    decode.optional(decode_scaling_configuration_struct_params()),
  )
  use engine_mode <- decode.optional_field(
    "EngineMode",
    option.None,
    decode.optional(decode.string),
  )
  use rds_custom_cluster_configuration <- decode.optional_field(
    "RdsCustomClusterConfiguration",
    option.None,
    decode.optional(decode_rds_custom_cluster_configuration_struct_params()),
  )
  use monitoring_interval <- decode.optional_field(
    "MonitoringInterval",
    option.None,
    decode.optional(decode.int),
  )
  use monitoring_role_arn <- decode.optional_field(
    "MonitoringRoleArn",
    option.None,
    decode.optional(decode.string),
  )
  use enable_performance_insights <- decode.optional_field(
    "EnablePerformanceInsights",
    option.None,
    decode.optional(decode.bool),
  )
  use performance_insights_kms_key_id <- decode.optional_field(
    "PerformanceInsightsKMSKeyId",
    option.None,
    decode.optional(decode.string),
  )
  use performance_insights_retention_period <- decode.optional_field(
    "PerformanceInsightsRetentionPeriod",
    option.None,
    decode.optional(decode.int),
  )
  use backup_retention_period <- decode.optional_field(
    "BackupRetentionPeriod",
    option.None,
    decode.optional(decode.int),
  )
  use preferred_backup_window <- decode.optional_field(
    "PreferredBackupWindow",
    option.None,
    decode.optional(decode.string),
  )
  use engine_lifecycle_support <- decode.optional_field(
    "EngineLifecycleSupport",
    option.None,
    decode.optional(decode.string),
  )
  use tag_specifications <- decode.optional_field(
    "TagSpecifications",
    option.None,
    decode.optional(decode.list(decode_tag_specification_struct_params())),
  )
  use enable_vpc_networking <- decode.optional_field(
    "EnableVPCNetworking",
    option.None,
    decode.optional(decode.bool),
  )
  use enable_internet_access_gateway <- decode.optional_field(
    "EnableInternetAccessGateway",
    option.None,
    decode.optional(decode.bool),
  )
  decode.success(RestoreDBClusterToPointInTimeInput(
    db_cluster_identifier: db_cluster_identifier,
    restore_type: restore_type,
    source_db_cluster_identifier: source_db_cluster_identifier,
    restore_to_time: restore_to_time,
    use_latest_restorable_time: use_latest_restorable_time,
    port: port,
    db_subnet_group_name: db_subnet_group_name,
    option_group_name: option_group_name,
    vpc_security_group_ids: vpc_security_group_ids,
    tags: tags,
    kms_key_id: kms_key_id,
    enable_iam_database_authentication: enable_iam_database_authentication,
    backtrack_window: backtrack_window,
    enable_cloudwatch_logs_exports: enable_cloudwatch_logs_exports,
    db_cluster_parameter_group_name: db_cluster_parameter_group_name,
    deletion_protection: deletion_protection,
    copy_tags_to_snapshot: copy_tags_to_snapshot,
    domain: domain,
    domain_iam_role_name: domain_iam_role_name,
    db_cluster_instance_class: db_cluster_instance_class,
    storage_type: storage_type,
    publicly_accessible: publicly_accessible,
    iops: iops,
    network_type: network_type,
    source_db_cluster_resource_id: source_db_cluster_resource_id,
    serverless_v2_scaling_configuration: serverless_v2_scaling_configuration,
    scaling_configuration: scaling_configuration,
    engine_mode: engine_mode,
    rds_custom_cluster_configuration: rds_custom_cluster_configuration,
    monitoring_interval: monitoring_interval,
    monitoring_role_arn: monitoring_role_arn,
    enable_performance_insights: enable_performance_insights,
    performance_insights_kms_key_id: performance_insights_kms_key_id,
    performance_insights_retention_period: performance_insights_retention_period,
    backup_retention_period: backup_retention_period,
    preferred_backup_window: preferred_backup_window,
    engine_lifecycle_support: engine_lifecycle_support,
    tag_specifications: tag_specifications,
    enable_vpc_networking: enable_vpc_networking,
    enable_internet_access_gateway: enable_internet_access_gateway,
  ))
}

pub fn decode_restore_db_cluster_to_point_in_time_input(
  json_string: String,
) -> Result(RestoreDBClusterToPointInTimeInput, String) {
  result.map_error(
    json.parse(
      json_string,
      decode_restore_db_cluster_to_point_in_time_input_struct(),
    ),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_restore_db_cluster_to_point_in_time_request(
  input: RestoreDBClusterToPointInTimeInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=RestoreDBClusterToPointInTime&Version=2014-10-31"
  let body = {
    let v = input.db_cluster_identifier
    string.concat([
      body,
      string.concat(["&", "DBClusterIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.restore_type {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "RestoreType", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.source_db_cluster_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "SourceDBClusterIdentifier",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.restore_to_time {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "RestoreToTime",
          "=",
          uri.encode_component(json_timestamp.format_iso8601_precise(v)),
        ]),
      ])
  }
  let body = case input.use_latest_restorable_time {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "UseLatestRestorableTime",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.port {
    option.None -> body
    option.Some(v) ->
      string.concat([body, string.concat(["&", "Port", "=", int.to_string(v)])])
  }
  let body = case input.db_subnet_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DBSubnetGroupName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.option_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "OptionGroupName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.vpc_security_group_ids {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "VpcSecurityGroupIds", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "VpcSecurityGroupIds",
                    ".VpcSecurityGroupId.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body = case input.tags {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Tags", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_tag_at(
                  string.concat(["Tags", ".Tag.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.kms_key_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "KmsKeyId", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.enable_iam_database_authentication {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EnableIAMDatabaseAuthentication",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.backtrack_window {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "BacktrackWindow", "=", int.to_string(v)]),
      ])
  }
  let body = case input.enable_cloudwatch_logs_exports {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "EnableCloudwatchLogsExports", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "EnableCloudwatchLogsExports",
                    ".member.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body = case input.db_cluster_parameter_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DBClusterParameterGroupName",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.deletion_protection {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DeletionProtection",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.copy_tags_to_snapshot {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "CopyTagsToSnapshot",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.domain {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Domain", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.domain_iam_role_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DomainIAMRoleName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.db_cluster_instance_class {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DBClusterInstanceClass",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.storage_type {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "StorageType", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.publicly_accessible {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "PubliclyAccessible",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.iops {
    option.None -> body
    option.Some(v) ->
      string.concat([body, string.concat(["&", "Iops", "=", int.to_string(v)])])
  }
  let body = case input.network_type {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "NetworkType", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.source_db_cluster_resource_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "SourceDbClusterResourceId",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.serverless_v2_scaling_configuration {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        encode_serverless_v2_scaling_configuration_at(
          "ServerlessV2ScalingConfiguration",
          v,
        ),
      ])
  }
  let body = case input.scaling_configuration {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        encode_scaling_configuration_at("ScalingConfiguration", v),
      ])
  }
  let body = case input.engine_mode {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "EngineMode", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.rds_custom_cluster_configuration {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        encode_rds_custom_cluster_configuration_at(
          "RdsCustomClusterConfiguration",
          v,
        ),
      ])
  }
  let body = case input.monitoring_interval {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MonitoringInterval", "=", int.to_string(v)]),
      ])
  }
  let body = case input.monitoring_role_arn {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MonitoringRoleArn", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.enable_performance_insights {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EnablePerformanceInsights",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.performance_insights_kms_key_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "PerformanceInsightsKMSKeyId",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.performance_insights_retention_period {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "PerformanceInsightsRetentionPeriod",
          "=",
          int.to_string(v),
        ]),
      ])
  }
  let body = case input.backup_retention_period {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "BackupRetentionPeriod", "=", int.to_string(v)]),
      ])
  }
  let body = case input.preferred_backup_window {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "PreferredBackupWindow",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.engine_lifecycle_support {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EngineLifecycleSupport",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.tag_specifications {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "TagSpecifications", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_tag_specification_at(
                  string.concat([
                    "TagSpecifications",
                    ".item.",
                    int.to_string(idx + 1),
                  ]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.enable_vpc_networking {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EnableVPCNetworking",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.enable_internet_access_gateway {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EnableInternetAccessGateway",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_restore_db_cluster_to_point_in_time_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(RestoreDBClusterToPointInTimeOutput, String) {
  Ok(RestoreDBClusterToPointInTimeOutput)
}

pub type RestoreDBInstanceFromDBSnapshotInput {
  RestoreDBInstanceFromDBSnapshotInput(
    db_instance_identifier: String,
    db_snapshot_identifier: option.Option(String),
    db_instance_class: option.Option(String),
    port: option.Option(Int),
    availability_zone: option.Option(String),
    db_subnet_group_name: option.Option(String),
    multi_az: option.Option(Bool),
    publicly_accessible: option.Option(Bool),
    auto_minor_version_upgrade: option.Option(Bool),
    license_model: option.Option(String),
    db_name: option.Option(String),
    engine: option.Option(String),
    iops: option.Option(Int),
    storage_throughput: option.Option(Int),
    option_group_name: option.Option(String),
    tags: option.Option(List(Tag)),
    storage_type: option.Option(String),
    tde_credential_arn: option.Option(String),
    tde_credential_password: option.Option(String),
    vpc_security_group_ids: option.Option(List(String)),
    domain: option.Option(String),
    domain_fqdn: option.Option(String),
    domain_ou: option.Option(String),
    domain_auth_secret_arn: option.Option(String),
    domain_dns_ips: option.Option(List(String)),
    copy_tags_to_snapshot: option.Option(Bool),
    domain_iam_role_name: option.Option(String),
    enable_iam_database_authentication: option.Option(Bool),
    enable_cloudwatch_logs_exports: option.Option(List(String)),
    processor_features: option.Option(List(ProcessorFeature)),
    use_default_processor_features: option.Option(Bool),
    db_parameter_group_name: option.Option(String),
    deletion_protection: option.Option(Bool),
    enable_customer_owned_ip: option.Option(Bool),
    network_type: option.Option(String),
    backup_target: option.Option(String),
    custom_iam_instance_profile: option.Option(String),
    allocated_storage: option.Option(Int),
    db_cluster_snapshot_identifier: option.Option(String),
    backup_retention_period: option.Option(Int),
    preferred_backup_window: option.Option(String),
    dedicated_log_volume: option.Option(Bool),
    ca_certificate_identifier: option.Option(String),
    engine_lifecycle_support: option.Option(String),
    additional_storage_volumes: option.Option(List(AdditionalStorageVolume)),
    tag_specifications: option.Option(List(TagSpecification)),
    manage_master_user_password: option.Option(Bool),
    master_user_secret_kms_key_id: option.Option(String),
  )
}

pub fn restore_db_instance_from_db_snapshot_input_default(
  db_instance_identifier db_instance_identifier: String,
) -> RestoreDBInstanceFromDBSnapshotInput {
  RestoreDBInstanceFromDBSnapshotInput(
    db_instance_identifier: db_instance_identifier,
    db_snapshot_identifier: option.None,
    db_instance_class: option.None,
    port: option.None,
    availability_zone: option.None,
    db_subnet_group_name: option.None,
    multi_az: option.None,
    publicly_accessible: option.None,
    auto_minor_version_upgrade: option.None,
    license_model: option.None,
    db_name: option.None,
    engine: option.None,
    iops: option.None,
    storage_throughput: option.None,
    option_group_name: option.None,
    tags: option.None,
    storage_type: option.None,
    tde_credential_arn: option.None,
    tde_credential_password: option.None,
    vpc_security_group_ids: option.None,
    domain: option.None,
    domain_fqdn: option.None,
    domain_ou: option.None,
    domain_auth_secret_arn: option.None,
    domain_dns_ips: option.None,
    copy_tags_to_snapshot: option.None,
    domain_iam_role_name: option.None,
    enable_iam_database_authentication: option.None,
    enable_cloudwatch_logs_exports: option.None,
    processor_features: option.None,
    use_default_processor_features: option.None,
    db_parameter_group_name: option.None,
    deletion_protection: option.None,
    enable_customer_owned_ip: option.None,
    network_type: option.None,
    backup_target: option.None,
    custom_iam_instance_profile: option.None,
    allocated_storage: option.None,
    db_cluster_snapshot_identifier: option.None,
    backup_retention_period: option.None,
    preferred_backup_window: option.None,
    dedicated_log_volume: option.None,
    ca_certificate_identifier: option.None,
    engine_lifecycle_support: option.None,
    additional_storage_volumes: option.None,
    tag_specifications: option.None,
    manage_master_user_password: option.None,
    master_user_secret_kms_key_id: option.None,
  )
}

pub type RestoreDBInstanceFromDBSnapshotOutput {
  RestoreDBInstanceFromDBSnapshotOutput
}

pub fn decode_restore_db_instance_from_db_snapshot_input_struct() -> decode.Decoder(
  RestoreDBInstanceFromDBSnapshotInput,
) {
  use <- decode.recursive
  use db_instance_identifier <- decode.field(
    "DBInstanceIdentifier",
    decode.string,
  )
  use db_snapshot_identifier <- decode.optional_field(
    "DBSnapshotIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use db_instance_class <- decode.optional_field(
    "DBInstanceClass",
    option.None,
    decode.optional(decode.string),
  )
  use port <- decode.optional_field(
    "Port",
    option.None,
    decode.optional(decode.int),
  )
  use availability_zone <- decode.optional_field(
    "AvailabilityZone",
    option.None,
    decode.optional(decode.string),
  )
  use db_subnet_group_name <- decode.optional_field(
    "DBSubnetGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use multi_az <- decode.optional_field(
    "MultiAZ",
    option.None,
    decode.optional(decode.bool),
  )
  use publicly_accessible <- decode.optional_field(
    "PubliclyAccessible",
    option.None,
    decode.optional(decode.bool),
  )
  use auto_minor_version_upgrade <- decode.optional_field(
    "AutoMinorVersionUpgrade",
    option.None,
    decode.optional(decode.bool),
  )
  use license_model <- decode.optional_field(
    "LicenseModel",
    option.None,
    decode.optional(decode.string),
  )
  use db_name <- decode.optional_field(
    "DBName",
    option.None,
    decode.optional(decode.string),
  )
  use engine <- decode.optional_field(
    "Engine",
    option.None,
    decode.optional(decode.string),
  )
  use iops <- decode.optional_field(
    "Iops",
    option.None,
    decode.optional(decode.int),
  )
  use storage_throughput <- decode.optional_field(
    "StorageThroughput",
    option.None,
    decode.optional(decode.int),
  )
  use option_group_name <- decode.optional_field(
    "OptionGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use tags <- decode.optional_field(
    "Tags",
    option.None,
    decode.optional(decode.list(decode_tag_struct_params())),
  )
  use storage_type <- decode.optional_field(
    "StorageType",
    option.None,
    decode.optional(decode.string),
  )
  use tde_credential_arn <- decode.optional_field(
    "TdeCredentialArn",
    option.None,
    decode.optional(decode.string),
  )
  use tde_credential_password <- decode.optional_field(
    "TdeCredentialPassword",
    option.None,
    decode.optional(decode.string),
  )
  use vpc_security_group_ids <- decode.optional_field(
    "VpcSecurityGroupIds",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use domain <- decode.optional_field(
    "Domain",
    option.None,
    decode.optional(decode.string),
  )
  use domain_fqdn <- decode.optional_field(
    "DomainFqdn",
    option.None,
    decode.optional(decode.string),
  )
  use domain_ou <- decode.optional_field(
    "DomainOu",
    option.None,
    decode.optional(decode.string),
  )
  use domain_auth_secret_arn <- decode.optional_field(
    "DomainAuthSecretArn",
    option.None,
    decode.optional(decode.string),
  )
  use domain_dns_ips <- decode.optional_field(
    "DomainDnsIps",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use copy_tags_to_snapshot <- decode.optional_field(
    "CopyTagsToSnapshot",
    option.None,
    decode.optional(decode.bool),
  )
  use domain_iam_role_name <- decode.optional_field(
    "DomainIAMRoleName",
    option.None,
    decode.optional(decode.string),
  )
  use enable_iam_database_authentication <- decode.optional_field(
    "EnableIAMDatabaseAuthentication",
    option.None,
    decode.optional(decode.bool),
  )
  use enable_cloudwatch_logs_exports <- decode.optional_field(
    "EnableCloudwatchLogsExports",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use processor_features <- decode.optional_field(
    "ProcessorFeatures",
    option.None,
    decode.optional(decode.list(decode_processor_feature_struct_params())),
  )
  use use_default_processor_features <- decode.optional_field(
    "UseDefaultProcessorFeatures",
    option.None,
    decode.optional(decode.bool),
  )
  use db_parameter_group_name <- decode.optional_field(
    "DBParameterGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use deletion_protection <- decode.optional_field(
    "DeletionProtection",
    option.None,
    decode.optional(decode.bool),
  )
  use enable_customer_owned_ip <- decode.optional_field(
    "EnableCustomerOwnedIp",
    option.None,
    decode.optional(decode.bool),
  )
  use network_type <- decode.optional_field(
    "NetworkType",
    option.None,
    decode.optional(decode.string),
  )
  use backup_target <- decode.optional_field(
    "BackupTarget",
    option.None,
    decode.optional(decode.string),
  )
  use custom_iam_instance_profile <- decode.optional_field(
    "CustomIamInstanceProfile",
    option.None,
    decode.optional(decode.string),
  )
  use allocated_storage <- decode.optional_field(
    "AllocatedStorage",
    option.None,
    decode.optional(decode.int),
  )
  use db_cluster_snapshot_identifier <- decode.optional_field(
    "DBClusterSnapshotIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use backup_retention_period <- decode.optional_field(
    "BackupRetentionPeriod",
    option.None,
    decode.optional(decode.int),
  )
  use preferred_backup_window <- decode.optional_field(
    "PreferredBackupWindow",
    option.None,
    decode.optional(decode.string),
  )
  use dedicated_log_volume <- decode.optional_field(
    "DedicatedLogVolume",
    option.None,
    decode.optional(decode.bool),
  )
  use ca_certificate_identifier <- decode.optional_field(
    "CACertificateIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use engine_lifecycle_support <- decode.optional_field(
    "EngineLifecycleSupport",
    option.None,
    decode.optional(decode.string),
  )
  use additional_storage_volumes <- decode.optional_field(
    "AdditionalStorageVolumes",
    option.None,
    decode.optional(
      decode.list(decode_additional_storage_volume_struct_params()),
    ),
  )
  use tag_specifications <- decode.optional_field(
    "TagSpecifications",
    option.None,
    decode.optional(decode.list(decode_tag_specification_struct_params())),
  )
  use manage_master_user_password <- decode.optional_field(
    "ManageMasterUserPassword",
    option.None,
    decode.optional(decode.bool),
  )
  use master_user_secret_kms_key_id <- decode.optional_field(
    "MasterUserSecretKmsKeyId",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(RestoreDBInstanceFromDBSnapshotInput(
    db_instance_identifier: db_instance_identifier,
    db_snapshot_identifier: db_snapshot_identifier,
    db_instance_class: db_instance_class,
    port: port,
    availability_zone: availability_zone,
    db_subnet_group_name: db_subnet_group_name,
    multi_az: multi_az,
    publicly_accessible: publicly_accessible,
    auto_minor_version_upgrade: auto_minor_version_upgrade,
    license_model: license_model,
    db_name: db_name,
    engine: engine,
    iops: iops,
    storage_throughput: storage_throughput,
    option_group_name: option_group_name,
    tags: tags,
    storage_type: storage_type,
    tde_credential_arn: tde_credential_arn,
    tde_credential_password: tde_credential_password,
    vpc_security_group_ids: vpc_security_group_ids,
    domain: domain,
    domain_fqdn: domain_fqdn,
    domain_ou: domain_ou,
    domain_auth_secret_arn: domain_auth_secret_arn,
    domain_dns_ips: domain_dns_ips,
    copy_tags_to_snapshot: copy_tags_to_snapshot,
    domain_iam_role_name: domain_iam_role_name,
    enable_iam_database_authentication: enable_iam_database_authentication,
    enable_cloudwatch_logs_exports: enable_cloudwatch_logs_exports,
    processor_features: processor_features,
    use_default_processor_features: use_default_processor_features,
    db_parameter_group_name: db_parameter_group_name,
    deletion_protection: deletion_protection,
    enable_customer_owned_ip: enable_customer_owned_ip,
    network_type: network_type,
    backup_target: backup_target,
    custom_iam_instance_profile: custom_iam_instance_profile,
    allocated_storage: allocated_storage,
    db_cluster_snapshot_identifier: db_cluster_snapshot_identifier,
    backup_retention_period: backup_retention_period,
    preferred_backup_window: preferred_backup_window,
    dedicated_log_volume: dedicated_log_volume,
    ca_certificate_identifier: ca_certificate_identifier,
    engine_lifecycle_support: engine_lifecycle_support,
    additional_storage_volumes: additional_storage_volumes,
    tag_specifications: tag_specifications,
    manage_master_user_password: manage_master_user_password,
    master_user_secret_kms_key_id: master_user_secret_kms_key_id,
  ))
}

pub fn decode_restore_db_instance_from_db_snapshot_input(
  json_string: String,
) -> Result(RestoreDBInstanceFromDBSnapshotInput, String) {
  result.map_error(
    json.parse(
      json_string,
      decode_restore_db_instance_from_db_snapshot_input_struct(),
    ),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_restore_db_instance_from_db_snapshot_request(
  input: RestoreDBInstanceFromDBSnapshotInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=RestoreDBInstanceFromDBSnapshot&Version=2014-10-31"
  let body = {
    let v = input.db_instance_identifier
    string.concat([
      body,
      string.concat(["&", "DBInstanceIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.db_snapshot_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DBSnapshotIdentifier",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.db_instance_class {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DBInstanceClass", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.port {
    option.None -> body
    option.Some(v) ->
      string.concat([body, string.concat(["&", "Port", "=", int.to_string(v)])])
  }
  let body = case input.availability_zone {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "AvailabilityZone", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.db_subnet_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DBSubnetGroupName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.multi_az {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "MultiAZ",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.publicly_accessible {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "PubliclyAccessible",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.auto_minor_version_upgrade {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "AutoMinorVersionUpgrade",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.license_model {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "LicenseModel", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.db_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DBName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.engine {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Engine", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.iops {
    option.None -> body
    option.Some(v) ->
      string.concat([body, string.concat(["&", "Iops", "=", int.to_string(v)])])
  }
  let body = case input.storage_throughput {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "StorageThroughput", "=", int.to_string(v)]),
      ])
  }
  let body = case input.option_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "OptionGroupName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.tags {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Tags", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_tag_at(
                  string.concat(["Tags", ".Tag.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.storage_type {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "StorageType", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.tde_credential_arn {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "TdeCredentialArn", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.tde_credential_password {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "TdeCredentialPassword",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.vpc_security_group_ids {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "VpcSecurityGroupIds", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "VpcSecurityGroupIds",
                    ".VpcSecurityGroupId.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body = case input.domain {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Domain", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.domain_fqdn {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DomainFqdn", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.domain_ou {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DomainOu", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.domain_auth_secret_arn {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DomainAuthSecretArn", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.domain_dns_ips {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "DomainDnsIps", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "DomainDnsIps",
                    ".member.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body = case input.copy_tags_to_snapshot {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "CopyTagsToSnapshot",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.domain_iam_role_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DomainIAMRoleName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.enable_iam_database_authentication {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EnableIAMDatabaseAuthentication",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.enable_cloudwatch_logs_exports {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "EnableCloudwatchLogsExports", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "EnableCloudwatchLogsExports",
                    ".member.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body = case input.processor_features {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "ProcessorFeatures", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_processor_feature_at(
                  string.concat([
                    "ProcessorFeatures",
                    ".ProcessorFeature.",
                    int.to_string(idx + 1),
                  ]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.use_default_processor_features {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "UseDefaultProcessorFeatures",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.db_parameter_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DBParameterGroupName",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.deletion_protection {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DeletionProtection",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.enable_customer_owned_ip {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EnableCustomerOwnedIp",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.network_type {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "NetworkType", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.backup_target {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "BackupTarget", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.custom_iam_instance_profile {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "CustomIamInstanceProfile",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.allocated_storage {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "AllocatedStorage", "=", int.to_string(v)]),
      ])
  }
  let body = case input.db_cluster_snapshot_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DBClusterSnapshotIdentifier",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.backup_retention_period {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "BackupRetentionPeriod", "=", int.to_string(v)]),
      ])
  }
  let body = case input.preferred_backup_window {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "PreferredBackupWindow",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.dedicated_log_volume {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DedicatedLogVolume",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.ca_certificate_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "CACertificateIdentifier",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.engine_lifecycle_support {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EngineLifecycleSupport",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.additional_storage_volumes {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "AdditionalStorageVolumes", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_additional_storage_volume_at(
                  string.concat([
                    "AdditionalStorageVolumes",
                    ".member.",
                    int.to_string(idx + 1),
                  ]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.tag_specifications {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "TagSpecifications", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_tag_specification_at(
                  string.concat([
                    "TagSpecifications",
                    ".item.",
                    int.to_string(idx + 1),
                  ]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.manage_master_user_password {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "ManageMasterUserPassword",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.master_user_secret_kms_key_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "MasterUserSecretKmsKeyId",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_restore_db_instance_from_db_snapshot_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(RestoreDBInstanceFromDBSnapshotOutput, String) {
  Ok(RestoreDBInstanceFromDBSnapshotOutput)
}

pub type RestoreDBInstanceFromS3Input {
  RestoreDBInstanceFromS3Input(
    db_name: option.Option(String),
    db_instance_identifier: String,
    allocated_storage: option.Option(Int),
    db_instance_class: String,
    engine: String,
    master_username: option.Option(String),
    master_user_password: option.Option(String),
    db_security_groups: option.Option(List(String)),
    vpc_security_group_ids: option.Option(List(String)),
    availability_zone: option.Option(String),
    db_subnet_group_name: option.Option(String),
    preferred_maintenance_window: option.Option(String),
    db_parameter_group_name: option.Option(String),
    backup_retention_period: option.Option(Int),
    preferred_backup_window: option.Option(String),
    port: option.Option(Int),
    multi_az: option.Option(Bool),
    engine_version: option.Option(String),
    auto_minor_version_upgrade: option.Option(Bool),
    license_model: option.Option(String),
    iops: option.Option(Int),
    storage_throughput: option.Option(Int),
    option_group_name: option.Option(String),
    publicly_accessible: option.Option(Bool),
    tags: option.Option(List(Tag)),
    storage_type: option.Option(String),
    storage_encrypted: option.Option(Bool),
    kms_key_id: option.Option(String),
    copy_tags_to_snapshot: option.Option(Bool),
    monitoring_interval: option.Option(Int),
    monitoring_role_arn: option.Option(String),
    enable_iam_database_authentication: option.Option(Bool),
    source_engine: String,
    source_engine_version: String,
    s3_bucket_name: String,
    s3_prefix: option.Option(String),
    s3_ingestion_role_arn: String,
    database_insights_mode: option.Option(DatabaseInsightsMode),
    enable_performance_insights: option.Option(Bool),
    performance_insights_kms_key_id: option.Option(String),
    performance_insights_retention_period: option.Option(Int),
    enable_cloudwatch_logs_exports: option.Option(List(String)),
    processor_features: option.Option(List(ProcessorFeature)),
    use_default_processor_features: option.Option(Bool),
    deletion_protection: option.Option(Bool),
    max_allocated_storage: option.Option(Int),
    network_type: option.Option(String),
    manage_master_user_password: option.Option(Bool),
    master_user_secret_kms_key_id: option.Option(String),
    dedicated_log_volume: option.Option(Bool),
    ca_certificate_identifier: option.Option(String),
    engine_lifecycle_support: option.Option(String),
    additional_storage_volumes: option.Option(List(AdditionalStorageVolume)),
    tag_specifications: option.Option(List(TagSpecification)),
  )
}

pub fn restore_db_instance_from_s3_input_default(
  db_instance_identifier db_instance_identifier: String,
  db_instance_class db_instance_class: String,
  engine engine: String,
  source_engine source_engine: String,
  source_engine_version source_engine_version: String,
  s3_bucket_name s3_bucket_name: String,
  s3_ingestion_role_arn s3_ingestion_role_arn: String,
) -> RestoreDBInstanceFromS3Input {
  RestoreDBInstanceFromS3Input(
    db_name: option.None,
    db_instance_identifier: db_instance_identifier,
    allocated_storage: option.None,
    db_instance_class: db_instance_class,
    engine: engine,
    master_username: option.None,
    master_user_password: option.None,
    db_security_groups: option.None,
    vpc_security_group_ids: option.None,
    availability_zone: option.None,
    db_subnet_group_name: option.None,
    preferred_maintenance_window: option.None,
    db_parameter_group_name: option.None,
    backup_retention_period: option.None,
    preferred_backup_window: option.None,
    port: option.None,
    multi_az: option.None,
    engine_version: option.None,
    auto_minor_version_upgrade: option.None,
    license_model: option.None,
    iops: option.None,
    storage_throughput: option.None,
    option_group_name: option.None,
    publicly_accessible: option.None,
    tags: option.None,
    storage_type: option.None,
    storage_encrypted: option.None,
    kms_key_id: option.None,
    copy_tags_to_snapshot: option.None,
    monitoring_interval: option.None,
    monitoring_role_arn: option.None,
    enable_iam_database_authentication: option.None,
    source_engine: source_engine,
    source_engine_version: source_engine_version,
    s3_bucket_name: s3_bucket_name,
    s3_prefix: option.None,
    s3_ingestion_role_arn: s3_ingestion_role_arn,
    database_insights_mode: option.None,
    enable_performance_insights: option.None,
    performance_insights_kms_key_id: option.None,
    performance_insights_retention_period: option.None,
    enable_cloudwatch_logs_exports: option.None,
    processor_features: option.None,
    use_default_processor_features: option.None,
    deletion_protection: option.None,
    max_allocated_storage: option.None,
    network_type: option.None,
    manage_master_user_password: option.None,
    master_user_secret_kms_key_id: option.None,
    dedicated_log_volume: option.None,
    ca_certificate_identifier: option.None,
    engine_lifecycle_support: option.None,
    additional_storage_volumes: option.None,
    tag_specifications: option.None,
  )
}

pub type RestoreDBInstanceFromS3Output {
  RestoreDBInstanceFromS3Output
}

pub fn decode_restore_db_instance_from_s3_input_struct() -> decode.Decoder(
  RestoreDBInstanceFromS3Input,
) {
  use <- decode.recursive
  use db_name <- decode.optional_field(
    "DBName",
    option.None,
    decode.optional(decode.string),
  )
  use db_instance_identifier <- decode.field(
    "DBInstanceIdentifier",
    decode.string,
  )
  use allocated_storage <- decode.optional_field(
    "AllocatedStorage",
    option.None,
    decode.optional(decode.int),
  )
  use db_instance_class <- decode.field("DBInstanceClass", decode.string)
  use engine <- decode.field("Engine", decode.string)
  use master_username <- decode.optional_field(
    "MasterUsername",
    option.None,
    decode.optional(decode.string),
  )
  use master_user_password <- decode.optional_field(
    "MasterUserPassword",
    option.None,
    decode.optional(decode.string),
  )
  use db_security_groups <- decode.optional_field(
    "DBSecurityGroups",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use vpc_security_group_ids <- decode.optional_field(
    "VpcSecurityGroupIds",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use availability_zone <- decode.optional_field(
    "AvailabilityZone",
    option.None,
    decode.optional(decode.string),
  )
  use db_subnet_group_name <- decode.optional_field(
    "DBSubnetGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use preferred_maintenance_window <- decode.optional_field(
    "PreferredMaintenanceWindow",
    option.None,
    decode.optional(decode.string),
  )
  use db_parameter_group_name <- decode.optional_field(
    "DBParameterGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use backup_retention_period <- decode.optional_field(
    "BackupRetentionPeriod",
    option.None,
    decode.optional(decode.int),
  )
  use preferred_backup_window <- decode.optional_field(
    "PreferredBackupWindow",
    option.None,
    decode.optional(decode.string),
  )
  use port <- decode.optional_field(
    "Port",
    option.None,
    decode.optional(decode.int),
  )
  use multi_az <- decode.optional_field(
    "MultiAZ",
    option.None,
    decode.optional(decode.bool),
  )
  use engine_version <- decode.optional_field(
    "EngineVersion",
    option.None,
    decode.optional(decode.string),
  )
  use auto_minor_version_upgrade <- decode.optional_field(
    "AutoMinorVersionUpgrade",
    option.None,
    decode.optional(decode.bool),
  )
  use license_model <- decode.optional_field(
    "LicenseModel",
    option.None,
    decode.optional(decode.string),
  )
  use iops <- decode.optional_field(
    "Iops",
    option.None,
    decode.optional(decode.int),
  )
  use storage_throughput <- decode.optional_field(
    "StorageThroughput",
    option.None,
    decode.optional(decode.int),
  )
  use option_group_name <- decode.optional_field(
    "OptionGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use publicly_accessible <- decode.optional_field(
    "PubliclyAccessible",
    option.None,
    decode.optional(decode.bool),
  )
  use tags <- decode.optional_field(
    "Tags",
    option.None,
    decode.optional(decode.list(decode_tag_struct_params())),
  )
  use storage_type <- decode.optional_field(
    "StorageType",
    option.None,
    decode.optional(decode.string),
  )
  use storage_encrypted <- decode.optional_field(
    "StorageEncrypted",
    option.None,
    decode.optional(decode.bool),
  )
  use kms_key_id <- decode.optional_field(
    "KmsKeyId",
    option.None,
    decode.optional(decode.string),
  )
  use copy_tags_to_snapshot <- decode.optional_field(
    "CopyTagsToSnapshot",
    option.None,
    decode.optional(decode.bool),
  )
  use monitoring_interval <- decode.optional_field(
    "MonitoringInterval",
    option.None,
    decode.optional(decode.int),
  )
  use monitoring_role_arn <- decode.optional_field(
    "MonitoringRoleArn",
    option.None,
    decode.optional(decode.string),
  )
  use enable_iam_database_authentication <- decode.optional_field(
    "EnableIAMDatabaseAuthentication",
    option.None,
    decode.optional(decode.bool),
  )
  use source_engine <- decode.field("SourceEngine", decode.string)
  use source_engine_version <- decode.field(
    "SourceEngineVersion",
    decode.string,
  )
  use s3_bucket_name <- decode.field("S3BucketName", decode.string)
  use s3_prefix <- decode.optional_field(
    "S3Prefix",
    option.None,
    decode.optional(decode.string),
  )
  use s3_ingestion_role_arn <- decode.field("S3IngestionRoleArn", decode.string)
  use database_insights_mode <- decode.optional_field(
    "DatabaseInsightsMode",
    option.None,
    decode.optional(decode_database_insights_mode_enum()),
  )
  use enable_performance_insights <- decode.optional_field(
    "EnablePerformanceInsights",
    option.None,
    decode.optional(decode.bool),
  )
  use performance_insights_kms_key_id <- decode.optional_field(
    "PerformanceInsightsKMSKeyId",
    option.None,
    decode.optional(decode.string),
  )
  use performance_insights_retention_period <- decode.optional_field(
    "PerformanceInsightsRetentionPeriod",
    option.None,
    decode.optional(decode.int),
  )
  use enable_cloudwatch_logs_exports <- decode.optional_field(
    "EnableCloudwatchLogsExports",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use processor_features <- decode.optional_field(
    "ProcessorFeatures",
    option.None,
    decode.optional(decode.list(decode_processor_feature_struct_params())),
  )
  use use_default_processor_features <- decode.optional_field(
    "UseDefaultProcessorFeatures",
    option.None,
    decode.optional(decode.bool),
  )
  use deletion_protection <- decode.optional_field(
    "DeletionProtection",
    option.None,
    decode.optional(decode.bool),
  )
  use max_allocated_storage <- decode.optional_field(
    "MaxAllocatedStorage",
    option.None,
    decode.optional(decode.int),
  )
  use network_type <- decode.optional_field(
    "NetworkType",
    option.None,
    decode.optional(decode.string),
  )
  use manage_master_user_password <- decode.optional_field(
    "ManageMasterUserPassword",
    option.None,
    decode.optional(decode.bool),
  )
  use master_user_secret_kms_key_id <- decode.optional_field(
    "MasterUserSecretKmsKeyId",
    option.None,
    decode.optional(decode.string),
  )
  use dedicated_log_volume <- decode.optional_field(
    "DedicatedLogVolume",
    option.None,
    decode.optional(decode.bool),
  )
  use ca_certificate_identifier <- decode.optional_field(
    "CACertificateIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use engine_lifecycle_support <- decode.optional_field(
    "EngineLifecycleSupport",
    option.None,
    decode.optional(decode.string),
  )
  use additional_storage_volumes <- decode.optional_field(
    "AdditionalStorageVolumes",
    option.None,
    decode.optional(
      decode.list(decode_additional_storage_volume_struct_params()),
    ),
  )
  use tag_specifications <- decode.optional_field(
    "TagSpecifications",
    option.None,
    decode.optional(decode.list(decode_tag_specification_struct_params())),
  )
  decode.success(RestoreDBInstanceFromS3Input(
    db_name: db_name,
    db_instance_identifier: db_instance_identifier,
    allocated_storage: allocated_storage,
    db_instance_class: db_instance_class,
    engine: engine,
    master_username: master_username,
    master_user_password: master_user_password,
    db_security_groups: db_security_groups,
    vpc_security_group_ids: vpc_security_group_ids,
    availability_zone: availability_zone,
    db_subnet_group_name: db_subnet_group_name,
    preferred_maintenance_window: preferred_maintenance_window,
    db_parameter_group_name: db_parameter_group_name,
    backup_retention_period: backup_retention_period,
    preferred_backup_window: preferred_backup_window,
    port: port,
    multi_az: multi_az,
    engine_version: engine_version,
    auto_minor_version_upgrade: auto_minor_version_upgrade,
    license_model: license_model,
    iops: iops,
    storage_throughput: storage_throughput,
    option_group_name: option_group_name,
    publicly_accessible: publicly_accessible,
    tags: tags,
    storage_type: storage_type,
    storage_encrypted: storage_encrypted,
    kms_key_id: kms_key_id,
    copy_tags_to_snapshot: copy_tags_to_snapshot,
    monitoring_interval: monitoring_interval,
    monitoring_role_arn: monitoring_role_arn,
    enable_iam_database_authentication: enable_iam_database_authentication,
    source_engine: source_engine,
    source_engine_version: source_engine_version,
    s3_bucket_name: s3_bucket_name,
    s3_prefix: s3_prefix,
    s3_ingestion_role_arn: s3_ingestion_role_arn,
    database_insights_mode: database_insights_mode,
    enable_performance_insights: enable_performance_insights,
    performance_insights_kms_key_id: performance_insights_kms_key_id,
    performance_insights_retention_period: performance_insights_retention_period,
    enable_cloudwatch_logs_exports: enable_cloudwatch_logs_exports,
    processor_features: processor_features,
    use_default_processor_features: use_default_processor_features,
    deletion_protection: deletion_protection,
    max_allocated_storage: max_allocated_storage,
    network_type: network_type,
    manage_master_user_password: manage_master_user_password,
    master_user_secret_kms_key_id: master_user_secret_kms_key_id,
    dedicated_log_volume: dedicated_log_volume,
    ca_certificate_identifier: ca_certificate_identifier,
    engine_lifecycle_support: engine_lifecycle_support,
    additional_storage_volumes: additional_storage_volumes,
    tag_specifications: tag_specifications,
  ))
}

pub fn decode_restore_db_instance_from_s3_input(
  json_string: String,
) -> Result(RestoreDBInstanceFromS3Input, String) {
  result.map_error(
    json.parse(json_string, decode_restore_db_instance_from_s3_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_restore_db_instance_from_s3_request(
  input: RestoreDBInstanceFromS3Input,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=RestoreDBInstanceFromS3&Version=2014-10-31"
  let body = case input.db_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DBName", "=", uri.encode_component(v)]),
      ])
  }
  let body = {
    let v = input.db_instance_identifier
    string.concat([
      body,
      string.concat(["&", "DBInstanceIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.allocated_storage {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "AllocatedStorage", "=", int.to_string(v)]),
      ])
  }
  let body = {
    let v = input.db_instance_class
    string.concat([
      body,
      string.concat(["&", "DBInstanceClass", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.engine
    string.concat([
      body,
      string.concat(["&", "Engine", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.master_username {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MasterUsername", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.master_user_password {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MasterUserPassword", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.db_security_groups {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "DBSecurityGroups", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "DBSecurityGroups",
                    ".DBSecurityGroupName.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body = case input.vpc_security_group_ids {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "VpcSecurityGroupIds", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "VpcSecurityGroupIds",
                    ".VpcSecurityGroupId.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body = case input.availability_zone {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "AvailabilityZone", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.db_subnet_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DBSubnetGroupName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.preferred_maintenance_window {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "PreferredMaintenanceWindow",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.db_parameter_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DBParameterGroupName",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.backup_retention_period {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "BackupRetentionPeriod", "=", int.to_string(v)]),
      ])
  }
  let body = case input.preferred_backup_window {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "PreferredBackupWindow",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.port {
    option.None -> body
    option.Some(v) ->
      string.concat([body, string.concat(["&", "Port", "=", int.to_string(v)])])
  }
  let body = case input.multi_az {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "MultiAZ",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.engine_version {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "EngineVersion", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.auto_minor_version_upgrade {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "AutoMinorVersionUpgrade",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.license_model {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "LicenseModel", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.iops {
    option.None -> body
    option.Some(v) ->
      string.concat([body, string.concat(["&", "Iops", "=", int.to_string(v)])])
  }
  let body = case input.storage_throughput {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "StorageThroughput", "=", int.to_string(v)]),
      ])
  }
  let body = case input.option_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "OptionGroupName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.publicly_accessible {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "PubliclyAccessible",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.tags {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Tags", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_tag_at(
                  string.concat(["Tags", ".Tag.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.storage_type {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "StorageType", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.storage_encrypted {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "StorageEncrypted",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.kms_key_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "KmsKeyId", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.copy_tags_to_snapshot {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "CopyTagsToSnapshot",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.monitoring_interval {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MonitoringInterval", "=", int.to_string(v)]),
      ])
  }
  let body = case input.monitoring_role_arn {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MonitoringRoleArn", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.enable_iam_database_authentication {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EnableIAMDatabaseAuthentication",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = {
    let v = input.source_engine
    string.concat([
      body,
      string.concat(["&", "SourceEngine", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.source_engine_version
    string.concat([
      body,
      string.concat(["&", "SourceEngineVersion", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.s3_bucket_name
    string.concat([
      body,
      string.concat(["&", "S3BucketName", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.s3_prefix {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "S3Prefix", "=", uri.encode_component(v)]),
      ])
  }
  let body = {
    let v = input.s3_ingestion_role_arn
    string.concat([
      body,
      string.concat(["&", "S3IngestionRoleArn", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.database_insights_mode {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DatabaseInsightsMode",
          "=",
          uri.encode_component(database_insights_mode_to_wire(v)),
        ]),
      ])
  }
  let body = case input.enable_performance_insights {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EnablePerformanceInsights",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.performance_insights_kms_key_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "PerformanceInsightsKMSKeyId",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.performance_insights_retention_period {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "PerformanceInsightsRetentionPeriod",
          "=",
          int.to_string(v),
        ]),
      ])
  }
  let body = case input.enable_cloudwatch_logs_exports {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "EnableCloudwatchLogsExports", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "EnableCloudwatchLogsExports",
                    ".member.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body = case input.processor_features {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "ProcessorFeatures", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_processor_feature_at(
                  string.concat([
                    "ProcessorFeatures",
                    ".ProcessorFeature.",
                    int.to_string(idx + 1),
                  ]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.use_default_processor_features {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "UseDefaultProcessorFeatures",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.deletion_protection {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DeletionProtection",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.max_allocated_storage {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxAllocatedStorage", "=", int.to_string(v)]),
      ])
  }
  let body = case input.network_type {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "NetworkType", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.manage_master_user_password {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "ManageMasterUserPassword",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.master_user_secret_kms_key_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "MasterUserSecretKmsKeyId",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.dedicated_log_volume {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DedicatedLogVolume",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.ca_certificate_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "CACertificateIdentifier",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.engine_lifecycle_support {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EngineLifecycleSupport",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.additional_storage_volumes {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "AdditionalStorageVolumes", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_additional_storage_volume_at(
                  string.concat([
                    "AdditionalStorageVolumes",
                    ".member.",
                    int.to_string(idx + 1),
                  ]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.tag_specifications {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "TagSpecifications", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_tag_specification_at(
                  string.concat([
                    "TagSpecifications",
                    ".item.",
                    int.to_string(idx + 1),
                  ]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_restore_db_instance_from_s3_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(RestoreDBInstanceFromS3Output, String) {
  Ok(RestoreDBInstanceFromS3Output)
}

pub type RestoreDBInstanceToPointInTimeInput {
  RestoreDBInstanceToPointInTimeInput(
    source_db_instance_identifier: option.Option(String),
    target_db_instance_identifier: String,
    restore_time: option.Option(json_timestamp.Timestamp),
    use_latest_restorable_time: option.Option(Bool),
    db_instance_class: option.Option(String),
    port: option.Option(Int),
    availability_zone: option.Option(String),
    db_subnet_group_name: option.Option(String),
    multi_az: option.Option(Bool),
    publicly_accessible: option.Option(Bool),
    auto_minor_version_upgrade: option.Option(Bool),
    license_model: option.Option(String),
    db_name: option.Option(String),
    engine: option.Option(String),
    iops: option.Option(Int),
    storage_throughput: option.Option(Int),
    option_group_name: option.Option(String),
    copy_tags_to_snapshot: option.Option(Bool),
    tags: option.Option(List(Tag)),
    storage_type: option.Option(String),
    tde_credential_arn: option.Option(String),
    tde_credential_password: option.Option(String),
    vpc_security_group_ids: option.Option(List(String)),
    domain: option.Option(String),
    domain_iam_role_name: option.Option(String),
    domain_fqdn: option.Option(String),
    domain_ou: option.Option(String),
    domain_auth_secret_arn: option.Option(String),
    domain_dns_ips: option.Option(List(String)),
    enable_iam_database_authentication: option.Option(Bool),
    enable_cloudwatch_logs_exports: option.Option(List(String)),
    processor_features: option.Option(List(ProcessorFeature)),
    use_default_processor_features: option.Option(Bool),
    db_parameter_group_name: option.Option(String),
    deletion_protection: option.Option(Bool),
    source_dbi_resource_id: option.Option(String),
    max_allocated_storage: option.Option(Int),
    enable_customer_owned_ip: option.Option(Bool),
    network_type: option.Option(String),
    source_db_instance_automated_backups_arn: option.Option(String),
    backup_target: option.Option(String),
    custom_iam_instance_profile: option.Option(String),
    allocated_storage: option.Option(Int),
    backup_retention_period: option.Option(Int),
    preferred_backup_window: option.Option(String),
    dedicated_log_volume: option.Option(Bool),
    ca_certificate_identifier: option.Option(String),
    engine_lifecycle_support: option.Option(String),
    additional_storage_volumes: option.Option(List(AdditionalStorageVolume)),
    tag_specifications: option.Option(List(TagSpecification)),
    manage_master_user_password: option.Option(Bool),
    master_user_secret_kms_key_id: option.Option(String),
  )
}

pub fn restore_db_instance_to_point_in_time_input_default(
  target_db_instance_identifier target_db_instance_identifier: String,
) -> RestoreDBInstanceToPointInTimeInput {
  RestoreDBInstanceToPointInTimeInput(
    source_db_instance_identifier: option.None,
    target_db_instance_identifier: target_db_instance_identifier,
    restore_time: option.None,
    use_latest_restorable_time: option.None,
    db_instance_class: option.None,
    port: option.None,
    availability_zone: option.None,
    db_subnet_group_name: option.None,
    multi_az: option.None,
    publicly_accessible: option.None,
    auto_minor_version_upgrade: option.None,
    license_model: option.None,
    db_name: option.None,
    engine: option.None,
    iops: option.None,
    storage_throughput: option.None,
    option_group_name: option.None,
    copy_tags_to_snapshot: option.None,
    tags: option.None,
    storage_type: option.None,
    tde_credential_arn: option.None,
    tde_credential_password: option.None,
    vpc_security_group_ids: option.None,
    domain: option.None,
    domain_iam_role_name: option.None,
    domain_fqdn: option.None,
    domain_ou: option.None,
    domain_auth_secret_arn: option.None,
    domain_dns_ips: option.None,
    enable_iam_database_authentication: option.None,
    enable_cloudwatch_logs_exports: option.None,
    processor_features: option.None,
    use_default_processor_features: option.None,
    db_parameter_group_name: option.None,
    deletion_protection: option.None,
    source_dbi_resource_id: option.None,
    max_allocated_storage: option.None,
    enable_customer_owned_ip: option.None,
    network_type: option.None,
    source_db_instance_automated_backups_arn: option.None,
    backup_target: option.None,
    custom_iam_instance_profile: option.None,
    allocated_storage: option.None,
    backup_retention_period: option.None,
    preferred_backup_window: option.None,
    dedicated_log_volume: option.None,
    ca_certificate_identifier: option.None,
    engine_lifecycle_support: option.None,
    additional_storage_volumes: option.None,
    tag_specifications: option.None,
    manage_master_user_password: option.None,
    master_user_secret_kms_key_id: option.None,
  )
}

pub type RestoreDBInstanceToPointInTimeOutput {
  RestoreDBInstanceToPointInTimeOutput
}

pub fn decode_restore_db_instance_to_point_in_time_input_struct() -> decode.Decoder(
  RestoreDBInstanceToPointInTimeInput,
) {
  use <- decode.recursive
  use source_db_instance_identifier <- decode.optional_field(
    "SourceDBInstanceIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use target_db_instance_identifier <- decode.field(
    "TargetDBInstanceIdentifier",
    decode.string,
  )
  use restore_time <- decode.optional_field(
    "RestoreTime",
    option.None,
    decode.optional(json_timestamp.decoder_precise()),
  )
  use use_latest_restorable_time <- decode.optional_field(
    "UseLatestRestorableTime",
    option.None,
    decode.optional(decode.bool),
  )
  use db_instance_class <- decode.optional_field(
    "DBInstanceClass",
    option.None,
    decode.optional(decode.string),
  )
  use port <- decode.optional_field(
    "Port",
    option.None,
    decode.optional(decode.int),
  )
  use availability_zone <- decode.optional_field(
    "AvailabilityZone",
    option.None,
    decode.optional(decode.string),
  )
  use db_subnet_group_name <- decode.optional_field(
    "DBSubnetGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use multi_az <- decode.optional_field(
    "MultiAZ",
    option.None,
    decode.optional(decode.bool),
  )
  use publicly_accessible <- decode.optional_field(
    "PubliclyAccessible",
    option.None,
    decode.optional(decode.bool),
  )
  use auto_minor_version_upgrade <- decode.optional_field(
    "AutoMinorVersionUpgrade",
    option.None,
    decode.optional(decode.bool),
  )
  use license_model <- decode.optional_field(
    "LicenseModel",
    option.None,
    decode.optional(decode.string),
  )
  use db_name <- decode.optional_field(
    "DBName",
    option.None,
    decode.optional(decode.string),
  )
  use engine <- decode.optional_field(
    "Engine",
    option.None,
    decode.optional(decode.string),
  )
  use iops <- decode.optional_field(
    "Iops",
    option.None,
    decode.optional(decode.int),
  )
  use storage_throughput <- decode.optional_field(
    "StorageThroughput",
    option.None,
    decode.optional(decode.int),
  )
  use option_group_name <- decode.optional_field(
    "OptionGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use copy_tags_to_snapshot <- decode.optional_field(
    "CopyTagsToSnapshot",
    option.None,
    decode.optional(decode.bool),
  )
  use tags <- decode.optional_field(
    "Tags",
    option.None,
    decode.optional(decode.list(decode_tag_struct_params())),
  )
  use storage_type <- decode.optional_field(
    "StorageType",
    option.None,
    decode.optional(decode.string),
  )
  use tde_credential_arn <- decode.optional_field(
    "TdeCredentialArn",
    option.None,
    decode.optional(decode.string),
  )
  use tde_credential_password <- decode.optional_field(
    "TdeCredentialPassword",
    option.None,
    decode.optional(decode.string),
  )
  use vpc_security_group_ids <- decode.optional_field(
    "VpcSecurityGroupIds",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use domain <- decode.optional_field(
    "Domain",
    option.None,
    decode.optional(decode.string),
  )
  use domain_iam_role_name <- decode.optional_field(
    "DomainIAMRoleName",
    option.None,
    decode.optional(decode.string),
  )
  use domain_fqdn <- decode.optional_field(
    "DomainFqdn",
    option.None,
    decode.optional(decode.string),
  )
  use domain_ou <- decode.optional_field(
    "DomainOu",
    option.None,
    decode.optional(decode.string),
  )
  use domain_auth_secret_arn <- decode.optional_field(
    "DomainAuthSecretArn",
    option.None,
    decode.optional(decode.string),
  )
  use domain_dns_ips <- decode.optional_field(
    "DomainDnsIps",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use enable_iam_database_authentication <- decode.optional_field(
    "EnableIAMDatabaseAuthentication",
    option.None,
    decode.optional(decode.bool),
  )
  use enable_cloudwatch_logs_exports <- decode.optional_field(
    "EnableCloudwatchLogsExports",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  use processor_features <- decode.optional_field(
    "ProcessorFeatures",
    option.None,
    decode.optional(decode.list(decode_processor_feature_struct_params())),
  )
  use use_default_processor_features <- decode.optional_field(
    "UseDefaultProcessorFeatures",
    option.None,
    decode.optional(decode.bool),
  )
  use db_parameter_group_name <- decode.optional_field(
    "DBParameterGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use deletion_protection <- decode.optional_field(
    "DeletionProtection",
    option.None,
    decode.optional(decode.bool),
  )
  use source_dbi_resource_id <- decode.optional_field(
    "SourceDbiResourceId",
    option.None,
    decode.optional(decode.string),
  )
  use max_allocated_storage <- decode.optional_field(
    "MaxAllocatedStorage",
    option.None,
    decode.optional(decode.int),
  )
  use enable_customer_owned_ip <- decode.optional_field(
    "EnableCustomerOwnedIp",
    option.None,
    decode.optional(decode.bool),
  )
  use network_type <- decode.optional_field(
    "NetworkType",
    option.None,
    decode.optional(decode.string),
  )
  use source_db_instance_automated_backups_arn <- decode.optional_field(
    "SourceDBInstanceAutomatedBackupsArn",
    option.None,
    decode.optional(decode.string),
  )
  use backup_target <- decode.optional_field(
    "BackupTarget",
    option.None,
    decode.optional(decode.string),
  )
  use custom_iam_instance_profile <- decode.optional_field(
    "CustomIamInstanceProfile",
    option.None,
    decode.optional(decode.string),
  )
  use allocated_storage <- decode.optional_field(
    "AllocatedStorage",
    option.None,
    decode.optional(decode.int),
  )
  use backup_retention_period <- decode.optional_field(
    "BackupRetentionPeriod",
    option.None,
    decode.optional(decode.int),
  )
  use preferred_backup_window <- decode.optional_field(
    "PreferredBackupWindow",
    option.None,
    decode.optional(decode.string),
  )
  use dedicated_log_volume <- decode.optional_field(
    "DedicatedLogVolume",
    option.None,
    decode.optional(decode.bool),
  )
  use ca_certificate_identifier <- decode.optional_field(
    "CACertificateIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  use engine_lifecycle_support <- decode.optional_field(
    "EngineLifecycleSupport",
    option.None,
    decode.optional(decode.string),
  )
  use additional_storage_volumes <- decode.optional_field(
    "AdditionalStorageVolumes",
    option.None,
    decode.optional(
      decode.list(decode_additional_storage_volume_struct_params()),
    ),
  )
  use tag_specifications <- decode.optional_field(
    "TagSpecifications",
    option.None,
    decode.optional(decode.list(decode_tag_specification_struct_params())),
  )
  use manage_master_user_password <- decode.optional_field(
    "ManageMasterUserPassword",
    option.None,
    decode.optional(decode.bool),
  )
  use master_user_secret_kms_key_id <- decode.optional_field(
    "MasterUserSecretKmsKeyId",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(RestoreDBInstanceToPointInTimeInput(
    source_db_instance_identifier: source_db_instance_identifier,
    target_db_instance_identifier: target_db_instance_identifier,
    restore_time: restore_time,
    use_latest_restorable_time: use_latest_restorable_time,
    db_instance_class: db_instance_class,
    port: port,
    availability_zone: availability_zone,
    db_subnet_group_name: db_subnet_group_name,
    multi_az: multi_az,
    publicly_accessible: publicly_accessible,
    auto_minor_version_upgrade: auto_minor_version_upgrade,
    license_model: license_model,
    db_name: db_name,
    engine: engine,
    iops: iops,
    storage_throughput: storage_throughput,
    option_group_name: option_group_name,
    copy_tags_to_snapshot: copy_tags_to_snapshot,
    tags: tags,
    storage_type: storage_type,
    tde_credential_arn: tde_credential_arn,
    tde_credential_password: tde_credential_password,
    vpc_security_group_ids: vpc_security_group_ids,
    domain: domain,
    domain_iam_role_name: domain_iam_role_name,
    domain_fqdn: domain_fqdn,
    domain_ou: domain_ou,
    domain_auth_secret_arn: domain_auth_secret_arn,
    domain_dns_ips: domain_dns_ips,
    enable_iam_database_authentication: enable_iam_database_authentication,
    enable_cloudwatch_logs_exports: enable_cloudwatch_logs_exports,
    processor_features: processor_features,
    use_default_processor_features: use_default_processor_features,
    db_parameter_group_name: db_parameter_group_name,
    deletion_protection: deletion_protection,
    source_dbi_resource_id: source_dbi_resource_id,
    max_allocated_storage: max_allocated_storage,
    enable_customer_owned_ip: enable_customer_owned_ip,
    network_type: network_type,
    source_db_instance_automated_backups_arn: source_db_instance_automated_backups_arn,
    backup_target: backup_target,
    custom_iam_instance_profile: custom_iam_instance_profile,
    allocated_storage: allocated_storage,
    backup_retention_period: backup_retention_period,
    preferred_backup_window: preferred_backup_window,
    dedicated_log_volume: dedicated_log_volume,
    ca_certificate_identifier: ca_certificate_identifier,
    engine_lifecycle_support: engine_lifecycle_support,
    additional_storage_volumes: additional_storage_volumes,
    tag_specifications: tag_specifications,
    manage_master_user_password: manage_master_user_password,
    master_user_secret_kms_key_id: master_user_secret_kms_key_id,
  ))
}

pub fn decode_restore_db_instance_to_point_in_time_input(
  json_string: String,
) -> Result(RestoreDBInstanceToPointInTimeInput, String) {
  result.map_error(
    json.parse(
      json_string,
      decode_restore_db_instance_to_point_in_time_input_struct(),
    ),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_restore_db_instance_to_point_in_time_request(
  input: RestoreDBInstanceToPointInTimeInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=RestoreDBInstanceToPointInTime&Version=2014-10-31"
  let body = case input.source_db_instance_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "SourceDBInstanceIdentifier",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = {
    let v = input.target_db_instance_identifier
    string.concat([
      body,
      string.concat([
        "&",
        "TargetDBInstanceIdentifier",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body = case input.restore_time {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "RestoreTime",
          "=",
          uri.encode_component(json_timestamp.format_iso8601_precise(v)),
        ]),
      ])
  }
  let body = case input.use_latest_restorable_time {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "UseLatestRestorableTime",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.db_instance_class {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DBInstanceClass", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.port {
    option.None -> body
    option.Some(v) ->
      string.concat([body, string.concat(["&", "Port", "=", int.to_string(v)])])
  }
  let body = case input.availability_zone {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "AvailabilityZone", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.db_subnet_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DBSubnetGroupName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.multi_az {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "MultiAZ",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.publicly_accessible {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "PubliclyAccessible",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.auto_minor_version_upgrade {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "AutoMinorVersionUpgrade",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.license_model {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "LicenseModel", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.db_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DBName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.engine {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Engine", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.iops {
    option.None -> body
    option.Some(v) ->
      string.concat([body, string.concat(["&", "Iops", "=", int.to_string(v)])])
  }
  let body = case input.storage_throughput {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "StorageThroughput", "=", int.to_string(v)]),
      ])
  }
  let body = case input.option_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "OptionGroupName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.copy_tags_to_snapshot {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "CopyTagsToSnapshot",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.tags {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Tags", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_tag_at(
                  string.concat(["Tags", ".Tag.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.storage_type {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "StorageType", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.tde_credential_arn {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "TdeCredentialArn", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.tde_credential_password {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "TdeCredentialPassword",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.vpc_security_group_ids {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "VpcSecurityGroupIds", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "VpcSecurityGroupIds",
                    ".VpcSecurityGroupId.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body = case input.domain {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "Domain", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.domain_iam_role_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DomainIAMRoleName", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.domain_fqdn {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DomainFqdn", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.domain_ou {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DomainOu", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.domain_auth_secret_arn {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "DomainAuthSecretArn", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.domain_dns_ips {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "DomainDnsIps", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "DomainDnsIps",
                    ".member.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body = case input.enable_iam_database_authentication {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EnableIAMDatabaseAuthentication",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.enable_cloudwatch_logs_exports {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "EnableCloudwatchLogsExports", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "EnableCloudwatchLogsExports",
                    ".member.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body = case input.processor_features {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "ProcessorFeatures", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_processor_feature_at(
                  string.concat([
                    "ProcessorFeatures",
                    ".ProcessorFeature.",
                    int.to_string(idx + 1),
                  ]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.use_default_processor_features {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "UseDefaultProcessorFeatures",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.db_parameter_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DBParameterGroupName",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.deletion_protection {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DeletionProtection",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.source_dbi_resource_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "SourceDbiResourceId", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.max_allocated_storage {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "MaxAllocatedStorage", "=", int.to_string(v)]),
      ])
  }
  let body = case input.enable_customer_owned_ip {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EnableCustomerOwnedIp",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.network_type {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "NetworkType", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.source_db_instance_automated_backups_arn {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "SourceDBInstanceAutomatedBackupsArn",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.backup_target {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "BackupTarget", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.custom_iam_instance_profile {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "CustomIamInstanceProfile",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.allocated_storage {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "AllocatedStorage", "=", int.to_string(v)]),
      ])
  }
  let body = case input.backup_retention_period {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "BackupRetentionPeriod", "=", int.to_string(v)]),
      ])
  }
  let body = case input.preferred_backup_window {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "PreferredBackupWindow",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.dedicated_log_volume {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DedicatedLogVolume",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.ca_certificate_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "CACertificateIdentifier",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.engine_lifecycle_support {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EngineLifecycleSupport",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.additional_storage_volumes {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "AdditionalStorageVolumes", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_additional_storage_volume_at(
                  string.concat([
                    "AdditionalStorageVolumes",
                    ".member.",
                    int.to_string(idx + 1),
                  ]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.tag_specifications {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "TagSpecifications", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_tag_specification_at(
                  string.concat([
                    "TagSpecifications",
                    ".item.",
                    int.to_string(idx + 1),
                  ]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body = case input.manage_master_user_password {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "ManageMasterUserPassword",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.master_user_secret_kms_key_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "MasterUserSecretKmsKeyId",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_restore_db_instance_to_point_in_time_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(RestoreDBInstanceToPointInTimeOutput, String) {
  Ok(RestoreDBInstanceToPointInTimeOutput)
}

pub type RevokeDBSecurityGroupIngressInput {
  RevokeDBSecurityGroupIngressInput(
    db_security_group_name: String,
    cidrip: option.Option(String),
    ec2_security_group_name: option.Option(String),
    ec2_security_group_id: option.Option(String),
    ec2_security_group_owner_id: option.Option(String),
  )
}

pub fn revoke_db_security_group_ingress_input_default(
  db_security_group_name db_security_group_name: String,
) -> RevokeDBSecurityGroupIngressInput {
  RevokeDBSecurityGroupIngressInput(
    db_security_group_name: db_security_group_name,
    cidrip: option.None,
    ec2_security_group_name: option.None,
    ec2_security_group_id: option.None,
    ec2_security_group_owner_id: option.None,
  )
}

pub type RevokeDBSecurityGroupIngressOutput {
  RevokeDBSecurityGroupIngressOutput
}

pub fn decode_revoke_db_security_group_ingress_input_struct() -> decode.Decoder(
  RevokeDBSecurityGroupIngressInput,
) {
  use <- decode.recursive
  use db_security_group_name <- decode.field(
    "DBSecurityGroupName",
    decode.string,
  )
  use cidrip <- decode.optional_field(
    "CIDRIP",
    option.None,
    decode.optional(decode.string),
  )
  use ec2_security_group_name <- decode.optional_field(
    "EC2SecurityGroupName",
    option.None,
    decode.optional(decode.string),
  )
  use ec2_security_group_id <- decode.optional_field(
    "EC2SecurityGroupId",
    option.None,
    decode.optional(decode.string),
  )
  use ec2_security_group_owner_id <- decode.optional_field(
    "EC2SecurityGroupOwnerId",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(RevokeDBSecurityGroupIngressInput(
    db_security_group_name: db_security_group_name,
    cidrip: cidrip,
    ec2_security_group_name: ec2_security_group_name,
    ec2_security_group_id: ec2_security_group_id,
    ec2_security_group_owner_id: ec2_security_group_owner_id,
  ))
}

pub fn decode_revoke_db_security_group_ingress_input(
  json_string: String,
) -> Result(RevokeDBSecurityGroupIngressInput, String) {
  result.map_error(
    json.parse(
      json_string,
      decode_revoke_db_security_group_ingress_input_struct(),
    ),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_revoke_db_security_group_ingress_request(
  input: RevokeDBSecurityGroupIngressInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=RevokeDBSecurityGroupIngress&Version=2014-10-31"
  let body = {
    let v = input.db_security_group_name
    string.concat([
      body,
      string.concat(["&", "DBSecurityGroupName", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.cidrip {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "CIDRIP", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.ec2_security_group_name {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EC2SecurityGroupName",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body = case input.ec2_security_group_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "EC2SecurityGroupId", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.ec2_security_group_owner_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EC2SecurityGroupOwnerId",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_revoke_db_security_group_ingress_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(RevokeDBSecurityGroupIngressOutput, String) {
  Ok(RevokeDBSecurityGroupIngressOutput)
}

pub type StartActivityStreamInput {
  StartActivityStreamInput(
    resource_arn: String,
    mode: ActivityStreamMode,
    kms_key_id: String,
    apply_immediately: option.Option(Bool),
    engine_native_audit_fields_included: option.Option(Bool),
  )
}

pub fn start_activity_stream_input_default(
  resource_arn resource_arn: String,
  mode mode: ActivityStreamMode,
  kms_key_id kms_key_id: String,
) -> StartActivityStreamInput {
  StartActivityStreamInput(
    resource_arn: resource_arn,
    mode: mode,
    kms_key_id: kms_key_id,
    apply_immediately: option.None,
    engine_native_audit_fields_included: option.None,
  )
}

pub type StartActivityStreamOutput {
  StartActivityStreamOutput
}

pub fn decode_start_activity_stream_input_struct() -> decode.Decoder(
  StartActivityStreamInput,
) {
  use <- decode.recursive
  use resource_arn <- decode.field("ResourceArn", decode.string)
  use mode <- decode.field("Mode", decode_activity_stream_mode_enum())
  use kms_key_id <- decode.field("KmsKeyId", decode.string)
  use apply_immediately <- decode.optional_field(
    "ApplyImmediately",
    option.None,
    decode.optional(decode.bool),
  )
  use engine_native_audit_fields_included <- decode.optional_field(
    "EngineNativeAuditFieldsIncluded",
    option.None,
    decode.optional(decode.bool),
  )
  decode.success(StartActivityStreamInput(
    resource_arn: resource_arn,
    mode: mode,
    kms_key_id: kms_key_id,
    apply_immediately: apply_immediately,
    engine_native_audit_fields_included: engine_native_audit_fields_included,
  ))
}

pub fn decode_start_activity_stream_input(
  json_string: String,
) -> Result(StartActivityStreamInput, String) {
  result.map_error(
    json.parse(json_string, decode_start_activity_stream_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_start_activity_stream_request(
  input: StartActivityStreamInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=StartActivityStream&Version=2014-10-31"
  let body = {
    let v = input.resource_arn
    string.concat([
      body,
      string.concat(["&", "ResourceArn", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.mode
    string.concat([
      body,
      string.concat([
        "&",
        "Mode",
        "=",
        uri.encode_component(activity_stream_mode_to_wire(v)),
      ]),
    ])
  }
  let body = {
    let v = input.kms_key_id
    string.concat([
      body,
      string.concat(["&", "KmsKeyId", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.apply_immediately {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "ApplyImmediately",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body = case input.engine_native_audit_fields_included {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "EngineNativeAuditFieldsIncluded",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_start_activity_stream_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(StartActivityStreamOutput, String) {
  Ok(StartActivityStreamOutput)
}

pub type StartDBClusterInput {
  StartDBClusterInput(db_cluster_identifier: String)
}

pub fn start_db_cluster_input_default(
  db_cluster_identifier db_cluster_identifier: String,
) -> StartDBClusterInput {
  StartDBClusterInput(db_cluster_identifier: db_cluster_identifier)
}

pub type StartDBClusterOutput {
  StartDBClusterOutput
}

pub fn decode_start_db_cluster_input_struct() -> decode.Decoder(
  StartDBClusterInput,
) {
  use <- decode.recursive
  use db_cluster_identifier <- decode.field(
    "DBClusterIdentifier",
    decode.string,
  )
  decode.success(StartDBClusterInput(
    db_cluster_identifier: db_cluster_identifier,
  ))
}

pub fn decode_start_db_cluster_input(
  json_string: String,
) -> Result(StartDBClusterInput, String) {
  result.map_error(
    json.parse(json_string, decode_start_db_cluster_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_start_db_cluster_request(
  input: StartDBClusterInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=StartDBCluster&Version=2014-10-31"
  let body = {
    let v = input.db_cluster_identifier
    string.concat([
      body,
      string.concat(["&", "DBClusterIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_start_db_cluster_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(StartDBClusterOutput, String) {
  Ok(StartDBClusterOutput)
}

pub type StartDBInstanceInput {
  StartDBInstanceInput(db_instance_identifier: String)
}

pub fn start_db_instance_input_default(
  db_instance_identifier db_instance_identifier: String,
) -> StartDBInstanceInput {
  StartDBInstanceInput(db_instance_identifier: db_instance_identifier)
}

pub type StartDBInstanceOutput {
  StartDBInstanceOutput
}

pub fn decode_start_db_instance_input_struct() -> decode.Decoder(
  StartDBInstanceInput,
) {
  use <- decode.recursive
  use db_instance_identifier <- decode.field(
    "DBInstanceIdentifier",
    decode.string,
  )
  decode.success(StartDBInstanceInput(
    db_instance_identifier: db_instance_identifier,
  ))
}

pub fn decode_start_db_instance_input(
  json_string: String,
) -> Result(StartDBInstanceInput, String) {
  result.map_error(
    json.parse(json_string, decode_start_db_instance_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_start_db_instance_request(
  input: StartDBInstanceInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=StartDBInstance&Version=2014-10-31"
  let body = {
    let v = input.db_instance_identifier
    string.concat([
      body,
      string.concat(["&", "DBInstanceIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_start_db_instance_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(StartDBInstanceOutput, String) {
  Ok(StartDBInstanceOutput)
}

pub type StartDBInstanceAutomatedBackupsReplicationInput {
  StartDBInstanceAutomatedBackupsReplicationInput(
    source_db_instance_arn: String,
    backup_retention_period: option.Option(Int),
    kms_key_id: option.Option(String),
    pre_signed_url: option.Option(String),
    tags: option.Option(List(Tag)),
  )
}

pub fn start_db_instance_automated_backups_replication_input_default(
  source_db_instance_arn source_db_instance_arn: String,
) -> StartDBInstanceAutomatedBackupsReplicationInput {
  StartDBInstanceAutomatedBackupsReplicationInput(
    source_db_instance_arn: source_db_instance_arn,
    backup_retention_period: option.None,
    kms_key_id: option.None,
    pre_signed_url: option.None,
    tags: option.None,
  )
}

pub type StartDBInstanceAutomatedBackupsReplicationOutput {
  StartDBInstanceAutomatedBackupsReplicationOutput
}

pub fn decode_start_db_instance_automated_backups_replication_input_struct() -> decode.Decoder(
  StartDBInstanceAutomatedBackupsReplicationInput,
) {
  use <- decode.recursive
  use source_db_instance_arn <- decode.field(
    "SourceDBInstanceArn",
    decode.string,
  )
  use backup_retention_period <- decode.optional_field(
    "BackupRetentionPeriod",
    option.None,
    decode.optional(decode.int),
  )
  use kms_key_id <- decode.optional_field(
    "KmsKeyId",
    option.None,
    decode.optional(decode.string),
  )
  use pre_signed_url <- decode.optional_field(
    "PreSignedUrl",
    option.None,
    decode.optional(decode.string),
  )
  use tags <- decode.optional_field(
    "Tags",
    option.None,
    decode.optional(decode.list(decode_tag_struct_params())),
  )
  decode.success(StartDBInstanceAutomatedBackupsReplicationInput(
    source_db_instance_arn: source_db_instance_arn,
    backup_retention_period: backup_retention_period,
    kms_key_id: kms_key_id,
    pre_signed_url: pre_signed_url,
    tags: tags,
  ))
}

pub fn decode_start_db_instance_automated_backups_replication_input(
  json_string: String,
) -> Result(StartDBInstanceAutomatedBackupsReplicationInput, String) {
  result.map_error(
    json.parse(
      json_string,
      decode_start_db_instance_automated_backups_replication_input_struct(),
    ),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_start_db_instance_automated_backups_replication_request(
  input: StartDBInstanceAutomatedBackupsReplicationInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body =
    "Action=StartDBInstanceAutomatedBackupsReplication&Version=2014-10-31"
  let body = {
    let v = input.source_db_instance_arn
    string.concat([
      body,
      string.concat(["&", "SourceDBInstanceArn", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.backup_retention_period {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "BackupRetentionPeriod", "=", int.to_string(v)]),
      ])
  }
  let body = case input.kms_key_id {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "KmsKeyId", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.pre_signed_url {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "PreSignedUrl", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.tags {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "Tags", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                encode_tag_at(
                  string.concat(["Tags", ".Tag.", int.to_string(idx + 1)]),
                  item,
                ),
              ])
            })
        },
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_start_db_instance_automated_backups_replication_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(StartDBInstanceAutomatedBackupsReplicationOutput, String) {
  Ok(StartDBInstanceAutomatedBackupsReplicationOutput)
}

pub type StartExportTaskInput {
  StartExportTaskInput(
    export_task_identifier: String,
    source_arn: String,
    s3_bucket_name: String,
    iam_role_arn: String,
    kms_key_id: String,
    s3_prefix: option.Option(String),
    export_only: option.Option(List(String)),
  )
}

pub fn start_export_task_input_default(
  export_task_identifier export_task_identifier: String,
  source_arn source_arn: String,
  s3_bucket_name s3_bucket_name: String,
  iam_role_arn iam_role_arn: String,
  kms_key_id kms_key_id: String,
) -> StartExportTaskInput {
  StartExportTaskInput(
    export_task_identifier: export_task_identifier,
    source_arn: source_arn,
    s3_bucket_name: s3_bucket_name,
    iam_role_arn: iam_role_arn,
    kms_key_id: kms_key_id,
    s3_prefix: option.None,
    export_only: option.None,
  )
}

pub type StartExportTaskOutput {
  StartExportTaskOutput
}

pub fn decode_start_export_task_input_struct() -> decode.Decoder(
  StartExportTaskInput,
) {
  use <- decode.recursive
  use export_task_identifier <- decode.field(
    "ExportTaskIdentifier",
    decode.string,
  )
  use source_arn <- decode.field("SourceArn", decode.string)
  use s3_bucket_name <- decode.field("S3BucketName", decode.string)
  use iam_role_arn <- decode.field("IamRoleArn", decode.string)
  use kms_key_id <- decode.field("KmsKeyId", decode.string)
  use s3_prefix <- decode.optional_field(
    "S3Prefix",
    option.None,
    decode.optional(decode.string),
  )
  use export_only <- decode.optional_field(
    "ExportOnly",
    option.None,
    decode.optional(decode.list(decode.string)),
  )
  decode.success(StartExportTaskInput(
    export_task_identifier: export_task_identifier,
    source_arn: source_arn,
    s3_bucket_name: s3_bucket_name,
    iam_role_arn: iam_role_arn,
    kms_key_id: kms_key_id,
    s3_prefix: s3_prefix,
    export_only: export_only,
  ))
}

pub fn decode_start_export_task_input(
  json_string: String,
) -> Result(StartExportTaskInput, String) {
  result.map_error(
    json.parse(json_string, decode_start_export_task_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_start_export_task_request(
  input: StartExportTaskInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=StartExportTask&Version=2014-10-31"
  let body = {
    let v = input.export_task_identifier
    string.concat([
      body,
      string.concat(["&", "ExportTaskIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.source_arn
    string.concat([
      body,
      string.concat(["&", "SourceArn", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.s3_bucket_name
    string.concat([
      body,
      string.concat(["&", "S3BucketName", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.iam_role_arn
    string.concat([
      body,
      string.concat(["&", "IamRoleArn", "=", uri.encode_component(v)]),
    ])
  }
  let body = {
    let v = input.kms_key_id
    string.concat([
      body,
      string.concat(["&", "KmsKeyId", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.s3_prefix {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "S3Prefix", "=", uri.encode_component(v)]),
      ])
  }
  let body = case input.export_only {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        case v {
          [] -> string.concat(["&", "ExportOnly", "=", ""])
          _ ->
            list.index_fold(v, "", fn(acc, item, idx) {
              string.concat([
                acc,
                string.concat([
                  "&",
                  string.concat([
                    "ExportOnly",
                    ".member.",
                    int.to_string(idx + 1),
                  ]),
                  "=",
                  uri.encode_component(item),
                ]),
              ])
            })
        },
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_start_export_task_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(StartExportTaskOutput, String) {
  Ok(StartExportTaskOutput)
}

pub type StopActivityStreamInput {
  StopActivityStreamInput(
    resource_arn: String,
    apply_immediately: option.Option(Bool),
  )
}

pub fn stop_activity_stream_input_default(
  resource_arn resource_arn: String,
) -> StopActivityStreamInput {
  StopActivityStreamInput(
    resource_arn: resource_arn,
    apply_immediately: option.None,
  )
}

pub type StopActivityStreamOutput {
  StopActivityStreamOutput
}

pub fn decode_stop_activity_stream_input_struct() -> decode.Decoder(
  StopActivityStreamInput,
) {
  use <- decode.recursive
  use resource_arn <- decode.field("ResourceArn", decode.string)
  use apply_immediately <- decode.optional_field(
    "ApplyImmediately",
    option.None,
    decode.optional(decode.bool),
  )
  decode.success(StopActivityStreamInput(
    resource_arn: resource_arn,
    apply_immediately: apply_immediately,
  ))
}

pub fn decode_stop_activity_stream_input(
  json_string: String,
) -> Result(StopActivityStreamInput, String) {
  result.map_error(
    json.parse(json_string, decode_stop_activity_stream_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_stop_activity_stream_request(
  input: StopActivityStreamInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=StopActivityStream&Version=2014-10-31"
  let body = {
    let v = input.resource_arn
    string.concat([
      body,
      string.concat(["&", "ResourceArn", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.apply_immediately {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "ApplyImmediately",
          "=",
          case v {
            True -> "true"
            False -> "false"
          },
        ]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_stop_activity_stream_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(StopActivityStreamOutput, String) {
  Ok(StopActivityStreamOutput)
}

pub type StopDBClusterInput {
  StopDBClusterInput(db_cluster_identifier: String)
}

pub fn stop_db_cluster_input_default(
  db_cluster_identifier db_cluster_identifier: String,
) -> StopDBClusterInput {
  StopDBClusterInput(db_cluster_identifier: db_cluster_identifier)
}

pub type StopDBClusterOutput {
  StopDBClusterOutput
}

pub fn decode_stop_db_cluster_input_struct() -> decode.Decoder(
  StopDBClusterInput,
) {
  use <- decode.recursive
  use db_cluster_identifier <- decode.field(
    "DBClusterIdentifier",
    decode.string,
  )
  decode.success(StopDBClusterInput(
    db_cluster_identifier: db_cluster_identifier,
  ))
}

pub fn decode_stop_db_cluster_input(
  json_string: String,
) -> Result(StopDBClusterInput, String) {
  result.map_error(
    json.parse(json_string, decode_stop_db_cluster_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_stop_db_cluster_request(
  input: StopDBClusterInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=StopDBCluster&Version=2014-10-31"
  let body = {
    let v = input.db_cluster_identifier
    string.concat([
      body,
      string.concat(["&", "DBClusterIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_stop_db_cluster_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(StopDBClusterOutput, String) {
  Ok(StopDBClusterOutput)
}

pub type StopDBInstanceInput {
  StopDBInstanceInput(
    db_instance_identifier: String,
    db_snapshot_identifier: option.Option(String),
  )
}

pub fn stop_db_instance_input_default(
  db_instance_identifier db_instance_identifier: String,
) -> StopDBInstanceInput {
  StopDBInstanceInput(
    db_instance_identifier: db_instance_identifier,
    db_snapshot_identifier: option.None,
  )
}

pub type StopDBInstanceOutput {
  StopDBInstanceOutput
}

pub fn decode_stop_db_instance_input_struct() -> decode.Decoder(
  StopDBInstanceInput,
) {
  use <- decode.recursive
  use db_instance_identifier <- decode.field(
    "DBInstanceIdentifier",
    decode.string,
  )
  use db_snapshot_identifier <- decode.optional_field(
    "DBSnapshotIdentifier",
    option.None,
    decode.optional(decode.string),
  )
  decode.success(StopDBInstanceInput(
    db_instance_identifier: db_instance_identifier,
    db_snapshot_identifier: db_snapshot_identifier,
  ))
}

pub fn decode_stop_db_instance_input(
  json_string: String,
) -> Result(StopDBInstanceInput, String) {
  result.map_error(
    json.parse(json_string, decode_stop_db_instance_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_stop_db_instance_request(
  input: StopDBInstanceInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=StopDBInstance&Version=2014-10-31"
  let body = {
    let v = input.db_instance_identifier
    string.concat([
      body,
      string.concat(["&", "DBInstanceIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body = case input.db_snapshot_identifier {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat([
          "&",
          "DBSnapshotIdentifier",
          "=",
          uri.encode_component(v),
        ]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_stop_db_instance_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(StopDBInstanceOutput, String) {
  Ok(StopDBInstanceOutput)
}

pub type StopDBInstanceAutomatedBackupsReplicationInput {
  StopDBInstanceAutomatedBackupsReplicationInput(source_db_instance_arn: String)
}

pub fn stop_db_instance_automated_backups_replication_input_default(
  source_db_instance_arn source_db_instance_arn: String,
) -> StopDBInstanceAutomatedBackupsReplicationInput {
  StopDBInstanceAutomatedBackupsReplicationInput(
    source_db_instance_arn: source_db_instance_arn,
  )
}

pub type StopDBInstanceAutomatedBackupsReplicationOutput {
  StopDBInstanceAutomatedBackupsReplicationOutput
}

pub fn decode_stop_db_instance_automated_backups_replication_input_struct() -> decode.Decoder(
  StopDBInstanceAutomatedBackupsReplicationInput,
) {
  use <- decode.recursive
  use source_db_instance_arn <- decode.field(
    "SourceDBInstanceArn",
    decode.string,
  )
  decode.success(StopDBInstanceAutomatedBackupsReplicationInput(
    source_db_instance_arn: source_db_instance_arn,
  ))
}

pub fn decode_stop_db_instance_automated_backups_replication_input(
  json_string: String,
) -> Result(StopDBInstanceAutomatedBackupsReplicationInput, String) {
  result.map_error(
    json.parse(
      json_string,
      decode_stop_db_instance_automated_backups_replication_input_struct(),
    ),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_stop_db_instance_automated_backups_replication_request(
  input: StopDBInstanceAutomatedBackupsReplicationInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body =
    "Action=StopDBInstanceAutomatedBackupsReplication&Version=2014-10-31"
  let body = {
    let v = input.source_db_instance_arn
    string.concat([
      body,
      string.concat(["&", "SourceDBInstanceArn", "=", uri.encode_component(v)]),
    ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_stop_db_instance_automated_backups_replication_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(StopDBInstanceAutomatedBackupsReplicationOutput, String) {
  Ok(StopDBInstanceAutomatedBackupsReplicationOutput)
}

pub type SwitchoverBlueGreenDeploymentInput {
  SwitchoverBlueGreenDeploymentInput(
    blue_green_deployment_identifier: String,
    switchover_timeout: option.Option(Int),
  )
}

pub fn switchover_blue_green_deployment_input_default(
  blue_green_deployment_identifier blue_green_deployment_identifier: String,
) -> SwitchoverBlueGreenDeploymentInput {
  SwitchoverBlueGreenDeploymentInput(
    blue_green_deployment_identifier: blue_green_deployment_identifier,
    switchover_timeout: option.None,
  )
}

pub type SwitchoverBlueGreenDeploymentOutput {
  SwitchoverBlueGreenDeploymentOutput
}

pub fn decode_switchover_blue_green_deployment_input_struct() -> decode.Decoder(
  SwitchoverBlueGreenDeploymentInput,
) {
  use <- decode.recursive
  use blue_green_deployment_identifier <- decode.field(
    "BlueGreenDeploymentIdentifier",
    decode.string,
  )
  use switchover_timeout <- decode.optional_field(
    "SwitchoverTimeout",
    option.None,
    decode.optional(decode.int),
  )
  decode.success(SwitchoverBlueGreenDeploymentInput(
    blue_green_deployment_identifier: blue_green_deployment_identifier,
    switchover_timeout: switchover_timeout,
  ))
}

pub fn decode_switchover_blue_green_deployment_input(
  json_string: String,
) -> Result(SwitchoverBlueGreenDeploymentInput, String) {
  result.map_error(
    json.parse(
      json_string,
      decode_switchover_blue_green_deployment_input_struct(),
    ),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_switchover_blue_green_deployment_request(
  input: SwitchoverBlueGreenDeploymentInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=SwitchoverBlueGreenDeployment&Version=2014-10-31"
  let body = {
    let v = input.blue_green_deployment_identifier
    string.concat([
      body,
      string.concat([
        "&",
        "BlueGreenDeploymentIdentifier",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body = case input.switchover_timeout {
    option.None -> body
    option.Some(v) ->
      string.concat([
        body,
        string.concat(["&", "SwitchoverTimeout", "=", int.to_string(v)]),
      ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_switchover_blue_green_deployment_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(SwitchoverBlueGreenDeploymentOutput, String) {
  Ok(SwitchoverBlueGreenDeploymentOutput)
}

pub type SwitchoverGlobalClusterInput {
  SwitchoverGlobalClusterInput(
    global_cluster_identifier: String,
    target_db_cluster_identifier: String,
  )
}

pub fn switchover_global_cluster_input_default(
  global_cluster_identifier global_cluster_identifier: String,
  target_db_cluster_identifier target_db_cluster_identifier: String,
) -> SwitchoverGlobalClusterInput {
  SwitchoverGlobalClusterInput(
    global_cluster_identifier: global_cluster_identifier,
    target_db_cluster_identifier: target_db_cluster_identifier,
  )
}

pub type SwitchoverGlobalClusterOutput {
  SwitchoverGlobalClusterOutput
}

pub fn decode_switchover_global_cluster_input_struct() -> decode.Decoder(
  SwitchoverGlobalClusterInput,
) {
  use <- decode.recursive
  use global_cluster_identifier <- decode.field(
    "GlobalClusterIdentifier",
    decode.string,
  )
  use target_db_cluster_identifier <- decode.field(
    "TargetDbClusterIdentifier",
    decode.string,
  )
  decode.success(SwitchoverGlobalClusterInput(
    global_cluster_identifier: global_cluster_identifier,
    target_db_cluster_identifier: target_db_cluster_identifier,
  ))
}

pub fn decode_switchover_global_cluster_input(
  json_string: String,
) -> Result(SwitchoverGlobalClusterInput, String) {
  result.map_error(
    json.parse(json_string, decode_switchover_global_cluster_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_switchover_global_cluster_request(
  input: SwitchoverGlobalClusterInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=SwitchoverGlobalCluster&Version=2014-10-31"
  let body = {
    let v = input.global_cluster_identifier
    string.concat([
      body,
      string.concat([
        "&",
        "GlobalClusterIdentifier",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body = {
    let v = input.target_db_cluster_identifier
    string.concat([
      body,
      string.concat([
        "&",
        "TargetDbClusterIdentifier",
        "=",
        uri.encode_component(v),
      ]),
    ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_switchover_global_cluster_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(SwitchoverGlobalClusterOutput, String) {
  Ok(SwitchoverGlobalClusterOutput)
}

pub type SwitchoverReadReplicaInput {
  SwitchoverReadReplicaInput(db_instance_identifier: String)
}

pub fn switchover_read_replica_input_default(
  db_instance_identifier db_instance_identifier: String,
) -> SwitchoverReadReplicaInput {
  SwitchoverReadReplicaInput(db_instance_identifier: db_instance_identifier)
}

pub type SwitchoverReadReplicaOutput {
  SwitchoverReadReplicaOutput
}

pub fn decode_switchover_read_replica_input_struct() -> decode.Decoder(
  SwitchoverReadReplicaInput,
) {
  use <- decode.recursive
  use db_instance_identifier <- decode.field(
    "DBInstanceIdentifier",
    decode.string,
  )
  decode.success(SwitchoverReadReplicaInput(
    db_instance_identifier: db_instance_identifier,
  ))
}

pub fn decode_switchover_read_replica_input(
  json_string: String,
) -> Result(SwitchoverReadReplicaInput, String) {
  result.map_error(
    json.parse(json_string, decode_switchover_read_replica_input_struct()),
    fn(_) { "input JSON decode failed" },
  )
}

pub fn build_switchover_read_replica_request(
  input: SwitchoverReadReplicaInput,
) -> #(String, String, dict.Dict(String, String), BitArray) {
  let body = "Action=SwitchoverReadReplica&Version=2014-10-31"
  let body = {
    let v = input.db_instance_identifier
    string.concat([
      body,
      string.concat(["&", "DBInstanceIdentifier", "=", uri.encode_component(v)]),
    ])
  }
  let body_bytes = bit_array.from_string(body)
  let headers =
    dict.from_list([
      #("Content-Type", "application/x-www-form-urlencoded"),
      #("Content-Length", int.to_string(bit_array.byte_size(body_bytes))),
    ])
  #("POST", "/", headers, body_bytes)
}

pub fn parse_switchover_read_replica_response(
  _code: Int,
  _headers: dict.Dict(String, String),
  _body: BitArray,
) -> Result(SwitchoverReadReplicaOutput, String) {
  Ok(SwitchoverReadReplicaOutput)
}

pub fn parse_db_cluster_not_found_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "DBClusterNotFoundFault")
}

pub fn parse_db_cluster_role_already_exists_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "DBClusterRoleAlreadyExists")
}

pub fn parse_db_cluster_role_quota_exceeded_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "DBClusterRoleQuotaExceeded")
}

pub fn parse_invalid_db_cluster_state_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "InvalidDBClusterStateFault")
}

pub fn parse_db_instance_not_found_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "DBInstanceNotFound")
}

pub fn parse_db_instance_role_already_exists_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "DBInstanceRoleAlreadyExists")
}

pub fn parse_db_instance_role_quota_exceeded_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "DBInstanceRoleQuotaExceeded")
}

pub fn parse_invalid_db_instance_state_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "InvalidDBInstanceState")
}

pub fn parse_source_not_found_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "SourceNotFound")
}

pub fn parse_subscription_not_found_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "SubscriptionNotFound")
}

pub fn parse_blue_green_deployment_not_found_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "BlueGreenDeploymentNotFoundFault",
  )
}

pub fn parse_db_proxy_endpoint_not_found_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "DBProxyEndpointNotFoundFault",
  )
}

pub fn parse_db_proxy_not_found_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "DBProxyNotFoundFault")
}

pub fn parse_db_proxy_target_group_not_found_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "DBProxyTargetGroupNotFoundFault",
  )
}

pub fn parse_db_shard_group_not_found_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "DBShardGroupNotFound")
}

pub fn parse_db_snapshot_not_found_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "DBSnapshotNotFound")
}

pub fn parse_db_snapshot_tenant_database_not_found_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "DBSnapshotTenantDatabaseNotFoundFault",
  )
}

pub fn parse_integration_not_found_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "IntegrationNotFoundFault")
}

pub fn parse_invalid_db_cluster_endpoint_state_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "InvalidDBClusterEndpointStateFault",
  )
}

pub fn parse_tenant_database_not_found_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "TenantDatabaseNotFound")
}

pub fn parse_resource_not_found_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "ResourceNotFoundFault")
}

pub fn parse_authorization_already_exists_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "AuthorizationAlreadyExists")
}

pub fn parse_authorization_quota_exceeded_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "AuthorizationQuotaExceeded")
}

pub fn parse_db_security_group_not_found_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "DBSecurityGroupNotFound")
}

pub fn parse_invalid_db_security_group_state_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "InvalidDBSecurityGroupState")
}

pub fn parse_export_task_not_found_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "ExportTaskNotFound")
}

pub fn parse_invalid_export_task_state_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "InvalidExportTaskStateFault")
}

pub fn parse_db_parameter_group_already_exists_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "DBParameterGroupAlreadyExists",
  )
}

pub fn parse_db_parameter_group_not_found_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "DBParameterGroupNotFound")
}

pub fn parse_db_parameter_group_quota_exceeded_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "DBParameterGroupQuotaExceeded",
  )
}

pub fn parse_db_cluster_snapshot_already_exists_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "DBClusterSnapshotAlreadyExistsFault",
  )
}

pub fn parse_db_cluster_snapshot_not_found_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "DBClusterSnapshotNotFoundFault",
  )
}

pub fn parse_invalid_db_cluster_snapshot_state_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "InvalidDBClusterSnapshotStateFault",
  )
}

pub fn parse_kms_key_not_accessible_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "KMSKeyNotAccessibleFault")
}

pub fn parse_snapshot_quota_exceeded_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "SnapshotQuotaExceeded")
}

pub fn parse_custom_availability_zone_not_found_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "CustomAvailabilityZoneNotFound",
  )
}

pub fn parse_db_snapshot_already_exists_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "DBSnapshotAlreadyExists")
}

pub fn parse_invalid_db_snapshot_state_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "InvalidDBSnapshotState")
}

pub fn parse_option_group_already_exists_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "OptionGroupAlreadyExistsFault",
  )
}

pub fn parse_option_group_not_found_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "OptionGroupNotFoundFault")
}

pub fn parse_option_group_quota_exceeded_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "OptionGroupQuotaExceededFault",
  )
}

pub fn parse_blue_green_deployment_already_exists_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "BlueGreenDeploymentAlreadyExistsFault",
  )
}

pub fn parse_db_cluster_parameter_group_not_found_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "DBClusterParameterGroupNotFound",
  )
}

pub fn parse_db_cluster_quota_exceeded_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "DBClusterQuotaExceededFault")
}

pub fn parse_instance_quota_exceeded_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "InstanceQuotaExceeded")
}

pub fn parse_source_cluster_not_supported_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "SourceClusterNotSupportedFault",
  )
}

pub fn parse_source_database_not_supported_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "SourceDatabaseNotSupportedFault",
  )
}

pub fn parse_storage_quota_exceeded_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "StorageQuotaExceeded")
}

pub fn parse_create_custom_db_engine_version_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "CreateCustomDBEngineVersionFault",
  )
}

pub fn parse_custom_db_engine_version_already_exists_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "CustomDBEngineVersionAlreadyExistsFault",
  )
}

pub fn parse_custom_db_engine_version_not_found_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "CustomDBEngineVersionNotFoundFault",
  )
}

pub fn parse_custom_db_engine_version_quota_exceeded_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "CustomDBEngineVersionQuotaExceededFault",
  )
}

pub fn parse_ec2_image_properties_not_supported_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "Ec2ImagePropertiesNotSupportedFault",
  )
}

pub fn parse_invalid_custom_db_engine_version_state_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "InvalidCustomDBEngineVersionStateFault",
  )
}

pub fn parse_db_cluster_already_exists_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "DBClusterAlreadyExistsFault")
}

pub fn parse_db_subnet_group_does_not_cover_enough_a_zs_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "DBSubnetGroupDoesNotCoverEnoughAZs",
  )
}

pub fn parse_db_subnet_group_not_found_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "DBSubnetGroupNotFoundFault")
}

pub fn parse_domain_not_found_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "DomainNotFoundFault")
}

pub fn parse_global_cluster_not_found_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "GlobalClusterNotFoundFault")
}

pub fn parse_insufficient_db_instance_capacity_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "InsufficientDBInstanceCapacity",
  )
}

pub fn parse_insufficient_storage_cluster_capacity_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "InsufficientStorageClusterCapacity",
  )
}

pub fn parse_invalid_db_subnet_group_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "InvalidDBSubnetGroupFault")
}

pub fn parse_invalid_db_subnet_group_state_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "InvalidDBSubnetGroupStateFault",
  )
}

pub fn parse_invalid_global_cluster_state_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "InvalidGlobalClusterStateFault",
  )
}

pub fn parse_invalid_subnet_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "InvalidSubnet")
}

pub fn parse_invalid_vpc_network_state_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "InvalidVPCNetworkStateFault")
}

pub fn parse_network_type_not_supported_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "NetworkTypeNotSupported")
}

pub fn parse_storage_type_not_supported_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "StorageTypeNotSupported")
}

pub fn parse_vpc_encryption_control_violation_exception_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "VpcEncryptionControlViolationException",
  )
}

pub fn parse_db_cluster_endpoint_already_exists_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "DBClusterEndpointAlreadyExistsFault",
  )
}

pub fn parse_db_cluster_endpoint_quota_exceeded_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "DBClusterEndpointQuotaExceededFault",
  )
}

pub fn parse_authorization_not_found_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "AuthorizationNotFound")
}

pub fn parse_backup_policy_not_found_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "BackupPolicyNotFoundFault")
}

pub fn parse_certificate_not_found_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "CertificateNotFound")
}

pub fn parse_db_instance_already_exists_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "DBInstanceAlreadyExists")
}

pub fn parse_provisioned_iops_not_available_in_az_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "ProvisionedIopsNotAvailableInAZFault",
  )
}

pub fn parse_tenant_database_quota_exceeded_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "TenantDatabaseQuotaExceeded")
}

pub fn parse_db_subnet_group_not_allowed_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "DBSubnetGroupNotAllowedFault",
  )
}

pub fn parse_db_proxy_already_exists_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "DBProxyAlreadyExistsFault")
}

pub fn parse_db_proxy_quota_exceeded_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "DBProxyQuotaExceededFault")
}

pub fn parse_db_proxy_endpoint_already_exists_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "DBProxyEndpointAlreadyExistsFault",
  )
}

pub fn parse_db_proxy_endpoint_quota_exceeded_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "DBProxyEndpointQuotaExceededFault",
  )
}

pub fn parse_invalid_db_proxy_state_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "InvalidDBProxyStateFault")
}

pub fn parse_db_security_group_already_exists_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "DBSecurityGroupAlreadyExists",
  )
}

pub fn parse_db_security_group_not_supported_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "DBSecurityGroupNotSupported")
}

pub fn parse_db_security_group_quota_exceeded_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "QuotaExceeded.DBSecurityGroup",
  )
}

pub fn parse_db_shard_group_already_exists_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "DBShardGroupAlreadyExists")
}

pub fn parse_max_db_shard_group_limit_reached_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "MaxDBShardGroupLimitReached")
}

pub fn parse_unsupported_db_engine_version_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "UnsupportedDBEngineVersion")
}

pub fn parse_db_subnet_group_already_exists_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "DBSubnetGroupAlreadyExists")
}

pub fn parse_db_subnet_group_quota_exceeded_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "DBSubnetGroupQuotaExceeded")
}

pub fn parse_db_subnet_quota_exceeded_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "DBSubnetQuotaExceededFault")
}

pub fn parse_event_subscription_quota_exceeded_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "EventSubscriptionQuotaExceeded",
  )
}

pub fn parse_sns_invalid_topic_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "SNSInvalidTopic")
}

pub fn parse_sns_no_authorization_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "SNSNoAuthorization")
}

pub fn parse_sns_topic_arn_not_found_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "SNSTopicArnNotFound")
}

pub fn parse_subscription_already_exist_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "SubscriptionAlreadyExist")
}

pub fn parse_subscription_category_not_found_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "SubscriptionCategoryNotFound",
  )
}

pub fn parse_global_cluster_already_exists_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "GlobalClusterAlreadyExistsFault",
  )
}

pub fn parse_global_cluster_quota_exceeded_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "GlobalClusterQuotaExceededFault",
  )
}

pub fn parse_invalid_db_shard_group_state_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "InvalidDBShardGroupState")
}

pub fn parse_integration_already_exists_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "IntegrationAlreadyExistsFault",
  )
}

pub fn parse_integration_conflict_operation_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "IntegrationConflictOperationFault",
  )
}

pub fn parse_integration_quota_exceeded_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "IntegrationQuotaExceededFault",
  )
}

pub fn parse_tenant_database_already_exists_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "TenantDatabaseAlreadyExists")
}

pub fn parse_invalid_blue_green_deployment_state_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "InvalidBlueGreenDeploymentStateFault",
  )
}

pub fn parse_db_cluster_automated_backup_quota_exceeded_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "DBClusterAutomatedBackupQuotaExceededFault",
  )
}

pub fn parse_db_cluster_automated_backup_not_found_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "DBClusterAutomatedBackupNotFoundFault",
  )
}

pub fn parse_invalid_db_cluster_automated_backup_state_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "InvalidDBClusterAutomatedBackupStateFault",
  )
}

pub fn parse_db_cluster_endpoint_not_found_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "DBClusterEndpointNotFoundFault",
  )
}

pub fn parse_invalid_db_parameter_group_state_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "InvalidDBParameterGroupState",
  )
}

pub fn parse_db_instance_automated_backup_quota_exceeded_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "DBInstanceAutomatedBackupQuotaExceeded",
  )
}

pub fn parse_db_instance_automated_backup_not_found_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "DBInstanceAutomatedBackupNotFound",
  )
}

pub fn parse_invalid_db_instance_automated_backup_state_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "InvalidDBInstanceAutomatedBackupState",
  )
}

pub fn parse_invalid_db_proxy_endpoint_state_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "InvalidDBProxyEndpointStateFault",
  )
}

pub fn parse_invalid_db_subnet_state_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "InvalidDBSubnetStateFault")
}

pub fn parse_invalid_event_subscription_state_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "InvalidEventSubscriptionState",
  )
}

pub fn parse_invalid_integration_state_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "InvalidIntegrationStateFault",
  )
}

pub fn parse_invalid_option_group_state_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "InvalidOptionGroupStateFault",
  )
}

pub fn parse_db_proxy_target_not_found_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "DBProxyTargetNotFoundFault")
}

pub fn parse_db_cluster_backtrack_not_found_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "DBClusterBacktrackNotFoundFault",
  )
}

pub fn parse_db_instance_not_ready_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "DBInstanceNotReady")
}

pub fn parse_reserved_db_instance_not_found_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "ReservedDBInstanceNotFound")
}

pub fn parse_reserved_db_instances_offering_not_found_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "ReservedDBInstancesOfferingNotFound",
  )
}

pub fn parse_invalid_resource_state_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "InvalidResourceStateFault")
}

pub fn parse_db_log_file_not_found_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "DBLogFileNotFoundFault")
}

pub fn parse_invalid_db_cluster_capacity_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "InvalidDBClusterCapacityFault",
  )
}

pub fn parse_storage_type_not_available_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "StorageTypeNotAvailableFault",
  )
}

pub fn parse_shared_snapshot_quota_exceeded_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "SharedSnapshotQuotaExceeded")
}

pub fn parse_db_upgrade_dependency_failure_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "DBUpgradeDependencyFailure")
}

pub fn parse_subnet_already_in_use_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "SubnetAlreadyInUse")
}

pub fn parse_reserved_db_instance_already_exists_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "ReservedDBInstanceAlreadyExists",
  )
}

pub fn parse_reserved_db_instance_quota_exceeded_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "ReservedDBInstanceQuotaExceeded",
  )
}

pub fn parse_db_proxy_target_already_registered_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "DBProxyTargetAlreadyRegisteredFault",
  )
}

pub fn parse_insufficient_available_i_ps_in_subnet_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "InsufficientAvailableIPsInSubnetFault",
  )
}

pub fn parse_db_cluster_role_not_found_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "DBClusterRoleNotFound")
}

pub fn parse_db_instance_role_not_found_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "DBInstanceRoleNotFound")
}

pub fn parse_invalid_s3_bucket_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "InvalidS3BucketFault")
}

pub fn parse_insufficient_db_cluster_capacity_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "InsufficientDBClusterCapacityFault",
  )
}

pub fn parse_invalid_restore_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "InvalidRestoreFault")
}

pub fn parse_point_in_time_restore_not_enabled_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(
    headers,
    body,
    "PointInTimeRestoreNotEnabled",
  )
}

pub fn parse_export_task_already_exists_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "ExportTaskAlreadyExists")
}

pub fn parse_iam_role_missing_permissions_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "IamRoleMissingPermissions")
}

pub fn parse_iam_role_not_found_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "IamRoleNotFound")
}

pub fn parse_invalid_export_only_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "InvalidExportOnly")
}

pub fn parse_invalid_export_source_state_fault_response(
  _code: Int,
  headers: dict.Dict(String, String),
  body: BitArray,
) -> Result(Nil, String) {
  runtime.check_error_type_matches(headers, body, "InvalidExportSourceState")
}