// Code generated by software.amazon.smithy.rust.codegen.smithy-rs. DO NOT EDIT.
#[non_exhaustive]
#[derive(
    std::clone::Clone,
    std::cmp::Eq,
    std::cmp::Ord,
    std::cmp::PartialEq,
    std::cmp::PartialOrd,
    std::fmt::Debug,
    std::hash::Hash,
)]
pub enum SigningAlgorithmSpec {
    EcdsaSha256,
    EcdsaSha384,
    EcdsaSha512,
    RsassaPkcs1V15Sha256,
    RsassaPkcs1V15Sha384,
    RsassaPkcs1V15Sha512,
    RsassaPssSha256,
    RsassaPssSha384,
    RsassaPssSha512,
    Unknown(String),
}
impl std::convert::From<&str> for SigningAlgorithmSpec {
    fn from(s: &str) -> Self {
        match s {
            "ECDSA_SHA_256" => SigningAlgorithmSpec::EcdsaSha256,
            "ECDSA_SHA_384" => SigningAlgorithmSpec::EcdsaSha384,
            "ECDSA_SHA_512" => SigningAlgorithmSpec::EcdsaSha512,
            "RSASSA_PKCS1_V1_5_SHA_256" => SigningAlgorithmSpec::RsassaPkcs1V15Sha256,
            "RSASSA_PKCS1_V1_5_SHA_384" => SigningAlgorithmSpec::RsassaPkcs1V15Sha384,
            "RSASSA_PKCS1_V1_5_SHA_512" => SigningAlgorithmSpec::RsassaPkcs1V15Sha512,
            "RSASSA_PSS_SHA_256" => SigningAlgorithmSpec::RsassaPssSha256,
            "RSASSA_PSS_SHA_384" => SigningAlgorithmSpec::RsassaPssSha384,
            "RSASSA_PSS_SHA_512" => SigningAlgorithmSpec::RsassaPssSha512,
            other => SigningAlgorithmSpec::Unknown(other.to_owned()),
        }
    }
}

impl std::str::FromStr for SigningAlgorithmSpec {
    type Err = std::convert::Infallible;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Ok(SigningAlgorithmSpec::from(s))
    }
}

impl SigningAlgorithmSpec {
    pub fn as_str(&self) -> &str {
        match self {
            SigningAlgorithmSpec::EcdsaSha256 => "ECDSA_SHA_256",
            SigningAlgorithmSpec::EcdsaSha384 => "ECDSA_SHA_384",
            SigningAlgorithmSpec::EcdsaSha512 => "ECDSA_SHA_512",
            SigningAlgorithmSpec::RsassaPkcs1V15Sha256 => "RSASSA_PKCS1_V1_5_SHA_256",
            SigningAlgorithmSpec::RsassaPkcs1V15Sha384 => "RSASSA_PKCS1_V1_5_SHA_384",
            SigningAlgorithmSpec::RsassaPkcs1V15Sha512 => "RSASSA_PKCS1_V1_5_SHA_512",
            SigningAlgorithmSpec::RsassaPssSha256 => "RSASSA_PSS_SHA_256",
            SigningAlgorithmSpec::RsassaPssSha384 => "RSASSA_PSS_SHA_384",
            SigningAlgorithmSpec::RsassaPssSha512 => "RSASSA_PSS_SHA_512",
            SigningAlgorithmSpec::Unknown(s) => s.as_ref(),
        }
    }
}
impl AsRef<str> for SigningAlgorithmSpec {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}

impl serde::Serialize for SigningAlgorithmSpec {
    fn serialize<S>(
        &self,
        serializer: S,
    ) -> Result<<S as serde::Serializer>::Ok, <S as serde::Serializer>::Error>
    where
        S: serde::Serializer,
    {
        serializer.serialize_str(self.as_str())
    }
}

impl<'de> serde::Deserialize<'de> for SigningAlgorithmSpec {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let data = <&str>::deserialize(deserializer)?;
        Ok(Self::from(data))
    }
}

#[non_exhaustive]
#[derive(
    std::clone::Clone,
    std::cmp::Eq,
    std::cmp::Ord,
    std::cmp::PartialEq,
    std::cmp::PartialOrd,
    std::fmt::Debug,
    std::hash::Hash,
)]
pub enum MessageType {
    Digest,
    Raw,
    Unknown(String),
}
impl std::convert::From<&str> for MessageType {
    fn from(s: &str) -> Self {
        match s {
            "DIGEST" => MessageType::Digest,
            "RAW" => MessageType::Raw,
            other => MessageType::Unknown(other.to_owned()),
        }
    }
}

impl std::str::FromStr for MessageType {
    type Err = std::convert::Infallible;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Ok(MessageType::from(s))
    }
}

impl MessageType {
    pub fn as_str(&self) -> &str {
        match self {
            MessageType::Digest => "DIGEST",
            MessageType::Raw => "RAW",
            MessageType::Unknown(s) => s.as_ref(),
        }
    }
}
impl AsRef<str> for MessageType {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}

impl serde::Serialize for MessageType {
    fn serialize<S>(
        &self,
        serializer: S,
    ) -> Result<<S as serde::Serializer>::Ok, <S as serde::Serializer>::Error>
    where
        S: serde::Serializer,
    {
        serializer.serialize_str(self.as_str())
    }
}

impl<'de> serde::Deserialize<'de> for MessageType {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let data = <&str>::deserialize(deserializer)?;
        Ok(Self::from(data))
    }
}

/// <p>A key-value pair. A tag consists of a tag key and a tag value. Tag keys and tag values are
/// both required, but tag values can be empty (null) strings.</p>
/// <p>For information about the rules that apply to tag keys and tag values, see <a href="https://docs.aws.amazon.com/awsaccountbilling/latest/aboutv2/allocation-tag-restrictions.html">User-Defined Tag Restrictions</a> in the <i>AWS Billing and Cost Management User
/// Guide</i>.</p>
#[non_exhaustive]
#[derive(serde::Deserialize, serde::Serialize, std::clone::Clone, std::cmp::PartialEq)]
pub struct Tag {
    /// <p>The key of the tag.</p>
    #[serde(rename = "TagKey")]
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub tag_key: std::option::Option<std::string::String>,
    /// <p>The value of the tag.</p>
    #[serde(rename = "TagValue")]
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub tag_value: std::option::Option<std::string::String>,
}
impl std::fmt::Debug for Tag {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        let mut formatter = f.debug_struct("Tag");
        formatter.field("tag_key", &self.tag_key);
        formatter.field("tag_value", &self.tag_value);
        formatter.finish()
    }
}
/// See [`Tag`](crate::model::Tag)
pub mod tag {
    /// A builder for [`Tag`](crate::model::Tag)
    #[non_exhaustive]
    #[derive(std::default::Default, std::clone::Clone, std::cmp::PartialEq, std::fmt::Debug)]
    pub struct Builder {
        tag_key: std::option::Option<std::string::String>,
        tag_value: std::option::Option<std::string::String>,
    }
    impl Builder {
        /// <p>The key of the tag.</p>
        pub fn tag_key(mut self, inp: impl Into<std::string::String>) -> Self {
            self.tag_key = Some(inp.into());
            self
        }
        pub fn set_tag_key(mut self, inp: std::option::Option<std::string::String>) -> Self {
            self.tag_key = inp;
            self
        }
        /// <p>The value of the tag.</p>
        pub fn tag_value(mut self, inp: impl Into<std::string::String>) -> Self {
            self.tag_value = Some(inp.into());
            self
        }
        pub fn set_tag_value(mut self, inp: std::option::Option<std::string::String>) -> Self {
            self.tag_value = inp;
            self
        }
        /// Consumes the builder and constructs a [`Tag`](crate::model::Tag)
        pub fn build(self) -> crate::model::Tag {
            crate::model::Tag {
                tag_key: self.tag_key,
                tag_value: self.tag_value,
            }
        }
    }
}
impl Tag {
    /// Creates a new builder-style object to manufacture [`Tag`](crate::model::Tag)
    pub fn builder() -> crate::model::tag::Builder {
        crate::model::tag::Builder::default()
    }
}

#[non_exhaustive]
#[derive(
    std::clone::Clone,
    std::cmp::Eq,
    std::cmp::Ord,
    std::cmp::PartialEq,
    std::cmp::PartialOrd,
    std::fmt::Debug,
    std::hash::Hash,
)]
pub enum EncryptionAlgorithmSpec {
    RsaesOaepSha1,
    RsaesOaepSha256,
    SymmetricDefault,
    Unknown(String),
}
impl std::convert::From<&str> for EncryptionAlgorithmSpec {
    fn from(s: &str) -> Self {
        match s {
            "RSAES_OAEP_SHA_1" => EncryptionAlgorithmSpec::RsaesOaepSha1,
            "RSAES_OAEP_SHA_256" => EncryptionAlgorithmSpec::RsaesOaepSha256,
            "SYMMETRIC_DEFAULT" => EncryptionAlgorithmSpec::SymmetricDefault,
            other => EncryptionAlgorithmSpec::Unknown(other.to_owned()),
        }
    }
}

impl std::str::FromStr for EncryptionAlgorithmSpec {
    type Err = std::convert::Infallible;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Ok(EncryptionAlgorithmSpec::from(s))
    }
}

impl EncryptionAlgorithmSpec {
    pub fn as_str(&self) -> &str {
        match self {
            EncryptionAlgorithmSpec::RsaesOaepSha1 => "RSAES_OAEP_SHA_1",
            EncryptionAlgorithmSpec::RsaesOaepSha256 => "RSAES_OAEP_SHA_256",
            EncryptionAlgorithmSpec::SymmetricDefault => "SYMMETRIC_DEFAULT",
            EncryptionAlgorithmSpec::Unknown(s) => s.as_ref(),
        }
    }
}
impl AsRef<str> for EncryptionAlgorithmSpec {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}

impl serde::Serialize for EncryptionAlgorithmSpec {
    fn serialize<S>(
        &self,
        serializer: S,
    ) -> Result<<S as serde::Serializer>::Ok, <S as serde::Serializer>::Error>
    where
        S: serde::Serializer,
    {
        serializer.serialize_str(self.as_str())
    }
}

impl<'de> serde::Deserialize<'de> for EncryptionAlgorithmSpec {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let data = <&str>::deserialize(deserializer)?;
        Ok(Self::from(data))
    }
}

/// <p>Contains information about a grant.</p>
#[non_exhaustive]
#[derive(serde::Deserialize, serde::Serialize, std::clone::Clone, std::cmp::PartialEq)]
pub struct GrantListEntry {
    /// <p>The unique identifier for the customer master key (CMK) to which the grant applies.</p>
    #[serde(rename = "KeyId")]
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub key_id: std::option::Option<std::string::String>,
    /// <p>The unique identifier for the grant.</p>
    #[serde(rename = "GrantId")]
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub grant_id: std::option::Option<std::string::String>,
    /// <p>The friendly name that identifies the grant. If a name was provided in the <a>CreateGrant</a> request, that name is returned. Otherwise this value is null.</p>
    #[serde(rename = "Name")]
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub name: std::option::Option<std::string::String>,
    /// <p>The date and time when the grant was created.</p>
    #[serde(rename = "CreationDate")]
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(
        serialize_with = "crate::serde_util::stdoptionoptionsmithytypesinstant_epoch_seconds_ser"
    )]
    #[serde(
        deserialize_with = "crate::serde_util::stdoptionoptionsmithytypesinstant_epoch_seconds_deser"
    )]
    #[serde(default)]
    pub creation_date: std::option::Option<smithy_types::Instant>,
    /// <p>The identity that gets the permissions in the grant.</p>
    /// <p>The <code>GranteePrincipal</code> field in the <code>ListGrants</code> response usually contains the
    /// user or role designated as the grantee principal in the grant. However, when the grantee
    /// principal in the grant is an AWS service, the <code>GranteePrincipal</code> field contains
    /// the <a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_principal.html#principal-services">service
    /// principal</a>, which might represent several different grantee principals.</p>
    #[serde(rename = "GranteePrincipal")]
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub grantee_principal: std::option::Option<std::string::String>,
    /// <p>The principal that can retire the grant.</p>
    #[serde(rename = "RetiringPrincipal")]
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub retiring_principal: std::option::Option<std::string::String>,
    /// <p>The AWS account under which the grant was issued.</p>
    #[serde(rename = "IssuingAccount")]
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub issuing_account: std::option::Option<std::string::String>,
    /// <p>The list of operations permitted by the grant.</p>
    #[serde(rename = "Operations")]
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub operations: std::option::Option<std::vec::Vec<crate::model::GrantOperation>>,
    /// <p>A list of key-value pairs that must be present in the encryption context of certain
    /// subsequent operations that the grant allows.</p>
    #[serde(rename = "Constraints")]
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub constraints: std::option::Option<crate::model::GrantConstraints>,
}
impl std::fmt::Debug for GrantListEntry {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        let mut formatter = f.debug_struct("GrantListEntry");
        formatter.field("key_id", &self.key_id);
        formatter.field("grant_id", &self.grant_id);
        formatter.field("name", &self.name);
        formatter.field("creation_date", &self.creation_date);
        formatter.field("grantee_principal", &self.grantee_principal);
        formatter.field("retiring_principal", &self.retiring_principal);
        formatter.field("issuing_account", &self.issuing_account);
        formatter.field("operations", &self.operations);
        formatter.field("constraints", &self.constraints);
        formatter.finish()
    }
}
/// See [`GrantListEntry`](crate::model::GrantListEntry)
pub mod grant_list_entry {
    /// A builder for [`GrantListEntry`](crate::model::GrantListEntry)
    #[non_exhaustive]
    #[derive(std::default::Default, std::clone::Clone, std::cmp::PartialEq, std::fmt::Debug)]
    pub struct Builder {
        key_id: std::option::Option<std::string::String>,
        grant_id: std::option::Option<std::string::String>,
        name: std::option::Option<std::string::String>,
        creation_date: std::option::Option<smithy_types::Instant>,
        grantee_principal: std::option::Option<std::string::String>,
        retiring_principal: std::option::Option<std::string::String>,
        issuing_account: std::option::Option<std::string::String>,
        operations: std::option::Option<std::vec::Vec<crate::model::GrantOperation>>,
        constraints: std::option::Option<crate::model::GrantConstraints>,
    }
    impl Builder {
        /// <p>The unique identifier for the customer master key (CMK) to which the grant applies.</p>
        pub fn key_id(mut self, inp: impl Into<std::string::String>) -> Self {
            self.key_id = Some(inp.into());
            self
        }
        pub fn set_key_id(mut self, inp: std::option::Option<std::string::String>) -> Self {
            self.key_id = inp;
            self
        }
        /// <p>The unique identifier for the grant.</p>
        pub fn grant_id(mut self, inp: impl Into<std::string::String>) -> Self {
            self.grant_id = Some(inp.into());
            self
        }
        pub fn set_grant_id(mut self, inp: std::option::Option<std::string::String>) -> Self {
            self.grant_id = inp;
            self
        }
        /// <p>The friendly name that identifies the grant. If a name was provided in the <a>CreateGrant</a> request, that name is returned. Otherwise this value is null.</p>
        pub fn name(mut self, inp: impl Into<std::string::String>) -> Self {
            self.name = Some(inp.into());
            self
        }
        pub fn set_name(mut self, inp: std::option::Option<std::string::String>) -> Self {
            self.name = inp;
            self
        }
        /// <p>The date and time when the grant was created.</p>
        pub fn creation_date(mut self, inp: smithy_types::Instant) -> Self {
            self.creation_date = Some(inp);
            self
        }
        pub fn set_creation_date(
            mut self,
            inp: std::option::Option<smithy_types::Instant>,
        ) -> Self {
            self.creation_date = inp;
            self
        }
        /// <p>The identity that gets the permissions in the grant.</p>
        /// <p>The <code>GranteePrincipal</code> field in the <code>ListGrants</code> response usually contains the
        /// user or role designated as the grantee principal in the grant. However, when the grantee
        /// principal in the grant is an AWS service, the <code>GranteePrincipal</code> field contains
        /// the <a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_principal.html#principal-services">service
        /// principal</a>, which might represent several different grantee principals.</p>
        pub fn grantee_principal(mut self, inp: impl Into<std::string::String>) -> Self {
            self.grantee_principal = Some(inp.into());
            self
        }
        pub fn set_grantee_principal(
            mut self,
            inp: std::option::Option<std::string::String>,
        ) -> Self {
            self.grantee_principal = inp;
            self
        }
        /// <p>The principal that can retire the grant.</p>
        pub fn retiring_principal(mut self, inp: impl Into<std::string::String>) -> Self {
            self.retiring_principal = Some(inp.into());
            self
        }
        pub fn set_retiring_principal(
            mut self,
            inp: std::option::Option<std::string::String>,
        ) -> Self {
            self.retiring_principal = inp;
            self
        }
        /// <p>The AWS account under which the grant was issued.</p>
        pub fn issuing_account(mut self, inp: impl Into<std::string::String>) -> Self {
            self.issuing_account = Some(inp.into());
            self
        }
        pub fn set_issuing_account(
            mut self,
            inp: std::option::Option<std::string::String>,
        ) -> Self {
            self.issuing_account = inp;
            self
        }
        pub fn operations(mut self, inp: impl Into<crate::model::GrantOperation>) -> Self {
            let mut v = self.operations.unwrap_or_default();
            v.push(inp.into());
            self.operations = Some(v);
            self
        }
        pub fn set_operations(
            mut self,
            inp: std::option::Option<std::vec::Vec<crate::model::GrantOperation>>,
        ) -> Self {
            self.operations = inp;
            self
        }
        /// <p>A list of key-value pairs that must be present in the encryption context of certain
        /// subsequent operations that the grant allows.</p>
        pub fn constraints(mut self, inp: crate::model::GrantConstraints) -> Self {
            self.constraints = Some(inp);
            self
        }
        pub fn set_constraints(
            mut self,
            inp: std::option::Option<crate::model::GrantConstraints>,
        ) -> Self {
            self.constraints = inp;
            self
        }
        /// Consumes the builder and constructs a [`GrantListEntry`](crate::model::GrantListEntry)
        pub fn build(self) -> crate::model::GrantListEntry {
            crate::model::GrantListEntry {
                key_id: self.key_id,
                grant_id: self.grant_id,
                name: self.name,
                creation_date: self.creation_date,
                grantee_principal: self.grantee_principal,
                retiring_principal: self.retiring_principal,
                issuing_account: self.issuing_account,
                operations: self.operations,
                constraints: self.constraints,
            }
        }
    }
}
impl GrantListEntry {
    /// Creates a new builder-style object to manufacture [`GrantListEntry`](crate::model::GrantListEntry)
    pub fn builder() -> crate::model::grant_list_entry::Builder {
        crate::model::grant_list_entry::Builder::default()
    }
}

/// <p>Use this structure to allow <a href="https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#cryptographic-operations">cryptographic operations</a> in the grant only when the operation request
/// includes the specified <a href="https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#encrypt_context">encryption context</a>. </p>
/// <p>AWS KMS applies the grant constraints only to cryptographic operations that support an
/// encryption context, that is, all cryptographic operations with a <a href="https://docs.aws.amazon.com/kms/latest/developerguide/symm-asymm-concepts.html#symmetric-cmks">symmetric CMK</a>. Grant
/// constraints are not applied to operations that do not support an encryption context, such as
/// cryptographic operations with asymmetric CMKs and management operations, such as <a>DescribeKey</a> or <a>RetireGrant</a>.</p>
/// <important>
/// <p>In a cryptographic operation, the encryption context in the decryption operation must be
/// an exact, case-sensitive match for the keys and values in the encryption context of the
/// encryption operation. Only the order of the pairs can vary.</p>
/// <p>However, in a grant constraint, the key in each key-value pair is not case sensitive,
/// but the value is case sensitive.</p>
/// <p>To avoid confusion, do not use multiple encryption context pairs that differ only by
/// case. To require a fully case-sensitive encryption context, use the
/// <code>kms:EncryptionContext:</code> and <code>kms:EncryptionContextKeys</code> conditions
/// in an IAM or key policy. For details, see <a href="https://docs.aws.amazon.com/kms/latest/developerguide/policy-conditions.html#conditions-kms-encryption-context">kms:EncryptionContext:</a> in the <i>
/// <i>AWS Key Management Service Developer Guide</i>
/// </i>.</p>
/// </important>
#[non_exhaustive]
#[derive(serde::Deserialize, serde::Serialize, std::clone::Clone, std::cmp::PartialEq)]
pub struct GrantConstraints {
    /// <p>A list of key-value pairs that must be included in the encryption context of the
    /// <a href="https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#cryptographic-operations">cryptographic operation</a> request. The grant allows the cryptographic operation only when the
    /// encryption context in the request includes the key-value pairs specified in this constraint,
    /// although it can include additional key-value pairs.</p>
    #[serde(rename = "EncryptionContextSubset")]
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub encryption_context_subset:
        std::option::Option<std::collections::HashMap<std::string::String, std::string::String>>,
    /// <p>A list of key-value pairs that must match the encryption context in the <a href="https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#cryptographic-operations">cryptographic operation</a> request. The grant allows the operation only when the encryption context in the
    /// request is the same as the encryption context specified in this constraint.</p>
    #[serde(rename = "EncryptionContextEquals")]
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub encryption_context_equals:
        std::option::Option<std::collections::HashMap<std::string::String, std::string::String>>,
}
impl std::fmt::Debug for GrantConstraints {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        let mut formatter = f.debug_struct("GrantConstraints");
        formatter.field("encryption_context_subset", &self.encryption_context_subset);
        formatter.field("encryption_context_equals", &self.encryption_context_equals);
        formatter.finish()
    }
}
/// See [`GrantConstraints`](crate::model::GrantConstraints)
pub mod grant_constraints {
    /// A builder for [`GrantConstraints`](crate::model::GrantConstraints)
    #[non_exhaustive]
    #[derive(std::default::Default, std::clone::Clone, std::cmp::PartialEq, std::fmt::Debug)]
    pub struct Builder {
        encryption_context_subset: std::option::Option<
            std::collections::HashMap<std::string::String, std::string::String>,
        >,
        encryption_context_equals: std::option::Option<
            std::collections::HashMap<std::string::String, std::string::String>,
        >,
    }
    impl Builder {
        pub fn encryption_context_subset(
            mut self,
            k: impl Into<std::string::String>,
            v: impl Into<std::string::String>,
        ) -> Self {
            let mut hash_map = self.encryption_context_subset.unwrap_or_default();
            hash_map.insert(k.into(), v.into());
            self.encryption_context_subset = Some(hash_map);
            self
        }
        pub fn set_encryption_context_subset(
            mut self,
            inp: std::option::Option<
                std::collections::HashMap<std::string::String, std::string::String>,
            >,
        ) -> Self {
            self.encryption_context_subset = inp;
            self
        }
        pub fn encryption_context_equals(
            mut self,
            k: impl Into<std::string::String>,
            v: impl Into<std::string::String>,
        ) -> Self {
            let mut hash_map = self.encryption_context_equals.unwrap_or_default();
            hash_map.insert(k.into(), v.into());
            self.encryption_context_equals = Some(hash_map);
            self
        }
        pub fn set_encryption_context_equals(
            mut self,
            inp: std::option::Option<
                std::collections::HashMap<std::string::String, std::string::String>,
            >,
        ) -> Self {
            self.encryption_context_equals = inp;
            self
        }
        /// Consumes the builder and constructs a [`GrantConstraints`](crate::model::GrantConstraints)
        pub fn build(self) -> crate::model::GrantConstraints {
            crate::model::GrantConstraints {
                encryption_context_subset: self.encryption_context_subset,
                encryption_context_equals: self.encryption_context_equals,
            }
        }
    }
}
impl GrantConstraints {
    /// Creates a new builder-style object to manufacture [`GrantConstraints`](crate::model::GrantConstraints)
    pub fn builder() -> crate::model::grant_constraints::Builder {
        crate::model::grant_constraints::Builder::default()
    }
}

#[non_exhaustive]
#[derive(
    std::clone::Clone,
    std::cmp::Eq,
    std::cmp::Ord,
    std::cmp::PartialEq,
    std::cmp::PartialOrd,
    std::fmt::Debug,
    std::hash::Hash,
)]
pub enum GrantOperation {
    CreateGrant,
    Decrypt,
    DescribeKey,
    Encrypt,
    GenerateDataKey,
    GenerateDataKeyPair,
    GenerateDataKeyPairWithoutPlaintext,
    GenerateDataKeyWithoutPlaintext,
    GetPublicKey,
    ReEncryptFrom,
    ReEncryptTo,
    RetireGrant,
    Sign,
    Verify,
    Unknown(String),
}
impl std::convert::From<&str> for GrantOperation {
    fn from(s: &str) -> Self {
        match s {
            "CreateGrant" => GrantOperation::CreateGrant,
            "Decrypt" => GrantOperation::Decrypt,
            "DescribeKey" => GrantOperation::DescribeKey,
            "Encrypt" => GrantOperation::Encrypt,
            "GenerateDataKey" => GrantOperation::GenerateDataKey,
            "GenerateDataKeyPair" => GrantOperation::GenerateDataKeyPair,
            "GenerateDataKeyPairWithoutPlaintext" => {
                GrantOperation::GenerateDataKeyPairWithoutPlaintext
            }
            "GenerateDataKeyWithoutPlaintext" => GrantOperation::GenerateDataKeyWithoutPlaintext,
            "GetPublicKey" => GrantOperation::GetPublicKey,
            "ReEncryptFrom" => GrantOperation::ReEncryptFrom,
            "ReEncryptTo" => GrantOperation::ReEncryptTo,
            "RetireGrant" => GrantOperation::RetireGrant,
            "Sign" => GrantOperation::Sign,
            "Verify" => GrantOperation::Verify,
            other => GrantOperation::Unknown(other.to_owned()),
        }
    }
}

impl std::str::FromStr for GrantOperation {
    type Err = std::convert::Infallible;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Ok(GrantOperation::from(s))
    }
}

impl GrantOperation {
    pub fn as_str(&self) -> &str {
        match self {
            GrantOperation::CreateGrant => "CreateGrant",
            GrantOperation::Decrypt => "Decrypt",
            GrantOperation::DescribeKey => "DescribeKey",
            GrantOperation::Encrypt => "Encrypt",
            GrantOperation::GenerateDataKey => "GenerateDataKey",
            GrantOperation::GenerateDataKeyPair => "GenerateDataKeyPair",
            GrantOperation::GenerateDataKeyPairWithoutPlaintext => {
                "GenerateDataKeyPairWithoutPlaintext"
            }
            GrantOperation::GenerateDataKeyWithoutPlaintext => "GenerateDataKeyWithoutPlaintext",
            GrantOperation::GetPublicKey => "GetPublicKey",
            GrantOperation::ReEncryptFrom => "ReEncryptFrom",
            GrantOperation::ReEncryptTo => "ReEncryptTo",
            GrantOperation::RetireGrant => "RetireGrant",
            GrantOperation::Sign => "Sign",
            GrantOperation::Verify => "Verify",
            GrantOperation::Unknown(s) => s.as_ref(),
        }
    }
}
impl AsRef<str> for GrantOperation {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}

impl serde::Serialize for GrantOperation {
    fn serialize<S>(
        &self,
        serializer: S,
    ) -> Result<<S as serde::Serializer>::Ok, <S as serde::Serializer>::Error>
    where
        S: serde::Serializer,
    {
        serializer.serialize_str(self.as_str())
    }
}

impl<'de> serde::Deserialize<'de> for GrantOperation {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let data = <&str>::deserialize(deserializer)?;
        Ok(Self::from(data))
    }
}

/// <p>Contains information about each entry in the key list.</p>
#[non_exhaustive]
#[derive(serde::Deserialize, serde::Serialize, std::clone::Clone, std::cmp::PartialEq)]
pub struct KeyListEntry {
    /// <p>Unique identifier of the key.</p>
    #[serde(rename = "KeyId")]
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub key_id: std::option::Option<std::string::String>,
    /// <p>ARN of the key.</p>
    #[serde(rename = "KeyArn")]
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub key_arn: std::option::Option<std::string::String>,
}
impl std::fmt::Debug for KeyListEntry {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        let mut formatter = f.debug_struct("KeyListEntry");
        formatter.field("key_id", &self.key_id);
        formatter.field("key_arn", &self.key_arn);
        formatter.finish()
    }
}
/// See [`KeyListEntry`](crate::model::KeyListEntry)
pub mod key_list_entry {
    /// A builder for [`KeyListEntry`](crate::model::KeyListEntry)
    #[non_exhaustive]
    #[derive(std::default::Default, std::clone::Clone, std::cmp::PartialEq, std::fmt::Debug)]
    pub struct Builder {
        key_id: std::option::Option<std::string::String>,
        key_arn: std::option::Option<std::string::String>,
    }
    impl Builder {
        /// <p>Unique identifier of the key.</p>
        pub fn key_id(mut self, inp: impl Into<std::string::String>) -> Self {
            self.key_id = Some(inp.into());
            self
        }
        pub fn set_key_id(mut self, inp: std::option::Option<std::string::String>) -> Self {
            self.key_id = inp;
            self
        }
        /// <p>ARN of the key.</p>
        pub fn key_arn(mut self, inp: impl Into<std::string::String>) -> Self {
            self.key_arn = Some(inp.into());
            self
        }
        pub fn set_key_arn(mut self, inp: std::option::Option<std::string::String>) -> Self {
            self.key_arn = inp;
            self
        }
        /// Consumes the builder and constructs a [`KeyListEntry`](crate::model::KeyListEntry)
        pub fn build(self) -> crate::model::KeyListEntry {
            crate::model::KeyListEntry {
                key_id: self.key_id,
                key_arn: self.key_arn,
            }
        }
    }
}
impl KeyListEntry {
    /// Creates a new builder-style object to manufacture [`KeyListEntry`](crate::model::KeyListEntry)
    pub fn builder() -> crate::model::key_list_entry::Builder {
        crate::model::key_list_entry::Builder::default()
    }
}

/// <p>Contains information about an alias.</p>
#[non_exhaustive]
#[derive(serde::Deserialize, serde::Serialize, std::clone::Clone, std::cmp::PartialEq)]
pub struct AliasListEntry {
    /// <p>String that contains the alias. This value begins with <code>alias/</code>.</p>
    #[serde(rename = "AliasName")]
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub alias_name: std::option::Option<std::string::String>,
    /// <p>String that contains the key ARN.</p>
    #[serde(rename = "AliasArn")]
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub alias_arn: std::option::Option<std::string::String>,
    /// <p>String that contains the key identifier of the CMK associated with the alias.</p>
    #[serde(rename = "TargetKeyId")]
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub target_key_id: std::option::Option<std::string::String>,
    /// <p>Date and time that the alias was most recently created in the account and Region. Formatted as Unix time.</p>
    #[serde(rename = "CreationDate")]
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(
        serialize_with = "crate::serde_util::stdoptionoptionsmithytypesinstant_epoch_seconds_ser"
    )]
    #[serde(
        deserialize_with = "crate::serde_util::stdoptionoptionsmithytypesinstant_epoch_seconds_deser"
    )]
    #[serde(default)]
    pub creation_date: std::option::Option<smithy_types::Instant>,
    /// <p>Date and time that the alias was most recently associated with a CMK in the account and Region. Formatted as Unix time.</p>
    #[serde(rename = "LastUpdatedDate")]
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(
        serialize_with = "crate::serde_util::stdoptionoptionsmithytypesinstant_epoch_seconds_ser"
    )]
    #[serde(
        deserialize_with = "crate::serde_util::stdoptionoptionsmithytypesinstant_epoch_seconds_deser"
    )]
    #[serde(default)]
    pub last_updated_date: std::option::Option<smithy_types::Instant>,
}
impl std::fmt::Debug for AliasListEntry {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        let mut formatter = f.debug_struct("AliasListEntry");
        formatter.field("alias_name", &self.alias_name);
        formatter.field("alias_arn", &self.alias_arn);
        formatter.field("target_key_id", &self.target_key_id);
        formatter.field("creation_date", &self.creation_date);
        formatter.field("last_updated_date", &self.last_updated_date);
        formatter.finish()
    }
}
/// See [`AliasListEntry`](crate::model::AliasListEntry)
pub mod alias_list_entry {
    /// A builder for [`AliasListEntry`](crate::model::AliasListEntry)
    #[non_exhaustive]
    #[derive(std::default::Default, std::clone::Clone, std::cmp::PartialEq, std::fmt::Debug)]
    pub struct Builder {
        alias_name: std::option::Option<std::string::String>,
        alias_arn: std::option::Option<std::string::String>,
        target_key_id: std::option::Option<std::string::String>,
        creation_date: std::option::Option<smithy_types::Instant>,
        last_updated_date: std::option::Option<smithy_types::Instant>,
    }
    impl Builder {
        /// <p>String that contains the alias. This value begins with <code>alias/</code>.</p>
        pub fn alias_name(mut self, inp: impl Into<std::string::String>) -> Self {
            self.alias_name = Some(inp.into());
            self
        }
        pub fn set_alias_name(mut self, inp: std::option::Option<std::string::String>) -> Self {
            self.alias_name = inp;
            self
        }
        /// <p>String that contains the key ARN.</p>
        pub fn alias_arn(mut self, inp: impl Into<std::string::String>) -> Self {
            self.alias_arn = Some(inp.into());
            self
        }
        pub fn set_alias_arn(mut self, inp: std::option::Option<std::string::String>) -> Self {
            self.alias_arn = inp;
            self
        }
        /// <p>String that contains the key identifier of the CMK associated with the alias.</p>
        pub fn target_key_id(mut self, inp: impl Into<std::string::String>) -> Self {
            self.target_key_id = Some(inp.into());
            self
        }
        pub fn set_target_key_id(mut self, inp: std::option::Option<std::string::String>) -> Self {
            self.target_key_id = inp;
            self
        }
        /// <p>Date and time that the alias was most recently created in the account and Region. Formatted as Unix time.</p>
        pub fn creation_date(mut self, inp: smithy_types::Instant) -> Self {
            self.creation_date = Some(inp);
            self
        }
        pub fn set_creation_date(
            mut self,
            inp: std::option::Option<smithy_types::Instant>,
        ) -> Self {
            self.creation_date = inp;
            self
        }
        /// <p>Date and time that the alias was most recently associated with a CMK in the account and Region. Formatted as Unix time.</p>
        pub fn last_updated_date(mut self, inp: smithy_types::Instant) -> Self {
            self.last_updated_date = Some(inp);
            self
        }
        pub fn set_last_updated_date(
            mut self,
            inp: std::option::Option<smithy_types::Instant>,
        ) -> Self {
            self.last_updated_date = inp;
            self
        }
        /// Consumes the builder and constructs a [`AliasListEntry`](crate::model::AliasListEntry)
        pub fn build(self) -> crate::model::AliasListEntry {
            crate::model::AliasListEntry {
                alias_name: self.alias_name,
                alias_arn: self.alias_arn,
                target_key_id: self.target_key_id,
                creation_date: self.creation_date,
                last_updated_date: self.last_updated_date,
            }
        }
    }
}
impl AliasListEntry {
    /// Creates a new builder-style object to manufacture [`AliasListEntry`](crate::model::AliasListEntry)
    pub fn builder() -> crate::model::alias_list_entry::Builder {
        crate::model::alias_list_entry::Builder::default()
    }
}

#[non_exhaustive]
#[derive(
    std::clone::Clone,
    std::cmp::Eq,
    std::cmp::Ord,
    std::cmp::PartialEq,
    std::cmp::PartialOrd,
    std::fmt::Debug,
    std::hash::Hash,
)]
pub enum ExpirationModelType {
    KeyMaterialDoesNotExpire,
    KeyMaterialExpires,
    Unknown(String),
}
impl std::convert::From<&str> for ExpirationModelType {
    fn from(s: &str) -> Self {
        match s {
            "KEY_MATERIAL_DOES_NOT_EXPIRE" => ExpirationModelType::KeyMaterialDoesNotExpire,
            "KEY_MATERIAL_EXPIRES" => ExpirationModelType::KeyMaterialExpires,
            other => ExpirationModelType::Unknown(other.to_owned()),
        }
    }
}

impl std::str::FromStr for ExpirationModelType {
    type Err = std::convert::Infallible;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Ok(ExpirationModelType::from(s))
    }
}

impl ExpirationModelType {
    pub fn as_str(&self) -> &str {
        match self {
            ExpirationModelType::KeyMaterialDoesNotExpire => "KEY_MATERIAL_DOES_NOT_EXPIRE",
            ExpirationModelType::KeyMaterialExpires => "KEY_MATERIAL_EXPIRES",
            ExpirationModelType::Unknown(s) => s.as_ref(),
        }
    }
}
impl AsRef<str> for ExpirationModelType {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}

impl serde::Serialize for ExpirationModelType {
    fn serialize<S>(
        &self,
        serializer: S,
    ) -> Result<<S as serde::Serializer>::Ok, <S as serde::Serializer>::Error>
    where
        S: serde::Serializer,
    {
        serializer.serialize_str(self.as_str())
    }
}

impl<'de> serde::Deserialize<'de> for ExpirationModelType {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let data = <&str>::deserialize(deserializer)?;
        Ok(Self::from(data))
    }
}

#[non_exhaustive]
#[derive(
    std::clone::Clone,
    std::cmp::Eq,
    std::cmp::Ord,
    std::cmp::PartialEq,
    std::cmp::PartialOrd,
    std::fmt::Debug,
    std::hash::Hash,
)]
pub enum KeyUsageType {
    EncryptDecrypt,
    SignVerify,
    Unknown(String),
}
impl std::convert::From<&str> for KeyUsageType {
    fn from(s: &str) -> Self {
        match s {
            "ENCRYPT_DECRYPT" => KeyUsageType::EncryptDecrypt,
            "SIGN_VERIFY" => KeyUsageType::SignVerify,
            other => KeyUsageType::Unknown(other.to_owned()),
        }
    }
}

impl std::str::FromStr for KeyUsageType {
    type Err = std::convert::Infallible;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Ok(KeyUsageType::from(s))
    }
}

impl KeyUsageType {
    pub fn as_str(&self) -> &str {
        match self {
            KeyUsageType::EncryptDecrypt => "ENCRYPT_DECRYPT",
            KeyUsageType::SignVerify => "SIGN_VERIFY",
            KeyUsageType::Unknown(s) => s.as_ref(),
        }
    }
}
impl AsRef<str> for KeyUsageType {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}

impl serde::Serialize for KeyUsageType {
    fn serialize<S>(
        &self,
        serializer: S,
    ) -> Result<<S as serde::Serializer>::Ok, <S as serde::Serializer>::Error>
    where
        S: serde::Serializer,
    {
        serializer.serialize_str(self.as_str())
    }
}

impl<'de> serde::Deserialize<'de> for KeyUsageType {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let data = <&str>::deserialize(deserializer)?;
        Ok(Self::from(data))
    }
}

#[non_exhaustive]
#[derive(
    std::clone::Clone,
    std::cmp::Eq,
    std::cmp::Ord,
    std::cmp::PartialEq,
    std::cmp::PartialOrd,
    std::fmt::Debug,
    std::hash::Hash,
)]
pub enum CustomerMasterKeySpec {
    EccNistP256,
    EccNistP384,
    EccNistP521,
    EccSecgP256K1,
    Rsa2048,
    Rsa3072,
    Rsa4096,
    SymmetricDefault,
    Unknown(String),
}
impl std::convert::From<&str> for CustomerMasterKeySpec {
    fn from(s: &str) -> Self {
        match s {
            "ECC_NIST_P256" => CustomerMasterKeySpec::EccNistP256,
            "ECC_NIST_P384" => CustomerMasterKeySpec::EccNistP384,
            "ECC_NIST_P521" => CustomerMasterKeySpec::EccNistP521,
            "ECC_SECG_P256K1" => CustomerMasterKeySpec::EccSecgP256K1,
            "RSA_2048" => CustomerMasterKeySpec::Rsa2048,
            "RSA_3072" => CustomerMasterKeySpec::Rsa3072,
            "RSA_4096" => CustomerMasterKeySpec::Rsa4096,
            "SYMMETRIC_DEFAULT" => CustomerMasterKeySpec::SymmetricDefault,
            other => CustomerMasterKeySpec::Unknown(other.to_owned()),
        }
    }
}

impl std::str::FromStr for CustomerMasterKeySpec {
    type Err = std::convert::Infallible;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Ok(CustomerMasterKeySpec::from(s))
    }
}

impl CustomerMasterKeySpec {
    pub fn as_str(&self) -> &str {
        match self {
            CustomerMasterKeySpec::EccNistP256 => "ECC_NIST_P256",
            CustomerMasterKeySpec::EccNistP384 => "ECC_NIST_P384",
            CustomerMasterKeySpec::EccNistP521 => "ECC_NIST_P521",
            CustomerMasterKeySpec::EccSecgP256K1 => "ECC_SECG_P256K1",
            CustomerMasterKeySpec::Rsa2048 => "RSA_2048",
            CustomerMasterKeySpec::Rsa3072 => "RSA_3072",
            CustomerMasterKeySpec::Rsa4096 => "RSA_4096",
            CustomerMasterKeySpec::SymmetricDefault => "SYMMETRIC_DEFAULT",
            CustomerMasterKeySpec::Unknown(s) => s.as_ref(),
        }
    }
}
impl AsRef<str> for CustomerMasterKeySpec {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}

impl serde::Serialize for CustomerMasterKeySpec {
    fn serialize<S>(
        &self,
        serializer: S,
    ) -> Result<<S as serde::Serializer>::Ok, <S as serde::Serializer>::Error>
    where
        S: serde::Serializer,
    {
        serializer.serialize_str(self.as_str())
    }
}

impl<'de> serde::Deserialize<'de> for CustomerMasterKeySpec {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let data = <&str>::deserialize(deserializer)?;
        Ok(Self::from(data))
    }
}

#[non_exhaustive]
#[derive(
    std::clone::Clone,
    std::cmp::Eq,
    std::cmp::Ord,
    std::cmp::PartialEq,
    std::cmp::PartialOrd,
    std::fmt::Debug,
    std::hash::Hash,
)]
pub enum WrappingKeySpec {
    Rsa2048,
    Unknown(String),
}
impl std::convert::From<&str> for WrappingKeySpec {
    fn from(s: &str) -> Self {
        match s {
            "RSA_2048" => WrappingKeySpec::Rsa2048,
            other => WrappingKeySpec::Unknown(other.to_owned()),
        }
    }
}

impl std::str::FromStr for WrappingKeySpec {
    type Err = std::convert::Infallible;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Ok(WrappingKeySpec::from(s))
    }
}

impl WrappingKeySpec {
    pub fn as_str(&self) -> &str {
        match self {
            WrappingKeySpec::Rsa2048 => "RSA_2048",
            WrappingKeySpec::Unknown(s) => s.as_ref(),
        }
    }
}
impl AsRef<str> for WrappingKeySpec {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}

impl serde::Serialize for WrappingKeySpec {
    fn serialize<S>(
        &self,
        serializer: S,
    ) -> Result<<S as serde::Serializer>::Ok, <S as serde::Serializer>::Error>
    where
        S: serde::Serializer,
    {
        serializer.serialize_str(self.as_str())
    }
}

impl<'de> serde::Deserialize<'de> for WrappingKeySpec {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let data = <&str>::deserialize(deserializer)?;
        Ok(Self::from(data))
    }
}

#[non_exhaustive]
#[derive(
    std::clone::Clone,
    std::cmp::Eq,
    std::cmp::Ord,
    std::cmp::PartialEq,
    std::cmp::PartialOrd,
    std::fmt::Debug,
    std::hash::Hash,
)]
pub enum AlgorithmSpec {
    RsaesOaepSha1,
    RsaesOaepSha256,
    RsaesPkcs1V15,
    Unknown(String),
}
impl std::convert::From<&str> for AlgorithmSpec {
    fn from(s: &str) -> Self {
        match s {
            "RSAES_OAEP_SHA_1" => AlgorithmSpec::RsaesOaepSha1,
            "RSAES_OAEP_SHA_256" => AlgorithmSpec::RsaesOaepSha256,
            "RSAES_PKCS1_V1_5" => AlgorithmSpec::RsaesPkcs1V15,
            other => AlgorithmSpec::Unknown(other.to_owned()),
        }
    }
}

impl std::str::FromStr for AlgorithmSpec {
    type Err = std::convert::Infallible;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Ok(AlgorithmSpec::from(s))
    }
}

impl AlgorithmSpec {
    pub fn as_str(&self) -> &str {
        match self {
            AlgorithmSpec::RsaesOaepSha1 => "RSAES_OAEP_SHA_1",
            AlgorithmSpec::RsaesOaepSha256 => "RSAES_OAEP_SHA_256",
            AlgorithmSpec::RsaesPkcs1V15 => "RSAES_PKCS1_V1_5",
            AlgorithmSpec::Unknown(s) => s.as_ref(),
        }
    }
}
impl AsRef<str> for AlgorithmSpec {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}

impl serde::Serialize for AlgorithmSpec {
    fn serialize<S>(
        &self,
        serializer: S,
    ) -> Result<<S as serde::Serializer>::Ok, <S as serde::Serializer>::Error>
    where
        S: serde::Serializer,
    {
        serializer.serialize_str(self.as_str())
    }
}

impl<'de> serde::Deserialize<'de> for AlgorithmSpec {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let data = <&str>::deserialize(deserializer)?;
        Ok(Self::from(data))
    }
}

#[non_exhaustive]
#[derive(
    std::clone::Clone,
    std::cmp::Eq,
    std::cmp::Ord,
    std::cmp::PartialEq,
    std::cmp::PartialOrd,
    std::fmt::Debug,
    std::hash::Hash,
)]
pub enum DataKeySpec {
    Aes128,
    Aes256,
    Unknown(String),
}
impl std::convert::From<&str> for DataKeySpec {
    fn from(s: &str) -> Self {
        match s {
            "AES_128" => DataKeySpec::Aes128,
            "AES_256" => DataKeySpec::Aes256,
            other => DataKeySpec::Unknown(other.to_owned()),
        }
    }
}

impl std::str::FromStr for DataKeySpec {
    type Err = std::convert::Infallible;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Ok(DataKeySpec::from(s))
    }
}

impl DataKeySpec {
    pub fn as_str(&self) -> &str {
        match self {
            DataKeySpec::Aes128 => "AES_128",
            DataKeySpec::Aes256 => "AES_256",
            DataKeySpec::Unknown(s) => s.as_ref(),
        }
    }
}
impl AsRef<str> for DataKeySpec {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}

impl serde::Serialize for DataKeySpec {
    fn serialize<S>(
        &self,
        serializer: S,
    ) -> Result<<S as serde::Serializer>::Ok, <S as serde::Serializer>::Error>
    where
        S: serde::Serializer,
    {
        serializer.serialize_str(self.as_str())
    }
}

impl<'de> serde::Deserialize<'de> for DataKeySpec {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let data = <&str>::deserialize(deserializer)?;
        Ok(Self::from(data))
    }
}

#[non_exhaustive]
#[derive(
    std::clone::Clone,
    std::cmp::Eq,
    std::cmp::Ord,
    std::cmp::PartialEq,
    std::cmp::PartialOrd,
    std::fmt::Debug,
    std::hash::Hash,
)]
pub enum DataKeyPairSpec {
    EccNistP256,
    EccNistP384,
    EccNistP521,
    EccSecgP256K1,
    Rsa2048,
    Rsa3072,
    Rsa4096,
    Unknown(String),
}
impl std::convert::From<&str> for DataKeyPairSpec {
    fn from(s: &str) -> Self {
        match s {
            "ECC_NIST_P256" => DataKeyPairSpec::EccNistP256,
            "ECC_NIST_P384" => DataKeyPairSpec::EccNistP384,
            "ECC_NIST_P521" => DataKeyPairSpec::EccNistP521,
            "ECC_SECG_P256K1" => DataKeyPairSpec::EccSecgP256K1,
            "RSA_2048" => DataKeyPairSpec::Rsa2048,
            "RSA_3072" => DataKeyPairSpec::Rsa3072,
            "RSA_4096" => DataKeyPairSpec::Rsa4096,
            other => DataKeyPairSpec::Unknown(other.to_owned()),
        }
    }
}

impl std::str::FromStr for DataKeyPairSpec {
    type Err = std::convert::Infallible;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Ok(DataKeyPairSpec::from(s))
    }
}

impl DataKeyPairSpec {
    pub fn as_str(&self) -> &str {
        match self {
            DataKeyPairSpec::EccNistP256 => "ECC_NIST_P256",
            DataKeyPairSpec::EccNistP384 => "ECC_NIST_P384",
            DataKeyPairSpec::EccNistP521 => "ECC_NIST_P521",
            DataKeyPairSpec::EccSecgP256K1 => "ECC_SECG_P256K1",
            DataKeyPairSpec::Rsa2048 => "RSA_2048",
            DataKeyPairSpec::Rsa3072 => "RSA_3072",
            DataKeyPairSpec::Rsa4096 => "RSA_4096",
            DataKeyPairSpec::Unknown(s) => s.as_ref(),
        }
    }
}
impl AsRef<str> for DataKeyPairSpec {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}

impl serde::Serialize for DataKeyPairSpec {
    fn serialize<S>(
        &self,
        serializer: S,
    ) -> Result<<S as serde::Serializer>::Ok, <S as serde::Serializer>::Error>
    where
        S: serde::Serializer,
    {
        serializer.serialize_str(self.as_str())
    }
}

impl<'de> serde::Deserialize<'de> for DataKeyPairSpec {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let data = <&str>::deserialize(deserializer)?;
        Ok(Self::from(data))
    }
}

/// <p>Contains metadata about a customer master key (CMK).</p>
/// <p>This data type is used as a response element for the <a>CreateKey</a> and <a>DescribeKey</a> operations.</p>
#[non_exhaustive]
#[derive(serde::Deserialize, serde::Serialize, std::clone::Clone, std::cmp::PartialEq)]
pub struct KeyMetadata {
    /// <p>The twelve-digit account ID of the AWS account that owns the CMK.</p>
    #[serde(rename = "AWSAccountId")]
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub aws_account_id: std::option::Option<std::string::String>,
    /// <p>The globally unique identifier for the CMK.</p>
    #[serde(rename = "KeyId")]
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub key_id: std::option::Option<std::string::String>,
    /// <p>The Amazon Resource Name (ARN) of the CMK. For examples, see <a href="https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html#arn-syntax-kms">AWS Key Management Service
    /// (AWS KMS)</a> in the Example ARNs section of the <i>AWS General
    /// Reference</i>.</p>
    #[serde(rename = "Arn")]
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub arn: std::option::Option<std::string::String>,
    /// <p>The date and time when the CMK was created.</p>
    #[serde(rename = "CreationDate")]
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(
        serialize_with = "crate::serde_util::stdoptionoptionsmithytypesinstant_epoch_seconds_ser"
    )]
    #[serde(
        deserialize_with = "crate::serde_util::stdoptionoptionsmithytypesinstant_epoch_seconds_deser"
    )]
    #[serde(default)]
    pub creation_date: std::option::Option<smithy_types::Instant>,
    /// <p>Specifies whether the CMK is enabled. When <code>KeyState</code> is <code>Enabled</code>
    /// this value is true, otherwise it is false.</p>
    #[serde(rename = "Enabled")]
    pub enabled: bool,
    /// <p>The description of the CMK.</p>
    #[serde(rename = "Description")]
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub description: std::option::Option<std::string::String>,
    /// <p>The <a href="https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#cryptographic-operations">cryptographic operations</a> for which you can use the CMK.</p>
    #[serde(rename = "KeyUsage")]
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub key_usage: std::option::Option<crate::model::KeyUsageType>,
    /// <p>The current status of the CMK.</p>
    /// <p>For more information about how key state affects the use of a CMK, see <a href="https://docs.aws.amazon.com/kms/latest/developerguide/key-state.html">Key state: Effect on your CMK</a> in the <i>AWS Key Management Service Developer Guide</i>.</p>
    #[serde(rename = "KeyState")]
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub key_state: std::option::Option<crate::model::KeyState>,
    /// <p>The date and time after which AWS KMS deletes the CMK. This value is present only when
    /// <code>KeyState</code> is <code>PendingDeletion</code>.</p>
    #[serde(rename = "DeletionDate")]
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(
        serialize_with = "crate::serde_util::stdoptionoptionsmithytypesinstant_epoch_seconds_ser"
    )]
    #[serde(
        deserialize_with = "crate::serde_util::stdoptionoptionsmithytypesinstant_epoch_seconds_deser"
    )]
    #[serde(default)]
    pub deletion_date: std::option::Option<smithy_types::Instant>,
    /// <p>The time at which the imported key material expires. When the key material expires, AWS KMS
    /// deletes the key material and the CMK becomes unusable. This value is present only for CMKs
    /// whose <code>Origin</code> is <code>EXTERNAL</code> and whose <code>ExpirationModel</code> is
    /// <code>KEY_MATERIAL_EXPIRES</code>, otherwise this value is omitted.</p>
    #[serde(rename = "ValidTo")]
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(
        serialize_with = "crate::serde_util::stdoptionoptionsmithytypesinstant_epoch_seconds_ser"
    )]
    #[serde(
        deserialize_with = "crate::serde_util::stdoptionoptionsmithytypesinstant_epoch_seconds_deser"
    )]
    #[serde(default)]
    pub valid_to: std::option::Option<smithy_types::Instant>,
    /// <p>The source of the CMK's key material. When this value is <code>AWS_KMS</code>, AWS KMS
    /// created the key material. When this value is <code>EXTERNAL</code>, the key material was
    /// imported from your existing key management infrastructure or the CMK lacks key material. When
    /// this value is <code>AWS_CLOUDHSM</code>, the key material was created in the AWS CloudHSM cluster
    /// associated with a custom key store.</p>
    #[serde(rename = "Origin")]
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub origin: std::option::Option<crate::model::OriginType>,
    /// <p>A unique identifier for the <a href="https://docs.aws.amazon.com/kms/latest/developerguide/custom-key-store-overview.html">custom key store</a> that contains the CMK. This value is present
    /// only when the CMK is created in a custom key store.</p>
    #[serde(rename = "CustomKeyStoreId")]
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub custom_key_store_id: std::option::Option<std::string::String>,
    /// <p>The cluster ID of the AWS CloudHSM cluster that contains the key material for the CMK. When you
    /// create a CMK in a <a href="https://docs.aws.amazon.com/kms/latest/developerguide/custom-key-store-overview.html">custom key store</a>, AWS KMS creates the key material for the CMK in the
    /// associated AWS CloudHSM cluster. This value is present only when the CMK is created in a custom key
    /// store.</p>
    #[serde(rename = "CloudHsmClusterId")]
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub cloud_hsm_cluster_id: std::option::Option<std::string::String>,
    /// <p>Specifies whether the CMK's key material expires. This value is present only when
    /// <code>Origin</code> is <code>EXTERNAL</code>, otherwise this value is omitted.</p>
    #[serde(rename = "ExpirationModel")]
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub expiration_model: std::option::Option<crate::model::ExpirationModelType>,
    /// <p>The manager of the CMK. CMKs in your AWS account are either customer managed or AWS
    /// managed. For more information about the difference, see <a href="https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys">Customer Master Keys</a> in the
    /// <i>AWS Key Management Service Developer Guide</i>.</p>
    #[serde(rename = "KeyManager")]
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub key_manager: std::option::Option<crate::model::KeyManagerType>,
    /// <p>Describes the type of key material in the CMK.</p>
    #[serde(rename = "CustomerMasterKeySpec")]
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub customer_master_key_spec: std::option::Option<crate::model::CustomerMasterKeySpec>,
    /// <p>The encryption algorithms that the CMK supports. You cannot use the CMK with other
    /// encryption algorithms within AWS KMS.</p>
    /// <p>This field appears only when the <code>KeyUsage</code> of the CMK is
    /// <code>ENCRYPT_DECRYPT</code>.</p>
    #[serde(rename = "EncryptionAlgorithms")]
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub encryption_algorithms:
        std::option::Option<std::vec::Vec<crate::model::EncryptionAlgorithmSpec>>,
    /// <p>The signing algorithms that the CMK supports. You cannot use the CMK with other
    /// signing algorithms within AWS KMS.</p>
    /// <p>This field appears only when the <code>KeyUsage</code> of the CMK is
    /// <code>SIGN_VERIFY</code>.</p>
    #[serde(rename = "SigningAlgorithms")]
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub signing_algorithms: std::option::Option<std::vec::Vec<crate::model::SigningAlgorithmSpec>>,
}
impl std::fmt::Debug for KeyMetadata {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        let mut formatter = f.debug_struct("KeyMetadata");
        formatter.field("aws_account_id", &self.aws_account_id);
        formatter.field("key_id", &self.key_id);
        formatter.field("arn", &self.arn);
        formatter.field("creation_date", &self.creation_date);
        formatter.field("enabled", &self.enabled);
        formatter.field("description", &self.description);
        formatter.field("key_usage", &self.key_usage);
        formatter.field("key_state", &self.key_state);
        formatter.field("deletion_date", &self.deletion_date);
        formatter.field("valid_to", &self.valid_to);
        formatter.field("origin", &self.origin);
        formatter.field("custom_key_store_id", &self.custom_key_store_id);
        formatter.field("cloud_hsm_cluster_id", &self.cloud_hsm_cluster_id);
        formatter.field("expiration_model", &self.expiration_model);
        formatter.field("key_manager", &self.key_manager);
        formatter.field("customer_master_key_spec", &self.customer_master_key_spec);
        formatter.field("encryption_algorithms", &self.encryption_algorithms);
        formatter.field("signing_algorithms", &self.signing_algorithms);
        formatter.finish()
    }
}
/// See [`KeyMetadata`](crate::model::KeyMetadata)
pub mod key_metadata {
    /// A builder for [`KeyMetadata`](crate::model::KeyMetadata)
    #[non_exhaustive]
    #[derive(std::default::Default, std::clone::Clone, std::cmp::PartialEq, std::fmt::Debug)]
    pub struct Builder {
        aws_account_id: std::option::Option<std::string::String>,
        key_id: std::option::Option<std::string::String>,
        arn: std::option::Option<std::string::String>,
        creation_date: std::option::Option<smithy_types::Instant>,
        enabled: std::option::Option<bool>,
        description: std::option::Option<std::string::String>,
        key_usage: std::option::Option<crate::model::KeyUsageType>,
        key_state: std::option::Option<crate::model::KeyState>,
        deletion_date: std::option::Option<smithy_types::Instant>,
        valid_to: std::option::Option<smithy_types::Instant>,
        origin: std::option::Option<crate::model::OriginType>,
        custom_key_store_id: std::option::Option<std::string::String>,
        cloud_hsm_cluster_id: std::option::Option<std::string::String>,
        expiration_model: std::option::Option<crate::model::ExpirationModelType>,
        key_manager: std::option::Option<crate::model::KeyManagerType>,
        customer_master_key_spec: std::option::Option<crate::model::CustomerMasterKeySpec>,
        encryption_algorithms:
            std::option::Option<std::vec::Vec<crate::model::EncryptionAlgorithmSpec>>,
        signing_algorithms: std::option::Option<std::vec::Vec<crate::model::SigningAlgorithmSpec>>,
    }
    impl Builder {
        /// <p>The twelve-digit account ID of the AWS account that owns the CMK.</p>
        pub fn aws_account_id(mut self, inp: impl Into<std::string::String>) -> Self {
            self.aws_account_id = Some(inp.into());
            self
        }
        pub fn set_aws_account_id(mut self, inp: std::option::Option<std::string::String>) -> Self {
            self.aws_account_id = inp;
            self
        }
        /// <p>The globally unique identifier for the CMK.</p>
        pub fn key_id(mut self, inp: impl Into<std::string::String>) -> Self {
            self.key_id = Some(inp.into());
            self
        }
        pub fn set_key_id(mut self, inp: std::option::Option<std::string::String>) -> Self {
            self.key_id = inp;
            self
        }
        /// <p>The Amazon Resource Name (ARN) of the CMK. For examples, see <a href="https://docs.aws.amazon.com/general/latest/gr/aws-arns-and-namespaces.html#arn-syntax-kms">AWS Key Management Service
        /// (AWS KMS)</a> in the Example ARNs section of the <i>AWS General
        /// Reference</i>.</p>
        pub fn arn(mut self, inp: impl Into<std::string::String>) -> Self {
            self.arn = Some(inp.into());
            self
        }
        pub fn set_arn(mut self, inp: std::option::Option<std::string::String>) -> Self {
            self.arn = inp;
            self
        }
        /// <p>The date and time when the CMK was created.</p>
        pub fn creation_date(mut self, inp: smithy_types::Instant) -> Self {
            self.creation_date = Some(inp);
            self
        }
        pub fn set_creation_date(
            mut self,
            inp: std::option::Option<smithy_types::Instant>,
        ) -> Self {
            self.creation_date = inp;
            self
        }
        /// <p>Specifies whether the CMK is enabled. When <code>KeyState</code> is <code>Enabled</code>
        /// this value is true, otherwise it is false.</p>
        pub fn enabled(mut self, inp: bool) -> Self {
            self.enabled = Some(inp);
            self
        }
        pub fn set_enabled(mut self, inp: bool) -> Self {
            self.enabled = Some(inp);
            self
        }
        /// <p>The description of the CMK.</p>
        pub fn description(mut self, inp: impl Into<std::string::String>) -> Self {
            self.description = Some(inp.into());
            self
        }
        pub fn set_description(mut self, inp: std::option::Option<std::string::String>) -> Self {
            self.description = inp;
            self
        }
        /// <p>The <a href="https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#cryptographic-operations">cryptographic operations</a> for which you can use the CMK.</p>
        pub fn key_usage(mut self, inp: crate::model::KeyUsageType) -> Self {
            self.key_usage = Some(inp);
            self
        }
        pub fn set_key_usage(
            mut self,
            inp: std::option::Option<crate::model::KeyUsageType>,
        ) -> Self {
            self.key_usage = inp;
            self
        }
        /// <p>The current status of the CMK.</p>
        /// <p>For more information about how key state affects the use of a CMK, see <a href="https://docs.aws.amazon.com/kms/latest/developerguide/key-state.html">Key state: Effect on your CMK</a> in the <i>AWS Key Management Service Developer Guide</i>.</p>
        pub fn key_state(mut self, inp: crate::model::KeyState) -> Self {
            self.key_state = Some(inp);
            self
        }
        pub fn set_key_state(mut self, inp: std::option::Option<crate::model::KeyState>) -> Self {
            self.key_state = inp;
            self
        }
        /// <p>The date and time after which AWS KMS deletes the CMK. This value is present only when
        /// <code>KeyState</code> is <code>PendingDeletion</code>.</p>
        pub fn deletion_date(mut self, inp: smithy_types::Instant) -> Self {
            self.deletion_date = Some(inp);
            self
        }
        pub fn set_deletion_date(
            mut self,
            inp: std::option::Option<smithy_types::Instant>,
        ) -> Self {
            self.deletion_date = inp;
            self
        }
        /// <p>The time at which the imported key material expires. When the key material expires, AWS KMS
        /// deletes the key material and the CMK becomes unusable. This value is present only for CMKs
        /// whose <code>Origin</code> is <code>EXTERNAL</code> and whose <code>ExpirationModel</code> is
        /// <code>KEY_MATERIAL_EXPIRES</code>, otherwise this value is omitted.</p>
        pub fn valid_to(mut self, inp: smithy_types::Instant) -> Self {
            self.valid_to = Some(inp);
            self
        }
        pub fn set_valid_to(mut self, inp: std::option::Option<smithy_types::Instant>) -> Self {
            self.valid_to = inp;
            self
        }
        /// <p>The source of the CMK's key material. When this value is <code>AWS_KMS</code>, AWS KMS
        /// created the key material. When this value is <code>EXTERNAL</code>, the key material was
        /// imported from your existing key management infrastructure or the CMK lacks key material. When
        /// this value is <code>AWS_CLOUDHSM</code>, the key material was created in the AWS CloudHSM cluster
        /// associated with a custom key store.</p>
        pub fn origin(mut self, inp: crate::model::OriginType) -> Self {
            self.origin = Some(inp);
            self
        }
        pub fn set_origin(mut self, inp: std::option::Option<crate::model::OriginType>) -> Self {
            self.origin = inp;
            self
        }
        /// <p>A unique identifier for the <a href="https://docs.aws.amazon.com/kms/latest/developerguide/custom-key-store-overview.html">custom key store</a> that contains the CMK. This value is present
        /// only when the CMK is created in a custom key store.</p>
        pub fn custom_key_store_id(mut self, inp: impl Into<std::string::String>) -> Self {
            self.custom_key_store_id = Some(inp.into());
            self
        }
        pub fn set_custom_key_store_id(
            mut self,
            inp: std::option::Option<std::string::String>,
        ) -> Self {
            self.custom_key_store_id = inp;
            self
        }
        /// <p>The cluster ID of the AWS CloudHSM cluster that contains the key material for the CMK. When you
        /// create a CMK in a <a href="https://docs.aws.amazon.com/kms/latest/developerguide/custom-key-store-overview.html">custom key store</a>, AWS KMS creates the key material for the CMK in the
        /// associated AWS CloudHSM cluster. This value is present only when the CMK is created in a custom key
        /// store.</p>
        pub fn cloud_hsm_cluster_id(mut self, inp: impl Into<std::string::String>) -> Self {
            self.cloud_hsm_cluster_id = Some(inp.into());
            self
        }
        pub fn set_cloud_hsm_cluster_id(
            mut self,
            inp: std::option::Option<std::string::String>,
        ) -> Self {
            self.cloud_hsm_cluster_id = inp;
            self
        }
        /// <p>Specifies whether the CMK's key material expires. This value is present only when
        /// <code>Origin</code> is <code>EXTERNAL</code>, otherwise this value is omitted.</p>
        pub fn expiration_model(mut self, inp: crate::model::ExpirationModelType) -> Self {
            self.expiration_model = Some(inp);
            self
        }
        pub fn set_expiration_model(
            mut self,
            inp: std::option::Option<crate::model::ExpirationModelType>,
        ) -> Self {
            self.expiration_model = inp;
            self
        }
        /// <p>The manager of the CMK. CMKs in your AWS account are either customer managed or AWS
        /// managed. For more information about the difference, see <a href="https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#master_keys">Customer Master Keys</a> in the
        /// <i>AWS Key Management Service Developer Guide</i>.</p>
        pub fn key_manager(mut self, inp: crate::model::KeyManagerType) -> Self {
            self.key_manager = Some(inp);
            self
        }
        pub fn set_key_manager(
            mut self,
            inp: std::option::Option<crate::model::KeyManagerType>,
        ) -> Self {
            self.key_manager = inp;
            self
        }
        /// <p>Describes the type of key material in the CMK.</p>
        pub fn customer_master_key_spec(
            mut self,
            inp: crate::model::CustomerMasterKeySpec,
        ) -> Self {
            self.customer_master_key_spec = Some(inp);
            self
        }
        pub fn set_customer_master_key_spec(
            mut self,
            inp: std::option::Option<crate::model::CustomerMasterKeySpec>,
        ) -> Self {
            self.customer_master_key_spec = inp;
            self
        }
        pub fn encryption_algorithms(
            mut self,
            inp: impl Into<crate::model::EncryptionAlgorithmSpec>,
        ) -> Self {
            let mut v = self.encryption_algorithms.unwrap_or_default();
            v.push(inp.into());
            self.encryption_algorithms = Some(v);
            self
        }
        pub fn set_encryption_algorithms(
            mut self,
            inp: std::option::Option<std::vec::Vec<crate::model::EncryptionAlgorithmSpec>>,
        ) -> Self {
            self.encryption_algorithms = inp;
            self
        }
        pub fn signing_algorithms(
            mut self,
            inp: impl Into<crate::model::SigningAlgorithmSpec>,
        ) -> Self {
            let mut v = self.signing_algorithms.unwrap_or_default();
            v.push(inp.into());
            self.signing_algorithms = Some(v);
            self
        }
        pub fn set_signing_algorithms(
            mut self,
            inp: std::option::Option<std::vec::Vec<crate::model::SigningAlgorithmSpec>>,
        ) -> Self {
            self.signing_algorithms = inp;
            self
        }
        /// Consumes the builder and constructs a [`KeyMetadata`](crate::model::KeyMetadata)
        pub fn build(self) -> crate::model::KeyMetadata {
            crate::model::KeyMetadata {
                aws_account_id: self.aws_account_id,
                key_id: self.key_id,
                arn: self.arn,
                creation_date: self.creation_date,
                enabled: self.enabled.unwrap_or_default(),
                description: self.description,
                key_usage: self.key_usage,
                key_state: self.key_state,
                deletion_date: self.deletion_date,
                valid_to: self.valid_to,
                origin: self.origin,
                custom_key_store_id: self.custom_key_store_id,
                cloud_hsm_cluster_id: self.cloud_hsm_cluster_id,
                expiration_model: self.expiration_model,
                key_manager: self.key_manager,
                customer_master_key_spec: self.customer_master_key_spec,
                encryption_algorithms: self.encryption_algorithms,
                signing_algorithms: self.signing_algorithms,
            }
        }
    }
}
impl KeyMetadata {
    /// Creates a new builder-style object to manufacture [`KeyMetadata`](crate::model::KeyMetadata)
    pub fn builder() -> crate::model::key_metadata::Builder {
        crate::model::key_metadata::Builder::default()
    }
}

#[non_exhaustive]
#[derive(
    std::clone::Clone,
    std::cmp::Eq,
    std::cmp::Ord,
    std::cmp::PartialEq,
    std::cmp::PartialOrd,
    std::fmt::Debug,
    std::hash::Hash,
)]
pub enum KeyManagerType {
    Aws,
    Customer,
    Unknown(String),
}
impl std::convert::From<&str> for KeyManagerType {
    fn from(s: &str) -> Self {
        match s {
            "AWS" => KeyManagerType::Aws,
            "CUSTOMER" => KeyManagerType::Customer,
            other => KeyManagerType::Unknown(other.to_owned()),
        }
    }
}

impl std::str::FromStr for KeyManagerType {
    type Err = std::convert::Infallible;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Ok(KeyManagerType::from(s))
    }
}

impl KeyManagerType {
    pub fn as_str(&self) -> &str {
        match self {
            KeyManagerType::Aws => "AWS",
            KeyManagerType::Customer => "CUSTOMER",
            KeyManagerType::Unknown(s) => s.as_ref(),
        }
    }
}
impl AsRef<str> for KeyManagerType {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}

impl serde::Serialize for KeyManagerType {
    fn serialize<S>(
        &self,
        serializer: S,
    ) -> Result<<S as serde::Serializer>::Ok, <S as serde::Serializer>::Error>
    where
        S: serde::Serializer,
    {
        serializer.serialize_str(self.as_str())
    }
}

impl<'de> serde::Deserialize<'de> for KeyManagerType {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let data = <&str>::deserialize(deserializer)?;
        Ok(Self::from(data))
    }
}

#[non_exhaustive]
#[derive(
    std::clone::Clone,
    std::cmp::Eq,
    std::cmp::Ord,
    std::cmp::PartialEq,
    std::cmp::PartialOrd,
    std::fmt::Debug,
    std::hash::Hash,
)]
pub enum OriginType {
    AwsCloudhsm,
    AwsKms,
    External,
    Unknown(String),
}
impl std::convert::From<&str> for OriginType {
    fn from(s: &str) -> Self {
        match s {
            "AWS_CLOUDHSM" => OriginType::AwsCloudhsm,
            "AWS_KMS" => OriginType::AwsKms,
            "EXTERNAL" => OriginType::External,
            other => OriginType::Unknown(other.to_owned()),
        }
    }
}

impl std::str::FromStr for OriginType {
    type Err = std::convert::Infallible;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Ok(OriginType::from(s))
    }
}

impl OriginType {
    pub fn as_str(&self) -> &str {
        match self {
            OriginType::AwsCloudhsm => "AWS_CLOUDHSM",
            OriginType::AwsKms => "AWS_KMS",
            OriginType::External => "EXTERNAL",
            OriginType::Unknown(s) => s.as_ref(),
        }
    }
}
impl AsRef<str> for OriginType {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}

impl serde::Serialize for OriginType {
    fn serialize<S>(
        &self,
        serializer: S,
    ) -> Result<<S as serde::Serializer>::Ok, <S as serde::Serializer>::Error>
    where
        S: serde::Serializer,
    {
        serializer.serialize_str(self.as_str())
    }
}

impl<'de> serde::Deserialize<'de> for OriginType {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let data = <&str>::deserialize(deserializer)?;
        Ok(Self::from(data))
    }
}

#[non_exhaustive]
#[derive(
    std::clone::Clone,
    std::cmp::Eq,
    std::cmp::Ord,
    std::cmp::PartialEq,
    std::cmp::PartialOrd,
    std::fmt::Debug,
    std::hash::Hash,
)]
pub enum KeyState {
    Disabled,
    Enabled,
    PendingDeletion,
    PendingImport,
    Unavailable,
    Unknown(String),
}
impl std::convert::From<&str> for KeyState {
    fn from(s: &str) -> Self {
        match s {
            "Disabled" => KeyState::Disabled,
            "Enabled" => KeyState::Enabled,
            "PendingDeletion" => KeyState::PendingDeletion,
            "PendingImport" => KeyState::PendingImport,
            "Unavailable" => KeyState::Unavailable,
            other => KeyState::Unknown(other.to_owned()),
        }
    }
}

impl std::str::FromStr for KeyState {
    type Err = std::convert::Infallible;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Ok(KeyState::from(s))
    }
}

impl KeyState {
    pub fn as_str(&self) -> &str {
        match self {
            KeyState::Disabled => "Disabled",
            KeyState::Enabled => "Enabled",
            KeyState::PendingDeletion => "PendingDeletion",
            KeyState::PendingImport => "PendingImport",
            KeyState::Unavailable => "Unavailable",
            KeyState::Unknown(s) => s.as_ref(),
        }
    }
}
impl AsRef<str> for KeyState {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}

impl serde::Serialize for KeyState {
    fn serialize<S>(
        &self,
        serializer: S,
    ) -> Result<<S as serde::Serializer>::Ok, <S as serde::Serializer>::Error>
    where
        S: serde::Serializer,
    {
        serializer.serialize_str(self.as_str())
    }
}

impl<'de> serde::Deserialize<'de> for KeyState {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let data = <&str>::deserialize(deserializer)?;
        Ok(Self::from(data))
    }
}

/// <p>Contains information about each custom key store in the custom key store list.</p>
#[non_exhaustive]
#[derive(serde::Deserialize, serde::Serialize, std::clone::Clone, std::cmp::PartialEq)]
pub struct CustomKeyStoresListEntry {
    /// <p>A unique identifier for the custom key store.</p>
    #[serde(rename = "CustomKeyStoreId")]
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub custom_key_store_id: std::option::Option<std::string::String>,
    /// <p>The user-specified friendly name for the custom key store.</p>
    #[serde(rename = "CustomKeyStoreName")]
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub custom_key_store_name: std::option::Option<std::string::String>,
    /// <p>A unique identifier for the AWS CloudHSM cluster that is associated with the custom key
    /// store.</p>
    #[serde(rename = "CloudHsmClusterId")]
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub cloud_hsm_cluster_id: std::option::Option<std::string::String>,
    /// <p>The trust anchor certificate of the associated AWS CloudHSM cluster. When you <a href="https://docs.aws.amazon.com/cloudhsm/latest/userguide/initialize-cluster.html#sign-csr">initialize the
    /// cluster</a>, you create this certificate and save it in the <code>customerCA.crt</code>
    /// file.</p>
    #[serde(rename = "TrustAnchorCertificate")]
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub trust_anchor_certificate: std::option::Option<std::string::String>,
    /// <p>Indicates whether the custom key store is connected to its AWS CloudHSM cluster.</p>
    /// <p>You can create and use CMKs in your custom key stores only when its connection state is
    /// <code>CONNECTED</code>.</p>
    /// <p>The value is <code>DISCONNECTED</code> if the key store has never been connected or you
    /// use the <a>DisconnectCustomKeyStore</a> operation to disconnect it. If the value is
    /// <code>CONNECTED</code> but you are having trouble using the custom key store, make sure that
    /// its associated AWS CloudHSM cluster is active and contains at least one active HSM.</p>
    /// <p>A value of <code>FAILED</code> indicates that an attempt to connect was unsuccessful. The <code>ConnectionErrorCode</code> field in the response indicates the cause of the failure. For
    /// help resolving a connection failure, see <a href="https://docs.aws.amazon.com/kms/latest/developerguide/fix-keystore.html">Troubleshooting a Custom Key Store</a> in the
    /// <i>AWS Key Management Service Developer Guide</i>.</p>
    #[serde(rename = "ConnectionState")]
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub connection_state: std::option::Option<crate::model::ConnectionStateType>,
    /// <p>Describes the connection error. This field appears in the response only when the <code>ConnectionState</code> is <code>FAILED</code>. For help resolving these errors, see <a href="https://docs.aws.amazon.com/kms/latest/developerguide/fix-keystore.html#fix-keystore-failed">How to Fix a Connection Failure</a> in <i>AWS Key Management Service Developer Guide</i>.</p>
    /// <p>Valid values are:</p>
    /// <ul>
    /// <li>
    /// <p>
    /// <code>CLUSTER_NOT_FOUND</code> - AWS KMS cannot find the AWS CloudHSM cluster with the
    /// specified cluster ID.</p>
    /// </li>
    /// <li>
    /// <p>
    /// <code>INSUFFICIENT_CLOUDHSM_HSMS</code> - The associated AWS CloudHSM cluster does not
    /// contain any active HSMs. To connect a custom key store to its AWS CloudHSM cluster, the cluster
    /// must contain at least one active HSM.</p>
    /// </li>
    /// <li>
    /// <p>
    /// <code>INTERNAL_ERROR</code> - AWS KMS could not complete the request due to an internal
    /// error. Retry the request. For <code>ConnectCustomKeyStore</code> requests, disconnect the
    /// custom key store before trying to connect again.</p>
    /// </li>
    /// <li>
    /// <p>
    /// <code>INVALID_CREDENTIALS</code> - AWS KMS does not have the correct password for the
    /// <code>kmsuser</code> crypto user in the AWS CloudHSM cluster. Before you can connect your
    /// custom key store to its AWS CloudHSM cluster, you must change the <code>kmsuser</code> account
    /// password and update the key store password value for the custom key store.</p>
    /// </li>
    /// <li>
    /// <p>
    /// <code>NETWORK_ERRORS</code> - Network errors are preventing AWS KMS from connecting to
    /// the custom key store.</p>
    /// </li>
    /// <li>
    /// <p>
    /// <code>SUBNET_NOT_FOUND</code> - A subnet in the AWS CloudHSM cluster
    /// configuration was deleted. If AWS KMS cannot find all of the subnets in the cluster configuration, attempts to connect the custom key store to the AWS CloudHSM cluster fail. To fix this error, create a cluster from a recent backup and associate it with your custom key store. (This process creates a new cluster configuration with a VPC and private subnets.) For details, see <a href="https://docs.aws.amazon.com/kms/latest/developerguide/fix-keystore.html#fix-keystore-failed">How to Fix a Connection Failure</a> in the
    /// <i>AWS Key Management Service Developer Guide</i>.</p>
    /// </li>
    /// <li>
    /// <p>
    /// <code>USER_LOCKED_OUT</code> - The <code>kmsuser</code> CU account is locked out of
    /// the associated AWS CloudHSM cluster due to too many failed password attempts. Before you can
    /// connect your custom key store to its AWS CloudHSM cluster, you must change the
    /// <code>kmsuser</code> account password and update the key store password value for the custom key
    /// store.</p>
    /// </li>
    /// <li>
    /// <p>
    /// <code>USER_LOGGED_IN</code> - The <code>kmsuser</code> CU account is logged into the
    /// the associated AWS CloudHSM cluster. This prevents AWS KMS from rotating the <code>kmsuser</code> account password and logging into the cluster. Before you can
    /// connect your custom key store to its AWS CloudHSM cluster, you must log the <code>kmsuser</code> CU out of the cluster. If you changed the <code>kmsuser</code> password to log into the cluster, you must also and update the key store password value for the custom key
    /// store. For help, see <a href="https://docs.aws.amazon.com/kms/latest/developerguide/fix-keystore.html#login-kmsuser-2">How to Log Out and Reconnect</a> in the <i>AWS Key Management Service Developer Guide</i>.</p>
    /// </li>
    /// <li>
    /// <p>
    /// <code>USER_NOT_FOUND</code> - AWS KMS cannot find a <code>kmsuser</code> CU account in the associated AWS CloudHSM cluster. Before you can
    /// connect your custom key store to its AWS CloudHSM cluster, you must create a <code>kmsuser</code> CU account in the cluster, and then update the key store password value for the custom key
    /// store.</p>
    /// </li>
    /// </ul>
    #[serde(rename = "ConnectionErrorCode")]
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default)]
    pub connection_error_code: std::option::Option<crate::model::ConnectionErrorCodeType>,
    /// <p>The date and time when the custom key store was created.</p>
    #[serde(rename = "CreationDate")]
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(
        serialize_with = "crate::serde_util::stdoptionoptionsmithytypesinstant_epoch_seconds_ser"
    )]
    #[serde(
        deserialize_with = "crate::serde_util::stdoptionoptionsmithytypesinstant_epoch_seconds_deser"
    )]
    #[serde(default)]
    pub creation_date: std::option::Option<smithy_types::Instant>,
}
impl std::fmt::Debug for CustomKeyStoresListEntry {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        let mut formatter = f.debug_struct("CustomKeyStoresListEntry");
        formatter.field("custom_key_store_id", &self.custom_key_store_id);
        formatter.field("custom_key_store_name", &self.custom_key_store_name);
        formatter.field("cloud_hsm_cluster_id", &self.cloud_hsm_cluster_id);
        formatter.field("trust_anchor_certificate", &self.trust_anchor_certificate);
        formatter.field("connection_state", &self.connection_state);
        formatter.field("connection_error_code", &self.connection_error_code);
        formatter.field("creation_date", &self.creation_date);
        formatter.finish()
    }
}
/// See [`CustomKeyStoresListEntry`](crate::model::CustomKeyStoresListEntry)
pub mod custom_key_stores_list_entry {
    /// A builder for [`CustomKeyStoresListEntry`](crate::model::CustomKeyStoresListEntry)
    #[non_exhaustive]
    #[derive(std::default::Default, std::clone::Clone, std::cmp::PartialEq, std::fmt::Debug)]
    pub struct Builder {
        custom_key_store_id: std::option::Option<std::string::String>,
        custom_key_store_name: std::option::Option<std::string::String>,
        cloud_hsm_cluster_id: std::option::Option<std::string::String>,
        trust_anchor_certificate: std::option::Option<std::string::String>,
        connection_state: std::option::Option<crate::model::ConnectionStateType>,
        connection_error_code: std::option::Option<crate::model::ConnectionErrorCodeType>,
        creation_date: std::option::Option<smithy_types::Instant>,
    }
    impl Builder {
        /// <p>A unique identifier for the custom key store.</p>
        pub fn custom_key_store_id(mut self, inp: impl Into<std::string::String>) -> Self {
            self.custom_key_store_id = Some(inp.into());
            self
        }
        pub fn set_custom_key_store_id(
            mut self,
            inp: std::option::Option<std::string::String>,
        ) -> Self {
            self.custom_key_store_id = inp;
            self
        }
        /// <p>The user-specified friendly name for the custom key store.</p>
        pub fn custom_key_store_name(mut self, inp: impl Into<std::string::String>) -> Self {
            self.custom_key_store_name = Some(inp.into());
            self
        }
        pub fn set_custom_key_store_name(
            mut self,
            inp: std::option::Option<std::string::String>,
        ) -> Self {
            self.custom_key_store_name = inp;
            self
        }
        /// <p>A unique identifier for the AWS CloudHSM cluster that is associated with the custom key
        /// store.</p>
        pub fn cloud_hsm_cluster_id(mut self, inp: impl Into<std::string::String>) -> Self {
            self.cloud_hsm_cluster_id = Some(inp.into());
            self
        }
        pub fn set_cloud_hsm_cluster_id(
            mut self,
            inp: std::option::Option<std::string::String>,
        ) -> Self {
            self.cloud_hsm_cluster_id = inp;
            self
        }
        /// <p>The trust anchor certificate of the associated AWS CloudHSM cluster. When you <a href="https://docs.aws.amazon.com/cloudhsm/latest/userguide/initialize-cluster.html#sign-csr">initialize the
        /// cluster</a>, you create this certificate and save it in the <code>customerCA.crt</code>
        /// file.</p>
        pub fn trust_anchor_certificate(mut self, inp: impl Into<std::string::String>) -> Self {
            self.trust_anchor_certificate = Some(inp.into());
            self
        }
        pub fn set_trust_anchor_certificate(
            mut self,
            inp: std::option::Option<std::string::String>,
        ) -> Self {
            self.trust_anchor_certificate = inp;
            self
        }
        /// <p>Indicates whether the custom key store is connected to its AWS CloudHSM cluster.</p>
        /// <p>You can create and use CMKs in your custom key stores only when its connection state is
        /// <code>CONNECTED</code>.</p>
        /// <p>The value is <code>DISCONNECTED</code> if the key store has never been connected or you
        /// use the <a>DisconnectCustomKeyStore</a> operation to disconnect it. If the value is
        /// <code>CONNECTED</code> but you are having trouble using the custom key store, make sure that
        /// its associated AWS CloudHSM cluster is active and contains at least one active HSM.</p>
        /// <p>A value of <code>FAILED</code> indicates that an attempt to connect was unsuccessful. The <code>ConnectionErrorCode</code> field in the response indicates the cause of the failure. For
        /// help resolving a connection failure, see <a href="https://docs.aws.amazon.com/kms/latest/developerguide/fix-keystore.html">Troubleshooting a Custom Key Store</a> in the
        /// <i>AWS Key Management Service Developer Guide</i>.</p>
        pub fn connection_state(mut self, inp: crate::model::ConnectionStateType) -> Self {
            self.connection_state = Some(inp);
            self
        }
        pub fn set_connection_state(
            mut self,
            inp: std::option::Option<crate::model::ConnectionStateType>,
        ) -> Self {
            self.connection_state = inp;
            self
        }
        /// <p>Describes the connection error. This field appears in the response only when the <code>ConnectionState</code> is <code>FAILED</code>. For help resolving these errors, see <a href="https://docs.aws.amazon.com/kms/latest/developerguide/fix-keystore.html#fix-keystore-failed">How to Fix a Connection Failure</a> in <i>AWS Key Management Service Developer Guide</i>.</p>
        /// <p>Valid values are:</p>
        /// <ul>
        /// <li>
        /// <p>
        /// <code>CLUSTER_NOT_FOUND</code> - AWS KMS cannot find the AWS CloudHSM cluster with the
        /// specified cluster ID.</p>
        /// </li>
        /// <li>
        /// <p>
        /// <code>INSUFFICIENT_CLOUDHSM_HSMS</code> - The associated AWS CloudHSM cluster does not
        /// contain any active HSMs. To connect a custom key store to its AWS CloudHSM cluster, the cluster
        /// must contain at least one active HSM.</p>
        /// </li>
        /// <li>
        /// <p>
        /// <code>INTERNAL_ERROR</code> - AWS KMS could not complete the request due to an internal
        /// error. Retry the request. For <code>ConnectCustomKeyStore</code> requests, disconnect the
        /// custom key store before trying to connect again.</p>
        /// </li>
        /// <li>
        /// <p>
        /// <code>INVALID_CREDENTIALS</code> - AWS KMS does not have the correct password for the
        /// <code>kmsuser</code> crypto user in the AWS CloudHSM cluster. Before you can connect your
        /// custom key store to its AWS CloudHSM cluster, you must change the <code>kmsuser</code> account
        /// password and update the key store password value for the custom key store.</p>
        /// </li>
        /// <li>
        /// <p>
        /// <code>NETWORK_ERRORS</code> - Network errors are preventing AWS KMS from connecting to
        /// the custom key store.</p>
        /// </li>
        /// <li>
        /// <p>
        /// <code>SUBNET_NOT_FOUND</code> - A subnet in the AWS CloudHSM cluster
        /// configuration was deleted. If AWS KMS cannot find all of the subnets in the cluster configuration, attempts to connect the custom key store to the AWS CloudHSM cluster fail. To fix this error, create a cluster from a recent backup and associate it with your custom key store. (This process creates a new cluster configuration with a VPC and private subnets.) For details, see <a href="https://docs.aws.amazon.com/kms/latest/developerguide/fix-keystore.html#fix-keystore-failed">How to Fix a Connection Failure</a> in the
        /// <i>AWS Key Management Service Developer Guide</i>.</p>
        /// </li>
        /// <li>
        /// <p>
        /// <code>USER_LOCKED_OUT</code> - The <code>kmsuser</code> CU account is locked out of
        /// the associated AWS CloudHSM cluster due to too many failed password attempts. Before you can
        /// connect your custom key store to its AWS CloudHSM cluster, you must change the
        /// <code>kmsuser</code> account password and update the key store password value for the custom key
        /// store.</p>
        /// </li>
        /// <li>
        /// <p>
        /// <code>USER_LOGGED_IN</code> - The <code>kmsuser</code> CU account is logged into the
        /// the associated AWS CloudHSM cluster. This prevents AWS KMS from rotating the <code>kmsuser</code> account password and logging into the cluster. Before you can
        /// connect your custom key store to its AWS CloudHSM cluster, you must log the <code>kmsuser</code> CU out of the cluster. If you changed the <code>kmsuser</code> password to log into the cluster, you must also and update the key store password value for the custom key
        /// store. For help, see <a href="https://docs.aws.amazon.com/kms/latest/developerguide/fix-keystore.html#login-kmsuser-2">How to Log Out and Reconnect</a> in the <i>AWS Key Management Service Developer Guide</i>.</p>
        /// </li>
        /// <li>
        /// <p>
        /// <code>USER_NOT_FOUND</code> - AWS KMS cannot find a <code>kmsuser</code> CU account in the associated AWS CloudHSM cluster. Before you can
        /// connect your custom key store to its AWS CloudHSM cluster, you must create a <code>kmsuser</code> CU account in the cluster, and then update the key store password value for the custom key
        /// store.</p>
        /// </li>
        /// </ul>
        pub fn connection_error_code(mut self, inp: crate::model::ConnectionErrorCodeType) -> Self {
            self.connection_error_code = Some(inp);
            self
        }
        pub fn set_connection_error_code(
            mut self,
            inp: std::option::Option<crate::model::ConnectionErrorCodeType>,
        ) -> Self {
            self.connection_error_code = inp;
            self
        }
        /// <p>The date and time when the custom key store was created.</p>
        pub fn creation_date(mut self, inp: smithy_types::Instant) -> Self {
            self.creation_date = Some(inp);
            self
        }
        pub fn set_creation_date(
            mut self,
            inp: std::option::Option<smithy_types::Instant>,
        ) -> Self {
            self.creation_date = inp;
            self
        }
        /// Consumes the builder and constructs a [`CustomKeyStoresListEntry`](crate::model::CustomKeyStoresListEntry)
        pub fn build(self) -> crate::model::CustomKeyStoresListEntry {
            crate::model::CustomKeyStoresListEntry {
                custom_key_store_id: self.custom_key_store_id,
                custom_key_store_name: self.custom_key_store_name,
                cloud_hsm_cluster_id: self.cloud_hsm_cluster_id,
                trust_anchor_certificate: self.trust_anchor_certificate,
                connection_state: self.connection_state,
                connection_error_code: self.connection_error_code,
                creation_date: self.creation_date,
            }
        }
    }
}
impl CustomKeyStoresListEntry {
    /// Creates a new builder-style object to manufacture [`CustomKeyStoresListEntry`](crate::model::CustomKeyStoresListEntry)
    pub fn builder() -> crate::model::custom_key_stores_list_entry::Builder {
        crate::model::custom_key_stores_list_entry::Builder::default()
    }
}

#[non_exhaustive]
#[derive(
    std::clone::Clone,
    std::cmp::Eq,
    std::cmp::Ord,
    std::cmp::PartialEq,
    std::cmp::PartialOrd,
    std::fmt::Debug,
    std::hash::Hash,
)]
pub enum ConnectionErrorCodeType {
    ClusterNotFound,
    InsufficientCloudhsmHsms,
    InternalError,
    InvalidCredentials,
    NetworkErrors,
    SubnetNotFound,
    UserLockedOut,
    UserLoggedIn,
    UserNotFound,
    Unknown(String),
}
impl std::convert::From<&str> for ConnectionErrorCodeType {
    fn from(s: &str) -> Self {
        match s {
            "CLUSTER_NOT_FOUND" => ConnectionErrorCodeType::ClusterNotFound,
            "INSUFFICIENT_CLOUDHSM_HSMS" => ConnectionErrorCodeType::InsufficientCloudhsmHsms,
            "INTERNAL_ERROR" => ConnectionErrorCodeType::InternalError,
            "INVALID_CREDENTIALS" => ConnectionErrorCodeType::InvalidCredentials,
            "NETWORK_ERRORS" => ConnectionErrorCodeType::NetworkErrors,
            "SUBNET_NOT_FOUND" => ConnectionErrorCodeType::SubnetNotFound,
            "USER_LOCKED_OUT" => ConnectionErrorCodeType::UserLockedOut,
            "USER_LOGGED_IN" => ConnectionErrorCodeType::UserLoggedIn,
            "USER_NOT_FOUND" => ConnectionErrorCodeType::UserNotFound,
            other => ConnectionErrorCodeType::Unknown(other.to_owned()),
        }
    }
}

impl std::str::FromStr for ConnectionErrorCodeType {
    type Err = std::convert::Infallible;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Ok(ConnectionErrorCodeType::from(s))
    }
}

impl ConnectionErrorCodeType {
    pub fn as_str(&self) -> &str {
        match self {
            ConnectionErrorCodeType::ClusterNotFound => "CLUSTER_NOT_FOUND",
            ConnectionErrorCodeType::InsufficientCloudhsmHsms => "INSUFFICIENT_CLOUDHSM_HSMS",
            ConnectionErrorCodeType::InternalError => "INTERNAL_ERROR",
            ConnectionErrorCodeType::InvalidCredentials => "INVALID_CREDENTIALS",
            ConnectionErrorCodeType::NetworkErrors => "NETWORK_ERRORS",
            ConnectionErrorCodeType::SubnetNotFound => "SUBNET_NOT_FOUND",
            ConnectionErrorCodeType::UserLockedOut => "USER_LOCKED_OUT",
            ConnectionErrorCodeType::UserLoggedIn => "USER_LOGGED_IN",
            ConnectionErrorCodeType::UserNotFound => "USER_NOT_FOUND",
            ConnectionErrorCodeType::Unknown(s) => s.as_ref(),
        }
    }
}
impl AsRef<str> for ConnectionErrorCodeType {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}

impl serde::Serialize for ConnectionErrorCodeType {
    fn serialize<S>(
        &self,
        serializer: S,
    ) -> Result<<S as serde::Serializer>::Ok, <S as serde::Serializer>::Error>
    where
        S: serde::Serializer,
    {
        serializer.serialize_str(self.as_str())
    }
}

impl<'de> serde::Deserialize<'de> for ConnectionErrorCodeType {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let data = <&str>::deserialize(deserializer)?;
        Ok(Self::from(data))
    }
}

#[non_exhaustive]
#[derive(
    std::clone::Clone,
    std::cmp::Eq,
    std::cmp::Ord,
    std::cmp::PartialEq,
    std::cmp::PartialOrd,
    std::fmt::Debug,
    std::hash::Hash,
)]
pub enum ConnectionStateType {
    Connected,
    Connecting,
    Disconnected,
    Disconnecting,
    Failed,
    Unknown(String),
}
impl std::convert::From<&str> for ConnectionStateType {
    fn from(s: &str) -> Self {
        match s {
            "CONNECTED" => ConnectionStateType::Connected,
            "CONNECTING" => ConnectionStateType::Connecting,
            "DISCONNECTED" => ConnectionStateType::Disconnected,
            "DISCONNECTING" => ConnectionStateType::Disconnecting,
            "FAILED" => ConnectionStateType::Failed,
            other => ConnectionStateType::Unknown(other.to_owned()),
        }
    }
}

impl std::str::FromStr for ConnectionStateType {
    type Err = std::convert::Infallible;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Ok(ConnectionStateType::from(s))
    }
}

impl ConnectionStateType {
    pub fn as_str(&self) -> &str {
        match self {
            ConnectionStateType::Connected => "CONNECTED",
            ConnectionStateType::Connecting => "CONNECTING",
            ConnectionStateType::Disconnected => "DISCONNECTED",
            ConnectionStateType::Disconnecting => "DISCONNECTING",
            ConnectionStateType::Failed => "FAILED",
            ConnectionStateType::Unknown(s) => s.as_ref(),
        }
    }
}
impl AsRef<str> for ConnectionStateType {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}

impl serde::Serialize for ConnectionStateType {
    fn serialize<S>(
        &self,
        serializer: S,
    ) -> Result<<S as serde::Serializer>::Ok, <S as serde::Serializer>::Error>
    where
        S: serde::Serializer,
    {
        serializer.serialize_str(self.as_str())
    }
}

impl<'de> serde::Deserialize<'de> for ConnectionStateType {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let data = <&str>::deserialize(deserializer)?;
        Ok(Self::from(data))
    }
}
