#[derive(
    Clone,
    Default,
    PartialEq,
    serde::Deserialize,
    serde::Serialize,
    std::fmt::Debug
)]
/// CSINode holds information about all CSI drivers installed on a node. CSI drivers do not need to create the CSINode object directly. As long as they use the node-driver-registrar sidecar container, the kubelet will automatically populate the CSINode object for the CSI driver as part of kubelet plugin registration. CSINode has the same name as a node. If the object is missing, it means either there are no CSI Drivers available on the node, or the Kubelet version is low enough that it doesn't create this object. CSINode has an OwnerReference that points to the corresponding node object.
#[serde(rename_all = "camelCase", deny_unknown_fields)]
pub struct CSINodeAc {
    #[serde(
        serialize_with = "crate::k8s_openapi::serialize_api_version",
        deserialize_with = "crate::k8s_openapi::deserialize_api_version"
    )]
    pub api_version: std::marker::PhantomData<Self>,
    #[serde(
        serialize_with = "crate::k8s_openapi::serialize_kind",
        deserialize_with = "crate::k8s_openapi::deserialize_kind"
    )]
    pub kind: std::marker::PhantomData<Self>,
    /// Standard object's metadata. metadata.name must be the Kubernetes node name.
    pub metadata: ::k8s_openapi028::apimachinery::pkg::apis::meta::v1::ObjectMeta,
    /// spec is the specification of CSINode
    #[serde(skip_serializing_if = "Option::is_none")]
    pub spec: Option<
        <::k8s_openapi028::api::storage::v1::CSINodeSpec as crate::Optionable>::Optioned,
    >,
}
#[automatically_derived]
impl crate::Optionable for k8s_openapi028::api::storage::v1::CSINode {
    type Optioned = CSINodeAc;
}
#[automatically_derived]
impl crate::Optionable for CSINodeAc {
    type Optioned = CSINodeAc;
}
#[automatically_derived]
#[cfg(feature = "k8s_openapi_convert")]
impl crate::OptionableConvert for k8s_openapi028::api::storage::v1::CSINode {
    fn into_optioned(self) -> CSINodeAc {
        CSINodeAc {
            api_version: Default::default(),
            kind: Default::default(),
            metadata: self.metadata,
            spec: Some(crate::OptionableConvert::into_optioned(self.spec)),
        }
    }
    fn try_from_optioned(value: CSINodeAc) -> Result<Self, crate::Error> {
        Ok(Self {
            metadata: value.metadata,
            spec: crate::OptionableConvert::try_from_optioned(
                value
                    .spec
                    .ok_or(crate::Error {
                        missing_field: "spec",
                    })?,
            )?,
        })
    }
    fn merge(&mut self, other: CSINodeAc) -> Result<(), crate::Error> {
        self.metadata = other.metadata;
        if let Some(other_value) = other.spec {
            crate::OptionableConvert::merge(&mut self.spec, other_value)?;
        }
        Ok(())
    }
}
#[automatically_derived]
#[cfg(feature = "k8s_openapi_convert")]
impl crate::OptionedConvert<k8s_openapi028::api::storage::v1::CSINode> for CSINodeAc {
    fn from_optionable(value: k8s_openapi028::api::storage::v1::CSINode) -> Self {
        crate::OptionableConvert::into_optioned(value)
    }
    fn try_into_optionable(
        self,
    ) -> Result<k8s_openapi028::api::storage::v1::CSINode, crate::Error> {
        crate::OptionableConvert::try_from_optioned(self)
    }
    fn merge_into(
        self,
        other: &mut k8s_openapi028::api::storage::v1::CSINode,
    ) -> Result<(), crate::Error> {
        crate::OptionableConvert::merge(other, self)
    }
}
impl k8s_openapi028::Resource for CSINodeAc {
    const API_VERSION: &'static str = <k8s_openapi028::api::storage::v1::CSINode as k8s_openapi028::Resource>::API_VERSION;
    const GROUP: &'static str = <k8s_openapi028::api::storage::v1::CSINode as k8s_openapi028::Resource>::GROUP;
    const KIND: &'static str = <k8s_openapi028::api::storage::v1::CSINode as k8s_openapi028::Resource>::KIND;
    const VERSION: &'static str = <k8s_openapi028::api::storage::v1::CSINode as k8s_openapi028::Resource>::VERSION;
    const URL_PATH_SEGMENT: &'static str = <k8s_openapi028::api::storage::v1::CSINode as k8s_openapi028::Resource>::URL_PATH_SEGMENT;
    type Scope = <k8s_openapi028::api::storage::v1::CSINode as k8s_openapi028::Resource>::Scope;
}
impl k8s_openapi028::Metadata for CSINodeAc {
    type Ty = <k8s_openapi028::api::storage::v1::CSINode as k8s_openapi028::Metadata>::Ty;
    fn metadata(&self) -> &<Self as k8s_openapi028::Metadata>::Ty {
        &self.metadata
    }
    fn metadata_mut(&mut self) -> &mut <Self as k8s_openapi028::Metadata>::Ty {
        &mut self.metadata
    }
}
#[cfg(test_k8s_openapi_roundtrip)]
#[test]
fn roundtrip_csinodeac() {
    crate::testutil::roundtrip_test::<k8s_openapi028::api::storage::v1::CSINode>();
}
impl k8s_openapi028::DeepMerge for CSINodeAc {
    fn merge_from(&mut self, other: Self) {
        k8s_openapi028::DeepMerge::merge_from(&mut self.metadata, other.metadata);
        k8s_openapi028::DeepMerge::merge_from(&mut self.spec, other.spec);
    }
}
