dropbox-sdk 0.15.0

Rust bindings to the Dropbox API, generated by Stone from the official spec.
Documentation
// DO NOT EDIT
// This file was @generated by Stone

#![allow(
    clippy::too_many_arguments,
    clippy::large_enum_variant,
    clippy::doc_markdown,
)]

//! This namespace contains helpers for property and template metadata endpoints.
//!
//! These endpoints enable you to tag arbitrary key/value data to Dropbox files.
//!
//! The most basic unit in this namespace is the [`PropertyField`](PropertyField). These fields
//! encapsulate the actual key/value data.
//!
//! Fields are added to a Dropbox file using a [`PropertyGroup`](PropertyGroup). Property groups
//! contain a reference to a Dropbox file and a [`PropertyGroupTemplate`](PropertyGroupTemplate).
//! Property groups are uniquely identified by the combination of their associated Dropbox file and
//! template.
//!
//! The [`PropertyGroupTemplate`](PropertyGroupTemplate) is a way of restricting the possible key
//! names and value types of the data within a property group. The possible key names and value
//! types are explicitly enumerated using [`PropertyFieldTemplate`](PropertyFieldTemplate) objects.
//!
//! You can think of a property group template as a class definition for a particular key/value
//! metadata object, and the property groups themselves as the instantiations of these objects.
//!
//! Templates are owned either by a user/app pair or team/app pair. Templates and their associated
//! properties can't be accessed by any app other than the app that created them, and even then,
//! only when the app is linked with the owner of the template (either a user or team).
//!
//! User-owned templates are accessed via the user-auth file_properties/templates/*_for_user
//! endpoints, while team-owned templates are accessed via the team-auth
//! file_properties/templates/*_for_team endpoints. Properties associated with either type of
//! template can be accessed via the user-auth properties/* endpoints.
//!
//! Finally, properties can be accessed from a number of endpoints that return metadata, including
//! `files/get_metadata`, and `files/list_folder`. Properties can also be added during upload, using
//! `files/upload`.

pub type Id = String;
pub type PathOrId = String;
pub type PropertiesSearchCursor = String;
pub type TemplateId = String;

/// Add property groups to a Dropbox file. See [`templates_add_for_user()`](templates_add_for_user)
/// or [`templates_add_for_team()`](templates_add_for_team) to create new templates.
pub fn properties_add(
    client: &impl crate::client_trait::UserAuthClient,
    arg: &AddPropertiesArg,
) -> crate::Result<Result<(), AddPropertiesError>> {
    crate::client_helpers::request(
        client,
        crate::client_trait::Endpoint::Api,
        crate::client_trait::Style::Rpc,
        "file_properties/properties/add",
        arg,
        None)
}

/// Overwrite property groups associated with a file. This endpoint should be used instead of
/// [`properties_update()`](properties_update) when property groups are being updated via a
/// "snapshot" instead of via a "delta". In other words, this endpoint will delete all omitted
/// fields from a property group, whereas [`properties_update()`](properties_update) will only
/// delete fields that are explicitly marked for deletion.
pub fn properties_overwrite(
    client: &impl crate::client_trait::UserAuthClient,
    arg: &OverwritePropertyGroupArg,
) -> crate::Result<Result<(), InvalidPropertyGroupError>> {
    crate::client_helpers::request(
        client,
        crate::client_trait::Endpoint::Api,
        crate::client_trait::Style::Rpc,
        "file_properties/properties/overwrite",
        arg,
        None)
}

/// Permanently removes the specified property group from the file. To remove specific property
/// field key value pairs, see [`properties_update()`](properties_update). To update a template, see
/// [`templates_update_for_user()`](templates_update_for_user) or
/// [`templates_update_for_team()`](templates_update_for_team). To remove a template, see
/// [`templates_remove_for_user()`](templates_remove_for_user) or
/// [`templates_remove_for_team()`](templates_remove_for_team).
pub fn properties_remove(
    client: &impl crate::client_trait::UserAuthClient,
    arg: &RemovePropertiesArg,
) -> crate::Result<Result<(), RemovePropertiesError>> {
    crate::client_helpers::request(
        client,
        crate::client_trait::Endpoint::Api,
        crate::client_trait::Style::Rpc,
        "file_properties/properties/remove",
        arg,
        None)
}

/// Search across property templates for particular property field values.
pub fn properties_search(
    client: &impl crate::client_trait::UserAuthClient,
    arg: &PropertiesSearchArg,
) -> crate::Result<Result<PropertiesSearchResult, PropertiesSearchError>> {
    crate::client_helpers::request(
        client,
        crate::client_trait::Endpoint::Api,
        crate::client_trait::Style::Rpc,
        "file_properties/properties/search",
        arg,
        None)
}

/// Once a cursor has been retrieved from [`properties_search()`](properties_search), use this to
/// paginate through all search results.
pub fn properties_search_continue(
    client: &impl crate::client_trait::UserAuthClient,
    arg: &PropertiesSearchContinueArg,
) -> crate::Result<Result<PropertiesSearchResult, PropertiesSearchContinueError>> {
    crate::client_helpers::request(
        client,
        crate::client_trait::Endpoint::Api,
        crate::client_trait::Style::Rpc,
        "file_properties/properties/search/continue",
        arg,
        None)
}

/// Add, update or remove properties associated with the supplied file and templates. This endpoint
/// should be used instead of [`properties_overwrite()`](properties_overwrite) when property groups
/// are being updated via a "delta" instead of via a "snapshot" . In other words, this endpoint will
/// not delete any omitted fields from a property group, whereas
/// [`properties_overwrite()`](properties_overwrite) will delete any fields that are omitted from a
/// property group.
pub fn properties_update(
    client: &impl crate::client_trait::UserAuthClient,
    arg: &UpdatePropertiesArg,
) -> crate::Result<Result<(), UpdatePropertiesError>> {
    crate::client_helpers::request(
        client,
        crate::client_trait::Endpoint::Api,
        crate::client_trait::Style::Rpc,
        "file_properties/properties/update",
        arg,
        None)
}

/// Add a template associated with a team. See [`properties_add()`](properties_add) to add
/// properties to a file or folder. Note: this endpoint will create team-owned templates.
pub fn templates_add_for_team(
    client: &impl crate::client_trait::TeamAuthClient,
    arg: &AddTemplateArg,
) -> crate::Result<Result<AddTemplateResult, ModifyTemplateError>> {
    crate::client_helpers::request(
        client,
        crate::client_trait::Endpoint::Api,
        crate::client_trait::Style::Rpc,
        "file_properties/templates/add_for_team",
        arg,
        None)
}

/// Add a template associated with a user. See [`properties_add()`](properties_add) to add
/// properties to a file. This endpoint can't be called on a team member or admin's behalf.
pub fn templates_add_for_user(
    client: &impl crate::client_trait::UserAuthClient,
    arg: &AddTemplateArg,
) -> crate::Result<Result<AddTemplateResult, ModifyTemplateError>> {
    crate::client_helpers::request(
        client,
        crate::client_trait::Endpoint::Api,
        crate::client_trait::Style::Rpc,
        "file_properties/templates/add_for_user",
        arg,
        None)
}

/// Get the schema for a specified template.
pub fn templates_get_for_team(
    client: &impl crate::client_trait::TeamAuthClient,
    arg: &GetTemplateArg,
) -> crate::Result<Result<GetTemplateResult, TemplateError>> {
    crate::client_helpers::request(
        client,
        crate::client_trait::Endpoint::Api,
        crate::client_trait::Style::Rpc,
        "file_properties/templates/get_for_team",
        arg,
        None)
}

/// Get the schema for a specified template. This endpoint can't be called on a team member or
/// admin's behalf.
pub fn templates_get_for_user(
    client: &impl crate::client_trait::UserAuthClient,
    arg: &GetTemplateArg,
) -> crate::Result<Result<GetTemplateResult, TemplateError>> {
    crate::client_helpers::request(
        client,
        crate::client_trait::Endpoint::Api,
        crate::client_trait::Style::Rpc,
        "file_properties/templates/get_for_user",
        arg,
        None)
}

/// Get the template identifiers for a team. To get the schema of each template use
/// [`templates_get_for_team()`](templates_get_for_team).
pub fn templates_list_for_team(
    client: &impl crate::client_trait::TeamAuthClient,
) -> crate::Result<Result<ListTemplateResult, TemplateError>> {
    crate::client_helpers::request(
        client,
        crate::client_trait::Endpoint::Api,
        crate::client_trait::Style::Rpc,
        "file_properties/templates/list_for_team",
        &(),
        None)
}

/// Get the template identifiers for a team. To get the schema of each template use
/// [`templates_get_for_user()`](templates_get_for_user). This endpoint can't be called on a team
/// member or admin's behalf.
pub fn templates_list_for_user(
    client: &impl crate::client_trait::UserAuthClient,
) -> crate::Result<Result<ListTemplateResult, TemplateError>> {
    crate::client_helpers::request(
        client,
        crate::client_trait::Endpoint::Api,
        crate::client_trait::Style::Rpc,
        "file_properties/templates/list_for_user",
        &(),
        None)
}

/// Permanently removes the specified template created from
/// [`templates_add_for_user()`](templates_add_for_user). All properties associated with the
/// template will also be removed. This action cannot be undone.
pub fn templates_remove_for_team(
    client: &impl crate::client_trait::TeamAuthClient,
    arg: &RemoveTemplateArg,
) -> crate::Result<Result<(), TemplateError>> {
    crate::client_helpers::request(
        client,
        crate::client_trait::Endpoint::Api,
        crate::client_trait::Style::Rpc,
        "file_properties/templates/remove_for_team",
        arg,
        None)
}

/// Permanently removes the specified template created from
/// [`templates_add_for_user()`](templates_add_for_user). All properties associated with the
/// template will also be removed. This action cannot be undone.
pub fn templates_remove_for_user(
    client: &impl crate::client_trait::UserAuthClient,
    arg: &RemoveTemplateArg,
) -> crate::Result<Result<(), TemplateError>> {
    crate::client_helpers::request(
        client,
        crate::client_trait::Endpoint::Api,
        crate::client_trait::Style::Rpc,
        "file_properties/templates/remove_for_user",
        arg,
        None)
}

/// Update a template associated with a team. This route can update the template name, the template
/// description and add optional properties to templates.
pub fn templates_update_for_team(
    client: &impl crate::client_trait::TeamAuthClient,
    arg: &UpdateTemplateArg,
) -> crate::Result<Result<UpdateTemplateResult, ModifyTemplateError>> {
    crate::client_helpers::request(
        client,
        crate::client_trait::Endpoint::Api,
        crate::client_trait::Style::Rpc,
        "file_properties/templates/update_for_team",
        arg,
        None)
}

/// Update a template associated with a user. This route can update the template name, the template
/// description and add optional properties to templates. This endpoint can't be called on a team
/// member or admin's behalf.
pub fn templates_update_for_user(
    client: &impl crate::client_trait::UserAuthClient,
    arg: &UpdateTemplateArg,
) -> crate::Result<Result<UpdateTemplateResult, ModifyTemplateError>> {
    crate::client_helpers::request(
        client,
        crate::client_trait::Endpoint::Api,
        crate::client_trait::Style::Rpc,
        "file_properties/templates/update_for_user",
        arg,
        None)
}

#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive] // structs may have more fields added in the future.
pub struct AddPropertiesArg {
    /// A unique identifier for the file or folder.
    pub path: PathOrId,
    /// The property groups which are to be added to a Dropbox file. No two groups in the input
    /// should  refer to the same template.
    pub property_groups: Vec<PropertyGroup>,
}

impl AddPropertiesArg {
    pub fn new(path: PathOrId, property_groups: Vec<PropertyGroup>) -> Self {
        AddPropertiesArg {
            path,
            property_groups,
        }
    }
}

const ADD_PROPERTIES_ARG_FIELDS: &[&str] = &["path",
                                             "property_groups"];
impl AddPropertiesArg {
    pub(crate) fn internal_deserialize<'de, V: ::serde::de::MapAccess<'de>>(
        map: V,
    ) -> Result<AddPropertiesArg, V::Error> {
        Self::internal_deserialize_opt(map, false).map(Option::unwrap)
    }

    pub(crate) fn internal_deserialize_opt<'de, V: ::serde::de::MapAccess<'de>>(
        mut map: V,
        optional: bool,
    ) -> Result<Option<AddPropertiesArg>, V::Error> {
        let mut field_path = None;
        let mut field_property_groups = None;
        let mut nothing = true;
        while let Some(key) = map.next_key::<&str>()? {
            nothing = false;
            match key {
                "path" => {
                    if field_path.is_some() {
                        return Err(::serde::de::Error::duplicate_field("path"));
                    }
                    field_path = Some(map.next_value()?);
                }
                "property_groups" => {
                    if field_property_groups.is_some() {
                        return Err(::serde::de::Error::duplicate_field("property_groups"));
                    }
                    field_property_groups = Some(map.next_value()?);
                }
                _ => {
                    // unknown field allowed and ignored
                    map.next_value::<::serde_json::Value>()?;
                }
            }
        }
        if optional && nothing {
            return Ok(None);
        }
        let result = AddPropertiesArg {
            path: field_path.ok_or_else(|| ::serde::de::Error::missing_field("path"))?,
            property_groups: field_property_groups.ok_or_else(|| ::serde::de::Error::missing_field("property_groups"))?,
        };
        Ok(Some(result))
    }

    pub(crate) fn internal_serialize<S: ::serde::ser::Serializer>(
        &self,
        s: &mut S::SerializeStruct,
    ) -> Result<(), S::Error> {
        use serde::ser::SerializeStruct;
        s.serialize_field("path", &self.path)?;
        s.serialize_field("property_groups", &self.property_groups)?;
        Ok(())
    }
}

impl<'de> ::serde::de::Deserialize<'de> for AddPropertiesArg {
    fn deserialize<D: ::serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        // struct deserializer
        use serde::de::{MapAccess, Visitor};
        struct StructVisitor;
        impl<'de> Visitor<'de> for StructVisitor {
            type Value = AddPropertiesArg;
            fn expecting(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                f.write_str("a AddPropertiesArg struct")
            }
            fn visit_map<V: MapAccess<'de>>(self, map: V) -> Result<Self::Value, V::Error> {
                AddPropertiesArg::internal_deserialize(map)
            }
        }
        deserializer.deserialize_struct("AddPropertiesArg", ADD_PROPERTIES_ARG_FIELDS, StructVisitor)
    }
}

impl ::serde::ser::Serialize for AddPropertiesArg {
    fn serialize<S: ::serde::ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        // struct serializer
        use serde::ser::SerializeStruct;
        let mut s = serializer.serialize_struct("AddPropertiesArg", 2)?;
        self.internal_serialize::<S>(&mut s)?;
        s.end()
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive] // variants may be added in the future
pub enum AddPropertiesError {
    /// Template does not exist for the given identifier.
    TemplateNotFound(TemplateId),
    /// You do not have permission to modify this template.
    RestrictedContent,
    Path(LookupError),
    /// This folder cannot be tagged. Tagging folders is not supported for team-owned templates.
    UnsupportedFolder,
    /// One or more of the supplied property field values is too large.
    PropertyFieldTooLarge,
    /// One or more of the supplied property fields does not conform to the template specifications.
    DoesNotFitTemplate,
    /// There are 2 or more property groups referring to the same templates in the input.
    DuplicatePropertyGroups,
    /// A property group associated with this template and file already exists.
    PropertyGroupAlreadyExists,
    /// Catch-all used for unrecognized values returned from the server. Encountering this value
    /// typically indicates that this SDK version is out of date.
    Other,
}

impl<'de> ::serde::de::Deserialize<'de> for AddPropertiesError {
    fn deserialize<D: ::serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        // union deserializer
        use serde::de::{self, MapAccess, Visitor};
        struct EnumVisitor;
        impl<'de> Visitor<'de> for EnumVisitor {
            type Value = AddPropertiesError;
            fn expecting(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                f.write_str("a AddPropertiesError structure")
            }
            fn visit_map<V: MapAccess<'de>>(self, mut map: V) -> Result<Self::Value, V::Error> {
                let tag: &str = match map.next_key()? {
                    Some(".tag") => map.next_value()?,
                    _ => return Err(de::Error::missing_field(".tag"))
                };
                let value = match tag {
                    "template_not_found" => {
                        match map.next_key()? {
                            Some("template_not_found") => AddPropertiesError::TemplateNotFound(map.next_value()?),
                            None => return Err(de::Error::missing_field("template_not_found")),
                            _ => return Err(de::Error::unknown_field(tag, VARIANTS))
                        }
                    }
                    "restricted_content" => AddPropertiesError::RestrictedContent,
                    "path" => {
                        match map.next_key()? {
                            Some("path") => AddPropertiesError::Path(map.next_value()?),
                            None => return Err(de::Error::missing_field("path")),
                            _ => return Err(de::Error::unknown_field(tag, VARIANTS))
                        }
                    }
                    "unsupported_folder" => AddPropertiesError::UnsupportedFolder,
                    "property_field_too_large" => AddPropertiesError::PropertyFieldTooLarge,
                    "does_not_fit_template" => AddPropertiesError::DoesNotFitTemplate,
                    "duplicate_property_groups" => AddPropertiesError::DuplicatePropertyGroups,
                    "property_group_already_exists" => AddPropertiesError::PropertyGroupAlreadyExists,
                    _ => AddPropertiesError::Other,
                };
                crate::eat_json_fields(&mut map)?;
                Ok(value)
            }
        }
        const VARIANTS: &[&str] = &["template_not_found",
                                    "restricted_content",
                                    "other",
                                    "path",
                                    "unsupported_folder",
                                    "property_field_too_large",
                                    "does_not_fit_template",
                                    "duplicate_property_groups",
                                    "property_group_already_exists"];
        deserializer.deserialize_struct("AddPropertiesError", VARIANTS, EnumVisitor)
    }
}

impl ::serde::ser::Serialize for AddPropertiesError {
    fn serialize<S: ::serde::ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        // union serializer
        use serde::ser::SerializeStruct;
        match *self {
            AddPropertiesError::TemplateNotFound(ref x) => {
                // primitive
                let mut s = serializer.serialize_struct("AddPropertiesError", 2)?;
                s.serialize_field(".tag", "template_not_found")?;
                s.serialize_field("template_not_found", x)?;
                s.end()
            }
            AddPropertiesError::RestrictedContent => {
                // unit
                let mut s = serializer.serialize_struct("AddPropertiesError", 1)?;
                s.serialize_field(".tag", "restricted_content")?;
                s.end()
            }
            AddPropertiesError::Path(ref x) => {
                // union or polymporphic struct
                let mut s = serializer.serialize_struct("AddPropertiesError", 2)?;
                s.serialize_field(".tag", "path")?;
                s.serialize_field("path", x)?;
                s.end()
            }
            AddPropertiesError::UnsupportedFolder => {
                // unit
                let mut s = serializer.serialize_struct("AddPropertiesError", 1)?;
                s.serialize_field(".tag", "unsupported_folder")?;
                s.end()
            }
            AddPropertiesError::PropertyFieldTooLarge => {
                // unit
                let mut s = serializer.serialize_struct("AddPropertiesError", 1)?;
                s.serialize_field(".tag", "property_field_too_large")?;
                s.end()
            }
            AddPropertiesError::DoesNotFitTemplate => {
                // unit
                let mut s = serializer.serialize_struct("AddPropertiesError", 1)?;
                s.serialize_field(".tag", "does_not_fit_template")?;
                s.end()
            }
            AddPropertiesError::DuplicatePropertyGroups => {
                // unit
                let mut s = serializer.serialize_struct("AddPropertiesError", 1)?;
                s.serialize_field(".tag", "duplicate_property_groups")?;
                s.end()
            }
            AddPropertiesError::PropertyGroupAlreadyExists => {
                // unit
                let mut s = serializer.serialize_struct("AddPropertiesError", 1)?;
                s.serialize_field(".tag", "property_group_already_exists")?;
                s.end()
            }
            AddPropertiesError::Other => Err(::serde::ser::Error::custom("cannot serialize 'Other' variant"))
        }
    }
}

impl ::std::error::Error for AddPropertiesError {
    fn source(&self) -> Option<&(dyn ::std::error::Error + 'static)> {
        match self {
            AddPropertiesError::Path(inner) => Some(inner),
            _ => None,
        }
    }
}

impl ::std::fmt::Display for AddPropertiesError {
    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
        match self {
            AddPropertiesError::TemplateNotFound(inner) => write!(f, "Template does not exist for the given identifier: {:?}", inner),
            AddPropertiesError::RestrictedContent => f.write_str("You do not have permission to modify this template."),
            AddPropertiesError::Path(inner) => write!(f, "{}", inner),
            AddPropertiesError::UnsupportedFolder => f.write_str("This folder cannot be tagged. Tagging folders is not supported for team-owned templates."),
            AddPropertiesError::PropertyFieldTooLarge => f.write_str("One or more of the supplied property field values is too large."),
            AddPropertiesError::DoesNotFitTemplate => f.write_str("One or more of the supplied property fields does not conform to the template specifications."),
            AddPropertiesError::DuplicatePropertyGroups => f.write_str("There are 2 or more property groups referring to the same templates in the input."),
            AddPropertiesError::PropertyGroupAlreadyExists => f.write_str("A property group associated with this template and file already exists."),
            _ => write!(f, "{:?}", *self),
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive] // structs may have more fields added in the future.
pub struct AddTemplateArg {
    /// Display name for the template. Template names can be up to 256 bytes.
    pub name: String,
    /// Description for the template. Template descriptions can be up to 1024 bytes.
    pub description: String,
    /// Definitions of the property fields associated with this template. There can be up to 32
    /// properties in a single template.
    pub fields: Vec<PropertyFieldTemplate>,
}

impl AddTemplateArg {
    pub fn new(name: String, description: String, fields: Vec<PropertyFieldTemplate>) -> Self {
        AddTemplateArg {
            name,
            description,
            fields,
        }
    }
}

const ADD_TEMPLATE_ARG_FIELDS: &[&str] = &["name",
                                           "description",
                                           "fields"];
impl AddTemplateArg {
    pub(crate) fn internal_deserialize<'de, V: ::serde::de::MapAccess<'de>>(
        map: V,
    ) -> Result<AddTemplateArg, V::Error> {
        Self::internal_deserialize_opt(map, false).map(Option::unwrap)
    }

    pub(crate) fn internal_deserialize_opt<'de, V: ::serde::de::MapAccess<'de>>(
        mut map: V,
        optional: bool,
    ) -> Result<Option<AddTemplateArg>, V::Error> {
        let mut field_name = None;
        let mut field_description = None;
        let mut field_fields = None;
        let mut nothing = true;
        while let Some(key) = map.next_key::<&str>()? {
            nothing = false;
            match key {
                "name" => {
                    if field_name.is_some() {
                        return Err(::serde::de::Error::duplicate_field("name"));
                    }
                    field_name = Some(map.next_value()?);
                }
                "description" => {
                    if field_description.is_some() {
                        return Err(::serde::de::Error::duplicate_field("description"));
                    }
                    field_description = Some(map.next_value()?);
                }
                "fields" => {
                    if field_fields.is_some() {
                        return Err(::serde::de::Error::duplicate_field("fields"));
                    }
                    field_fields = Some(map.next_value()?);
                }
                _ => {
                    // unknown field allowed and ignored
                    map.next_value::<::serde_json::Value>()?;
                }
            }
        }
        if optional && nothing {
            return Ok(None);
        }
        let result = AddTemplateArg {
            name: field_name.ok_or_else(|| ::serde::de::Error::missing_field("name"))?,
            description: field_description.ok_or_else(|| ::serde::de::Error::missing_field("description"))?,
            fields: field_fields.ok_or_else(|| ::serde::de::Error::missing_field("fields"))?,
        };
        Ok(Some(result))
    }

    pub(crate) fn internal_serialize<S: ::serde::ser::Serializer>(
        &self,
        s: &mut S::SerializeStruct,
    ) -> Result<(), S::Error> {
        use serde::ser::SerializeStruct;
        s.serialize_field("name", &self.name)?;
        s.serialize_field("description", &self.description)?;
        s.serialize_field("fields", &self.fields)?;
        Ok(())
    }
}

impl<'de> ::serde::de::Deserialize<'de> for AddTemplateArg {
    fn deserialize<D: ::serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        // struct deserializer
        use serde::de::{MapAccess, Visitor};
        struct StructVisitor;
        impl<'de> Visitor<'de> for StructVisitor {
            type Value = AddTemplateArg;
            fn expecting(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                f.write_str("a AddTemplateArg struct")
            }
            fn visit_map<V: MapAccess<'de>>(self, map: V) -> Result<Self::Value, V::Error> {
                AddTemplateArg::internal_deserialize(map)
            }
        }
        deserializer.deserialize_struct("AddTemplateArg", ADD_TEMPLATE_ARG_FIELDS, StructVisitor)
    }
}

impl ::serde::ser::Serialize for AddTemplateArg {
    fn serialize<S: ::serde::ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        // struct serializer
        use serde::ser::SerializeStruct;
        let mut s = serializer.serialize_struct("AddTemplateArg", 3)?;
        self.internal_serialize::<S>(&mut s)?;
        s.end()
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive] // structs may have more fields added in the future.
pub struct AddTemplateResult {
    /// An identifier for template added by  See
    /// [`templates_add_for_user()`](templates_add_for_user) or
    /// [`templates_add_for_team()`](templates_add_for_team).
    pub template_id: TemplateId,
}

impl AddTemplateResult {
    pub fn new(template_id: TemplateId) -> Self {
        AddTemplateResult {
            template_id,
        }
    }
}

const ADD_TEMPLATE_RESULT_FIELDS: &[&str] = &["template_id"];
impl AddTemplateResult {
    pub(crate) fn internal_deserialize<'de, V: ::serde::de::MapAccess<'de>>(
        map: V,
    ) -> Result<AddTemplateResult, V::Error> {
        Self::internal_deserialize_opt(map, false).map(Option::unwrap)
    }

    pub(crate) fn internal_deserialize_opt<'de, V: ::serde::de::MapAccess<'de>>(
        mut map: V,
        optional: bool,
    ) -> Result<Option<AddTemplateResult>, V::Error> {
        let mut field_template_id = None;
        let mut nothing = true;
        while let Some(key) = map.next_key::<&str>()? {
            nothing = false;
            match key {
                "template_id" => {
                    if field_template_id.is_some() {
                        return Err(::serde::de::Error::duplicate_field("template_id"));
                    }
                    field_template_id = Some(map.next_value()?);
                }
                _ => {
                    // unknown field allowed and ignored
                    map.next_value::<::serde_json::Value>()?;
                }
            }
        }
        if optional && nothing {
            return Ok(None);
        }
        let result = AddTemplateResult {
            template_id: field_template_id.ok_or_else(|| ::serde::de::Error::missing_field("template_id"))?,
        };
        Ok(Some(result))
    }

    pub(crate) fn internal_serialize<S: ::serde::ser::Serializer>(
        &self,
        s: &mut S::SerializeStruct,
    ) -> Result<(), S::Error> {
        use serde::ser::SerializeStruct;
        s.serialize_field("template_id", &self.template_id)?;
        Ok(())
    }
}

impl<'de> ::serde::de::Deserialize<'de> for AddTemplateResult {
    fn deserialize<D: ::serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        // struct deserializer
        use serde::de::{MapAccess, Visitor};
        struct StructVisitor;
        impl<'de> Visitor<'de> for StructVisitor {
            type Value = AddTemplateResult;
            fn expecting(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                f.write_str("a AddTemplateResult struct")
            }
            fn visit_map<V: MapAccess<'de>>(self, map: V) -> Result<Self::Value, V::Error> {
                AddTemplateResult::internal_deserialize(map)
            }
        }
        deserializer.deserialize_struct("AddTemplateResult", ADD_TEMPLATE_RESULT_FIELDS, StructVisitor)
    }
}

impl ::serde::ser::Serialize for AddTemplateResult {
    fn serialize<S: ::serde::ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        // struct serializer
        use serde::ser::SerializeStruct;
        let mut s = serializer.serialize_struct("AddTemplateResult", 1)?;
        self.internal_serialize::<S>(&mut s)?;
        s.end()
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive] // structs may have more fields added in the future.
pub struct GetTemplateArg {
    /// An identifier for template added by route  See
    /// [`templates_add_for_user()`](templates_add_for_user) or
    /// [`templates_add_for_team()`](templates_add_for_team).
    pub template_id: TemplateId,
}

impl GetTemplateArg {
    pub fn new(template_id: TemplateId) -> Self {
        GetTemplateArg {
            template_id,
        }
    }
}

const GET_TEMPLATE_ARG_FIELDS: &[&str] = &["template_id"];
impl GetTemplateArg {
    pub(crate) fn internal_deserialize<'de, V: ::serde::de::MapAccess<'de>>(
        map: V,
    ) -> Result<GetTemplateArg, V::Error> {
        Self::internal_deserialize_opt(map, false).map(Option::unwrap)
    }

    pub(crate) fn internal_deserialize_opt<'de, V: ::serde::de::MapAccess<'de>>(
        mut map: V,
        optional: bool,
    ) -> Result<Option<GetTemplateArg>, V::Error> {
        let mut field_template_id = None;
        let mut nothing = true;
        while let Some(key) = map.next_key::<&str>()? {
            nothing = false;
            match key {
                "template_id" => {
                    if field_template_id.is_some() {
                        return Err(::serde::de::Error::duplicate_field("template_id"));
                    }
                    field_template_id = Some(map.next_value()?);
                }
                _ => {
                    // unknown field allowed and ignored
                    map.next_value::<::serde_json::Value>()?;
                }
            }
        }
        if optional && nothing {
            return Ok(None);
        }
        let result = GetTemplateArg {
            template_id: field_template_id.ok_or_else(|| ::serde::de::Error::missing_field("template_id"))?,
        };
        Ok(Some(result))
    }

    pub(crate) fn internal_serialize<S: ::serde::ser::Serializer>(
        &self,
        s: &mut S::SerializeStruct,
    ) -> Result<(), S::Error> {
        use serde::ser::SerializeStruct;
        s.serialize_field("template_id", &self.template_id)?;
        Ok(())
    }
}

impl<'de> ::serde::de::Deserialize<'de> for GetTemplateArg {
    fn deserialize<D: ::serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        // struct deserializer
        use serde::de::{MapAccess, Visitor};
        struct StructVisitor;
        impl<'de> Visitor<'de> for StructVisitor {
            type Value = GetTemplateArg;
            fn expecting(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                f.write_str("a GetTemplateArg struct")
            }
            fn visit_map<V: MapAccess<'de>>(self, map: V) -> Result<Self::Value, V::Error> {
                GetTemplateArg::internal_deserialize(map)
            }
        }
        deserializer.deserialize_struct("GetTemplateArg", GET_TEMPLATE_ARG_FIELDS, StructVisitor)
    }
}

impl ::serde::ser::Serialize for GetTemplateArg {
    fn serialize<S: ::serde::ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        // struct serializer
        use serde::ser::SerializeStruct;
        let mut s = serializer.serialize_struct("GetTemplateArg", 1)?;
        self.internal_serialize::<S>(&mut s)?;
        s.end()
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive] // structs may have more fields added in the future.
pub struct GetTemplateResult {
    /// Display name for the template. Template names can be up to 256 bytes.
    pub name: String,
    /// Description for the template. Template descriptions can be up to 1024 bytes.
    pub description: String,
    /// Definitions of the property fields associated with this template. There can be up to 32
    /// properties in a single template.
    pub fields: Vec<PropertyFieldTemplate>,
}

impl GetTemplateResult {
    pub fn new(name: String, description: String, fields: Vec<PropertyFieldTemplate>) -> Self {
        GetTemplateResult {
            name,
            description,
            fields,
        }
    }
}

const GET_TEMPLATE_RESULT_FIELDS: &[&str] = &["name",
                                              "description",
                                              "fields"];
impl GetTemplateResult {
    pub(crate) fn internal_deserialize<'de, V: ::serde::de::MapAccess<'de>>(
        map: V,
    ) -> Result<GetTemplateResult, V::Error> {
        Self::internal_deserialize_opt(map, false).map(Option::unwrap)
    }

    pub(crate) fn internal_deserialize_opt<'de, V: ::serde::de::MapAccess<'de>>(
        mut map: V,
        optional: bool,
    ) -> Result<Option<GetTemplateResult>, V::Error> {
        let mut field_name = None;
        let mut field_description = None;
        let mut field_fields = None;
        let mut nothing = true;
        while let Some(key) = map.next_key::<&str>()? {
            nothing = false;
            match key {
                "name" => {
                    if field_name.is_some() {
                        return Err(::serde::de::Error::duplicate_field("name"));
                    }
                    field_name = Some(map.next_value()?);
                }
                "description" => {
                    if field_description.is_some() {
                        return Err(::serde::de::Error::duplicate_field("description"));
                    }
                    field_description = Some(map.next_value()?);
                }
                "fields" => {
                    if field_fields.is_some() {
                        return Err(::serde::de::Error::duplicate_field("fields"));
                    }
                    field_fields = Some(map.next_value()?);
                }
                _ => {
                    // unknown field allowed and ignored
                    map.next_value::<::serde_json::Value>()?;
                }
            }
        }
        if optional && nothing {
            return Ok(None);
        }
        let result = GetTemplateResult {
            name: field_name.ok_or_else(|| ::serde::de::Error::missing_field("name"))?,
            description: field_description.ok_or_else(|| ::serde::de::Error::missing_field("description"))?,
            fields: field_fields.ok_or_else(|| ::serde::de::Error::missing_field("fields"))?,
        };
        Ok(Some(result))
    }

    pub(crate) fn internal_serialize<S: ::serde::ser::Serializer>(
        &self,
        s: &mut S::SerializeStruct,
    ) -> Result<(), S::Error> {
        use serde::ser::SerializeStruct;
        s.serialize_field("name", &self.name)?;
        s.serialize_field("description", &self.description)?;
        s.serialize_field("fields", &self.fields)?;
        Ok(())
    }
}

impl<'de> ::serde::de::Deserialize<'de> for GetTemplateResult {
    fn deserialize<D: ::serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        // struct deserializer
        use serde::de::{MapAccess, Visitor};
        struct StructVisitor;
        impl<'de> Visitor<'de> for StructVisitor {
            type Value = GetTemplateResult;
            fn expecting(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                f.write_str("a GetTemplateResult struct")
            }
            fn visit_map<V: MapAccess<'de>>(self, map: V) -> Result<Self::Value, V::Error> {
                GetTemplateResult::internal_deserialize(map)
            }
        }
        deserializer.deserialize_struct("GetTemplateResult", GET_TEMPLATE_RESULT_FIELDS, StructVisitor)
    }
}

impl ::serde::ser::Serialize for GetTemplateResult {
    fn serialize<S: ::serde::ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        // struct serializer
        use serde::ser::SerializeStruct;
        let mut s = serializer.serialize_struct("GetTemplateResult", 3)?;
        self.internal_serialize::<S>(&mut s)?;
        s.end()
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive] // variants may be added in the future
pub enum InvalidPropertyGroupError {
    /// Template does not exist for the given identifier.
    TemplateNotFound(TemplateId),
    /// You do not have permission to modify this template.
    RestrictedContent,
    Path(LookupError),
    /// This folder cannot be tagged. Tagging folders is not supported for team-owned templates.
    UnsupportedFolder,
    /// One or more of the supplied property field values is too large.
    PropertyFieldTooLarge,
    /// One or more of the supplied property fields does not conform to the template specifications.
    DoesNotFitTemplate,
    /// There are 2 or more property groups referring to the same templates in the input.
    DuplicatePropertyGroups,
    /// Catch-all used for unrecognized values returned from the server. Encountering this value
    /// typically indicates that this SDK version is out of date.
    Other,
}

impl<'de> ::serde::de::Deserialize<'de> for InvalidPropertyGroupError {
    fn deserialize<D: ::serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        // union deserializer
        use serde::de::{self, MapAccess, Visitor};
        struct EnumVisitor;
        impl<'de> Visitor<'de> for EnumVisitor {
            type Value = InvalidPropertyGroupError;
            fn expecting(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                f.write_str("a InvalidPropertyGroupError structure")
            }
            fn visit_map<V: MapAccess<'de>>(self, mut map: V) -> Result<Self::Value, V::Error> {
                let tag: &str = match map.next_key()? {
                    Some(".tag") => map.next_value()?,
                    _ => return Err(de::Error::missing_field(".tag"))
                };
                let value = match tag {
                    "template_not_found" => {
                        match map.next_key()? {
                            Some("template_not_found") => InvalidPropertyGroupError::TemplateNotFound(map.next_value()?),
                            None => return Err(de::Error::missing_field("template_not_found")),
                            _ => return Err(de::Error::unknown_field(tag, VARIANTS))
                        }
                    }
                    "restricted_content" => InvalidPropertyGroupError::RestrictedContent,
                    "path" => {
                        match map.next_key()? {
                            Some("path") => InvalidPropertyGroupError::Path(map.next_value()?),
                            None => return Err(de::Error::missing_field("path")),
                            _ => return Err(de::Error::unknown_field(tag, VARIANTS))
                        }
                    }
                    "unsupported_folder" => InvalidPropertyGroupError::UnsupportedFolder,
                    "property_field_too_large" => InvalidPropertyGroupError::PropertyFieldTooLarge,
                    "does_not_fit_template" => InvalidPropertyGroupError::DoesNotFitTemplate,
                    "duplicate_property_groups" => InvalidPropertyGroupError::DuplicatePropertyGroups,
                    _ => InvalidPropertyGroupError::Other,
                };
                crate::eat_json_fields(&mut map)?;
                Ok(value)
            }
        }
        const VARIANTS: &[&str] = &["template_not_found",
                                    "restricted_content",
                                    "other",
                                    "path",
                                    "unsupported_folder",
                                    "property_field_too_large",
                                    "does_not_fit_template",
                                    "duplicate_property_groups"];
        deserializer.deserialize_struct("InvalidPropertyGroupError", VARIANTS, EnumVisitor)
    }
}

impl ::serde::ser::Serialize for InvalidPropertyGroupError {
    fn serialize<S: ::serde::ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        // union serializer
        use serde::ser::SerializeStruct;
        match *self {
            InvalidPropertyGroupError::TemplateNotFound(ref x) => {
                // primitive
                let mut s = serializer.serialize_struct("InvalidPropertyGroupError", 2)?;
                s.serialize_field(".tag", "template_not_found")?;
                s.serialize_field("template_not_found", x)?;
                s.end()
            }
            InvalidPropertyGroupError::RestrictedContent => {
                // unit
                let mut s = serializer.serialize_struct("InvalidPropertyGroupError", 1)?;
                s.serialize_field(".tag", "restricted_content")?;
                s.end()
            }
            InvalidPropertyGroupError::Path(ref x) => {
                // union or polymporphic struct
                let mut s = serializer.serialize_struct("InvalidPropertyGroupError", 2)?;
                s.serialize_field(".tag", "path")?;
                s.serialize_field("path", x)?;
                s.end()
            }
            InvalidPropertyGroupError::UnsupportedFolder => {
                // unit
                let mut s = serializer.serialize_struct("InvalidPropertyGroupError", 1)?;
                s.serialize_field(".tag", "unsupported_folder")?;
                s.end()
            }
            InvalidPropertyGroupError::PropertyFieldTooLarge => {
                // unit
                let mut s = serializer.serialize_struct("InvalidPropertyGroupError", 1)?;
                s.serialize_field(".tag", "property_field_too_large")?;
                s.end()
            }
            InvalidPropertyGroupError::DoesNotFitTemplate => {
                // unit
                let mut s = serializer.serialize_struct("InvalidPropertyGroupError", 1)?;
                s.serialize_field(".tag", "does_not_fit_template")?;
                s.end()
            }
            InvalidPropertyGroupError::DuplicatePropertyGroups => {
                // unit
                let mut s = serializer.serialize_struct("InvalidPropertyGroupError", 1)?;
                s.serialize_field(".tag", "duplicate_property_groups")?;
                s.end()
            }
            InvalidPropertyGroupError::Other => Err(::serde::ser::Error::custom("cannot serialize 'Other' variant"))
        }
    }
}

impl ::std::error::Error for InvalidPropertyGroupError {
    fn source(&self) -> Option<&(dyn ::std::error::Error + 'static)> {
        match self {
            InvalidPropertyGroupError::Path(inner) => Some(inner),
            _ => None,
        }
    }
}

impl ::std::fmt::Display for InvalidPropertyGroupError {
    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
        match self {
            InvalidPropertyGroupError::TemplateNotFound(inner) => write!(f, "Template does not exist for the given identifier: {:?}", inner),
            InvalidPropertyGroupError::RestrictedContent => f.write_str("You do not have permission to modify this template."),
            InvalidPropertyGroupError::Path(inner) => write!(f, "{}", inner),
            InvalidPropertyGroupError::UnsupportedFolder => f.write_str("This folder cannot be tagged. Tagging folders is not supported for team-owned templates."),
            InvalidPropertyGroupError::PropertyFieldTooLarge => f.write_str("One or more of the supplied property field values is too large."),
            InvalidPropertyGroupError::DoesNotFitTemplate => f.write_str("One or more of the supplied property fields does not conform to the template specifications."),
            InvalidPropertyGroupError::DuplicatePropertyGroups => f.write_str("There are 2 or more property groups referring to the same templates in the input."),
            _ => write!(f, "{:?}", *self),
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive] // structs may have more fields added in the future.
pub struct ListTemplateResult {
    /// List of identifiers for templates added by  See
    /// [`templates_add_for_user()`](templates_add_for_user) or
    /// [`templates_add_for_team()`](templates_add_for_team).
    pub template_ids: Vec<TemplateId>,
}

impl ListTemplateResult {
    pub fn new(template_ids: Vec<TemplateId>) -> Self {
        ListTemplateResult {
            template_ids,
        }
    }
}

const LIST_TEMPLATE_RESULT_FIELDS: &[&str] = &["template_ids"];
impl ListTemplateResult {
    pub(crate) fn internal_deserialize<'de, V: ::serde::de::MapAccess<'de>>(
        map: V,
    ) -> Result<ListTemplateResult, V::Error> {
        Self::internal_deserialize_opt(map, false).map(Option::unwrap)
    }

    pub(crate) fn internal_deserialize_opt<'de, V: ::serde::de::MapAccess<'de>>(
        mut map: V,
        optional: bool,
    ) -> Result<Option<ListTemplateResult>, V::Error> {
        let mut field_template_ids = None;
        let mut nothing = true;
        while let Some(key) = map.next_key::<&str>()? {
            nothing = false;
            match key {
                "template_ids" => {
                    if field_template_ids.is_some() {
                        return Err(::serde::de::Error::duplicate_field("template_ids"));
                    }
                    field_template_ids = Some(map.next_value()?);
                }
                _ => {
                    // unknown field allowed and ignored
                    map.next_value::<::serde_json::Value>()?;
                }
            }
        }
        if optional && nothing {
            return Ok(None);
        }
        let result = ListTemplateResult {
            template_ids: field_template_ids.ok_or_else(|| ::serde::de::Error::missing_field("template_ids"))?,
        };
        Ok(Some(result))
    }

    pub(crate) fn internal_serialize<S: ::serde::ser::Serializer>(
        &self,
        s: &mut S::SerializeStruct,
    ) -> Result<(), S::Error> {
        use serde::ser::SerializeStruct;
        s.serialize_field("template_ids", &self.template_ids)?;
        Ok(())
    }
}

impl<'de> ::serde::de::Deserialize<'de> for ListTemplateResult {
    fn deserialize<D: ::serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        // struct deserializer
        use serde::de::{MapAccess, Visitor};
        struct StructVisitor;
        impl<'de> Visitor<'de> for StructVisitor {
            type Value = ListTemplateResult;
            fn expecting(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                f.write_str("a ListTemplateResult struct")
            }
            fn visit_map<V: MapAccess<'de>>(self, map: V) -> Result<Self::Value, V::Error> {
                ListTemplateResult::internal_deserialize(map)
            }
        }
        deserializer.deserialize_struct("ListTemplateResult", LIST_TEMPLATE_RESULT_FIELDS, StructVisitor)
    }
}

impl ::serde::ser::Serialize for ListTemplateResult {
    fn serialize<S: ::serde::ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        // struct serializer
        use serde::ser::SerializeStruct;
        let mut s = serializer.serialize_struct("ListTemplateResult", 1)?;
        self.internal_serialize::<S>(&mut s)?;
        s.end()
    }
}

/// Logical operator to join search queries together.
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive] // variants may be added in the future
pub enum LogicalOperator {
    /// Append a query with an "or" operator.
    OrOperator,
    /// Catch-all used for unrecognized values returned from the server. Encountering this value
    /// typically indicates that this SDK version is out of date.
    Other,
}

impl<'de> ::serde::de::Deserialize<'de> for LogicalOperator {
    fn deserialize<D: ::serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        // union deserializer
        use serde::de::{self, MapAccess, Visitor};
        struct EnumVisitor;
        impl<'de> Visitor<'de> for EnumVisitor {
            type Value = LogicalOperator;
            fn expecting(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                f.write_str("a LogicalOperator structure")
            }
            fn visit_map<V: MapAccess<'de>>(self, mut map: V) -> Result<Self::Value, V::Error> {
                let tag: &str = match map.next_key()? {
                    Some(".tag") => map.next_value()?,
                    _ => return Err(de::Error::missing_field(".tag"))
                };
                let value = match tag {
                    "or_operator" => LogicalOperator::OrOperator,
                    _ => LogicalOperator::Other,
                };
                crate::eat_json_fields(&mut map)?;
                Ok(value)
            }
        }
        const VARIANTS: &[&str] = &["or_operator",
                                    "other"];
        deserializer.deserialize_struct("LogicalOperator", VARIANTS, EnumVisitor)
    }
}

impl ::serde::ser::Serialize for LogicalOperator {
    fn serialize<S: ::serde::ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        // union serializer
        use serde::ser::SerializeStruct;
        match *self {
            LogicalOperator::OrOperator => {
                // unit
                let mut s = serializer.serialize_struct("LogicalOperator", 1)?;
                s.serialize_field(".tag", "or_operator")?;
                s.end()
            }
            LogicalOperator::Other => Err(::serde::ser::Error::custom("cannot serialize 'Other' variant"))
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive] // variants may be added in the future
pub enum LookUpPropertiesError {
    /// No property group was found.
    PropertyGroupNotFound,
    /// Catch-all used for unrecognized values returned from the server. Encountering this value
    /// typically indicates that this SDK version is out of date.
    Other,
}

impl<'de> ::serde::de::Deserialize<'de> for LookUpPropertiesError {
    fn deserialize<D: ::serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        // union deserializer
        use serde::de::{self, MapAccess, Visitor};
        struct EnumVisitor;
        impl<'de> Visitor<'de> for EnumVisitor {
            type Value = LookUpPropertiesError;
            fn expecting(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                f.write_str("a LookUpPropertiesError structure")
            }
            fn visit_map<V: MapAccess<'de>>(self, mut map: V) -> Result<Self::Value, V::Error> {
                let tag: &str = match map.next_key()? {
                    Some(".tag") => map.next_value()?,
                    _ => return Err(de::Error::missing_field(".tag"))
                };
                let value = match tag {
                    "property_group_not_found" => LookUpPropertiesError::PropertyGroupNotFound,
                    _ => LookUpPropertiesError::Other,
                };
                crate::eat_json_fields(&mut map)?;
                Ok(value)
            }
        }
        const VARIANTS: &[&str] = &["property_group_not_found",
                                    "other"];
        deserializer.deserialize_struct("LookUpPropertiesError", VARIANTS, EnumVisitor)
    }
}

impl ::serde::ser::Serialize for LookUpPropertiesError {
    fn serialize<S: ::serde::ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        // union serializer
        use serde::ser::SerializeStruct;
        match *self {
            LookUpPropertiesError::PropertyGroupNotFound => {
                // unit
                let mut s = serializer.serialize_struct("LookUpPropertiesError", 1)?;
                s.serialize_field(".tag", "property_group_not_found")?;
                s.end()
            }
            LookUpPropertiesError::Other => Err(::serde::ser::Error::custom("cannot serialize 'Other' variant"))
        }
    }
}

impl ::std::error::Error for LookUpPropertiesError {
}

impl ::std::fmt::Display for LookUpPropertiesError {
    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
        match self {
            LookUpPropertiesError::PropertyGroupNotFound => f.write_str("No property group was found."),
            _ => write!(f, "{:?}", *self),
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive] // variants may be added in the future
pub enum LookupError {
    MalformedPath(String),
    /// There is nothing at the given path.
    NotFound,
    /// We were expecting a file, but the given path refers to something that isn't a file.
    NotFile,
    /// We were expecting a folder, but the given path refers to something that isn't a folder.
    NotFolder,
    /// The file cannot be transferred because the content is restricted. For example, we might
    /// restrict a file due to legal requirements.
    RestrictedContent,
    /// Catch-all used for unrecognized values returned from the server. Encountering this value
    /// typically indicates that this SDK version is out of date.
    Other,
}

impl<'de> ::serde::de::Deserialize<'de> for LookupError {
    fn deserialize<D: ::serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        // union deserializer
        use serde::de::{self, MapAccess, Visitor};
        struct EnumVisitor;
        impl<'de> Visitor<'de> for EnumVisitor {
            type Value = LookupError;
            fn expecting(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                f.write_str("a LookupError structure")
            }
            fn visit_map<V: MapAccess<'de>>(self, mut map: V) -> Result<Self::Value, V::Error> {
                let tag: &str = match map.next_key()? {
                    Some(".tag") => map.next_value()?,
                    _ => return Err(de::Error::missing_field(".tag"))
                };
                let value = match tag {
                    "malformed_path" => {
                        match map.next_key()? {
                            Some("malformed_path") => LookupError::MalformedPath(map.next_value()?),
                            None => return Err(de::Error::missing_field("malformed_path")),
                            _ => return Err(de::Error::unknown_field(tag, VARIANTS))
                        }
                    }
                    "not_found" => LookupError::NotFound,
                    "not_file" => LookupError::NotFile,
                    "not_folder" => LookupError::NotFolder,
                    "restricted_content" => LookupError::RestrictedContent,
                    _ => LookupError::Other,
                };
                crate::eat_json_fields(&mut map)?;
                Ok(value)
            }
        }
        const VARIANTS: &[&str] = &["malformed_path",
                                    "not_found",
                                    "not_file",
                                    "not_folder",
                                    "restricted_content",
                                    "other"];
        deserializer.deserialize_struct("LookupError", VARIANTS, EnumVisitor)
    }
}

impl ::serde::ser::Serialize for LookupError {
    fn serialize<S: ::serde::ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        // union serializer
        use serde::ser::SerializeStruct;
        match *self {
            LookupError::MalformedPath(ref x) => {
                // primitive
                let mut s = serializer.serialize_struct("LookupError", 2)?;
                s.serialize_field(".tag", "malformed_path")?;
                s.serialize_field("malformed_path", x)?;
                s.end()
            }
            LookupError::NotFound => {
                // unit
                let mut s = serializer.serialize_struct("LookupError", 1)?;
                s.serialize_field(".tag", "not_found")?;
                s.end()
            }
            LookupError::NotFile => {
                // unit
                let mut s = serializer.serialize_struct("LookupError", 1)?;
                s.serialize_field(".tag", "not_file")?;
                s.end()
            }
            LookupError::NotFolder => {
                // unit
                let mut s = serializer.serialize_struct("LookupError", 1)?;
                s.serialize_field(".tag", "not_folder")?;
                s.end()
            }
            LookupError::RestrictedContent => {
                // unit
                let mut s = serializer.serialize_struct("LookupError", 1)?;
                s.serialize_field(".tag", "restricted_content")?;
                s.end()
            }
            LookupError::Other => Err(::serde::ser::Error::custom("cannot serialize 'Other' variant"))
        }
    }
}

impl ::std::error::Error for LookupError {
}

impl ::std::fmt::Display for LookupError {
    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
        match self {
            LookupError::MalformedPath(inner) => write!(f, "malformed_path: {:?}", inner),
            LookupError::NotFound => f.write_str("There is nothing at the given path."),
            LookupError::NotFile => f.write_str("We were expecting a file, but the given path refers to something that isn't a file."),
            LookupError::NotFolder => f.write_str("We were expecting a folder, but the given path refers to something that isn't a folder."),
            LookupError::RestrictedContent => f.write_str("The file cannot be transferred because the content is restricted. For example, we might restrict a file due to legal requirements."),
            _ => write!(f, "{:?}", *self),
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive] // variants may be added in the future
pub enum ModifyTemplateError {
    /// Template does not exist for the given identifier.
    TemplateNotFound(TemplateId),
    /// You do not have permission to modify this template.
    RestrictedContent,
    /// A property field key with that name already exists in the template.
    ConflictingPropertyNames,
    /// There are too many properties in the changed template. The maximum number of properties per
    /// template is 32.
    TooManyProperties,
    /// There are too many templates for the team.
    TooManyTemplates,
    /// The template name, description or one or more of the property field keys is too large.
    TemplateAttributeTooLarge,
    /// Catch-all used for unrecognized values returned from the server. Encountering this value
    /// typically indicates that this SDK version is out of date.
    Other,
}

impl<'de> ::serde::de::Deserialize<'de> for ModifyTemplateError {
    fn deserialize<D: ::serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        // union deserializer
        use serde::de::{self, MapAccess, Visitor};
        struct EnumVisitor;
        impl<'de> Visitor<'de> for EnumVisitor {
            type Value = ModifyTemplateError;
            fn expecting(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                f.write_str("a ModifyTemplateError structure")
            }
            fn visit_map<V: MapAccess<'de>>(self, mut map: V) -> Result<Self::Value, V::Error> {
                let tag: &str = match map.next_key()? {
                    Some(".tag") => map.next_value()?,
                    _ => return Err(de::Error::missing_field(".tag"))
                };
                let value = match tag {
                    "template_not_found" => {
                        match map.next_key()? {
                            Some("template_not_found") => ModifyTemplateError::TemplateNotFound(map.next_value()?),
                            None => return Err(de::Error::missing_field("template_not_found")),
                            _ => return Err(de::Error::unknown_field(tag, VARIANTS))
                        }
                    }
                    "restricted_content" => ModifyTemplateError::RestrictedContent,
                    "conflicting_property_names" => ModifyTemplateError::ConflictingPropertyNames,
                    "too_many_properties" => ModifyTemplateError::TooManyProperties,
                    "too_many_templates" => ModifyTemplateError::TooManyTemplates,
                    "template_attribute_too_large" => ModifyTemplateError::TemplateAttributeTooLarge,
                    _ => ModifyTemplateError::Other,
                };
                crate::eat_json_fields(&mut map)?;
                Ok(value)
            }
        }
        const VARIANTS: &[&str] = &["template_not_found",
                                    "restricted_content",
                                    "other",
                                    "conflicting_property_names",
                                    "too_many_properties",
                                    "too_many_templates",
                                    "template_attribute_too_large"];
        deserializer.deserialize_struct("ModifyTemplateError", VARIANTS, EnumVisitor)
    }
}

impl ::serde::ser::Serialize for ModifyTemplateError {
    fn serialize<S: ::serde::ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        // union serializer
        use serde::ser::SerializeStruct;
        match *self {
            ModifyTemplateError::TemplateNotFound(ref x) => {
                // primitive
                let mut s = serializer.serialize_struct("ModifyTemplateError", 2)?;
                s.serialize_field(".tag", "template_not_found")?;
                s.serialize_field("template_not_found", x)?;
                s.end()
            }
            ModifyTemplateError::RestrictedContent => {
                // unit
                let mut s = serializer.serialize_struct("ModifyTemplateError", 1)?;
                s.serialize_field(".tag", "restricted_content")?;
                s.end()
            }
            ModifyTemplateError::ConflictingPropertyNames => {
                // unit
                let mut s = serializer.serialize_struct("ModifyTemplateError", 1)?;
                s.serialize_field(".tag", "conflicting_property_names")?;
                s.end()
            }
            ModifyTemplateError::TooManyProperties => {
                // unit
                let mut s = serializer.serialize_struct("ModifyTemplateError", 1)?;
                s.serialize_field(".tag", "too_many_properties")?;
                s.end()
            }
            ModifyTemplateError::TooManyTemplates => {
                // unit
                let mut s = serializer.serialize_struct("ModifyTemplateError", 1)?;
                s.serialize_field(".tag", "too_many_templates")?;
                s.end()
            }
            ModifyTemplateError::TemplateAttributeTooLarge => {
                // unit
                let mut s = serializer.serialize_struct("ModifyTemplateError", 1)?;
                s.serialize_field(".tag", "template_attribute_too_large")?;
                s.end()
            }
            ModifyTemplateError::Other => Err(::serde::ser::Error::custom("cannot serialize 'Other' variant"))
        }
    }
}

impl ::std::error::Error for ModifyTemplateError {
}

impl ::std::fmt::Display for ModifyTemplateError {
    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
        match self {
            ModifyTemplateError::TemplateNotFound(inner) => write!(f, "Template does not exist for the given identifier: {:?}", inner),
            ModifyTemplateError::RestrictedContent => f.write_str("You do not have permission to modify this template."),
            ModifyTemplateError::ConflictingPropertyNames => f.write_str("A property field key with that name already exists in the template."),
            ModifyTemplateError::TooManyProperties => f.write_str("There are too many properties in the changed template. The maximum number of properties per template is 32."),
            ModifyTemplateError::TooManyTemplates => f.write_str("There are too many templates for the team."),
            ModifyTemplateError::TemplateAttributeTooLarge => f.write_str("The template name, description or one or more of the property field keys is too large."),
            _ => write!(f, "{:?}", *self),
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive] // structs may have more fields added in the future.
pub struct OverwritePropertyGroupArg {
    /// A unique identifier for the file or folder.
    pub path: PathOrId,
    /// The property groups "snapshot" updates to force apply. No two groups in the input should
    /// refer to the same template.
    pub property_groups: Vec<PropertyGroup>,
}

impl OverwritePropertyGroupArg {
    pub fn new(path: PathOrId, property_groups: Vec<PropertyGroup>) -> Self {
        OverwritePropertyGroupArg {
            path,
            property_groups,
        }
    }
}

const OVERWRITE_PROPERTY_GROUP_ARG_FIELDS: &[&str] = &["path",
                                                       "property_groups"];
impl OverwritePropertyGroupArg {
    pub(crate) fn internal_deserialize<'de, V: ::serde::de::MapAccess<'de>>(
        map: V,
    ) -> Result<OverwritePropertyGroupArg, V::Error> {
        Self::internal_deserialize_opt(map, false).map(Option::unwrap)
    }

    pub(crate) fn internal_deserialize_opt<'de, V: ::serde::de::MapAccess<'de>>(
        mut map: V,
        optional: bool,
    ) -> Result<Option<OverwritePropertyGroupArg>, V::Error> {
        let mut field_path = None;
        let mut field_property_groups = None;
        let mut nothing = true;
        while let Some(key) = map.next_key::<&str>()? {
            nothing = false;
            match key {
                "path" => {
                    if field_path.is_some() {
                        return Err(::serde::de::Error::duplicate_field("path"));
                    }
                    field_path = Some(map.next_value()?);
                }
                "property_groups" => {
                    if field_property_groups.is_some() {
                        return Err(::serde::de::Error::duplicate_field("property_groups"));
                    }
                    field_property_groups = Some(map.next_value()?);
                }
                _ => {
                    // unknown field allowed and ignored
                    map.next_value::<::serde_json::Value>()?;
                }
            }
        }
        if optional && nothing {
            return Ok(None);
        }
        let result = OverwritePropertyGroupArg {
            path: field_path.ok_or_else(|| ::serde::de::Error::missing_field("path"))?,
            property_groups: field_property_groups.ok_or_else(|| ::serde::de::Error::missing_field("property_groups"))?,
        };
        Ok(Some(result))
    }

    pub(crate) fn internal_serialize<S: ::serde::ser::Serializer>(
        &self,
        s: &mut S::SerializeStruct,
    ) -> Result<(), S::Error> {
        use serde::ser::SerializeStruct;
        s.serialize_field("path", &self.path)?;
        s.serialize_field("property_groups", &self.property_groups)?;
        Ok(())
    }
}

impl<'de> ::serde::de::Deserialize<'de> for OverwritePropertyGroupArg {
    fn deserialize<D: ::serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        // struct deserializer
        use serde::de::{MapAccess, Visitor};
        struct StructVisitor;
        impl<'de> Visitor<'de> for StructVisitor {
            type Value = OverwritePropertyGroupArg;
            fn expecting(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                f.write_str("a OverwritePropertyGroupArg struct")
            }
            fn visit_map<V: MapAccess<'de>>(self, map: V) -> Result<Self::Value, V::Error> {
                OverwritePropertyGroupArg::internal_deserialize(map)
            }
        }
        deserializer.deserialize_struct("OverwritePropertyGroupArg", OVERWRITE_PROPERTY_GROUP_ARG_FIELDS, StructVisitor)
    }
}

impl ::serde::ser::Serialize for OverwritePropertyGroupArg {
    fn serialize<S: ::serde::ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        // struct serializer
        use serde::ser::SerializeStruct;
        let mut s = serializer.serialize_struct("OverwritePropertyGroupArg", 2)?;
        self.internal_serialize::<S>(&mut s)?;
        s.end()
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive] // variants may be added in the future
pub enum PropertiesError {
    /// Template does not exist for the given identifier.
    TemplateNotFound(TemplateId),
    /// You do not have permission to modify this template.
    RestrictedContent,
    Path(LookupError),
    /// This folder cannot be tagged. Tagging folders is not supported for team-owned templates.
    UnsupportedFolder,
    /// Catch-all used for unrecognized values returned from the server. Encountering this value
    /// typically indicates that this SDK version is out of date.
    Other,
}

impl<'de> ::serde::de::Deserialize<'de> for PropertiesError {
    fn deserialize<D: ::serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        // union deserializer
        use serde::de::{self, MapAccess, Visitor};
        struct EnumVisitor;
        impl<'de> Visitor<'de> for EnumVisitor {
            type Value = PropertiesError;
            fn expecting(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                f.write_str("a PropertiesError structure")
            }
            fn visit_map<V: MapAccess<'de>>(self, mut map: V) -> Result<Self::Value, V::Error> {
                let tag: &str = match map.next_key()? {
                    Some(".tag") => map.next_value()?,
                    _ => return Err(de::Error::missing_field(".tag"))
                };
                let value = match tag {
                    "template_not_found" => {
                        match map.next_key()? {
                            Some("template_not_found") => PropertiesError::TemplateNotFound(map.next_value()?),
                            None => return Err(de::Error::missing_field("template_not_found")),
                            _ => return Err(de::Error::unknown_field(tag, VARIANTS))
                        }
                    }
                    "restricted_content" => PropertiesError::RestrictedContent,
                    "path" => {
                        match map.next_key()? {
                            Some("path") => PropertiesError::Path(map.next_value()?),
                            None => return Err(de::Error::missing_field("path")),
                            _ => return Err(de::Error::unknown_field(tag, VARIANTS))
                        }
                    }
                    "unsupported_folder" => PropertiesError::UnsupportedFolder,
                    _ => PropertiesError::Other,
                };
                crate::eat_json_fields(&mut map)?;
                Ok(value)
            }
        }
        const VARIANTS: &[&str] = &["template_not_found",
                                    "restricted_content",
                                    "other",
                                    "path",
                                    "unsupported_folder"];
        deserializer.deserialize_struct("PropertiesError", VARIANTS, EnumVisitor)
    }
}

impl ::serde::ser::Serialize for PropertiesError {
    fn serialize<S: ::serde::ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        // union serializer
        use serde::ser::SerializeStruct;
        match *self {
            PropertiesError::TemplateNotFound(ref x) => {
                // primitive
                let mut s = serializer.serialize_struct("PropertiesError", 2)?;
                s.serialize_field(".tag", "template_not_found")?;
                s.serialize_field("template_not_found", x)?;
                s.end()
            }
            PropertiesError::RestrictedContent => {
                // unit
                let mut s = serializer.serialize_struct("PropertiesError", 1)?;
                s.serialize_field(".tag", "restricted_content")?;
                s.end()
            }
            PropertiesError::Path(ref x) => {
                // union or polymporphic struct
                let mut s = serializer.serialize_struct("PropertiesError", 2)?;
                s.serialize_field(".tag", "path")?;
                s.serialize_field("path", x)?;
                s.end()
            }
            PropertiesError::UnsupportedFolder => {
                // unit
                let mut s = serializer.serialize_struct("PropertiesError", 1)?;
                s.serialize_field(".tag", "unsupported_folder")?;
                s.end()
            }
            PropertiesError::Other => Err(::serde::ser::Error::custom("cannot serialize 'Other' variant"))
        }
    }
}

impl ::std::error::Error for PropertiesError {
    fn source(&self) -> Option<&(dyn ::std::error::Error + 'static)> {
        match self {
            PropertiesError::Path(inner) => Some(inner),
            _ => None,
        }
    }
}

impl ::std::fmt::Display for PropertiesError {
    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
        match self {
            PropertiesError::TemplateNotFound(inner) => write!(f, "Template does not exist for the given identifier: {:?}", inner),
            PropertiesError::RestrictedContent => f.write_str("You do not have permission to modify this template."),
            PropertiesError::Path(inner) => write!(f, "{}", inner),
            PropertiesError::UnsupportedFolder => f.write_str("This folder cannot be tagged. Tagging folders is not supported for team-owned templates."),
            _ => write!(f, "{:?}", *self),
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive] // structs may have more fields added in the future.
pub struct PropertiesSearchArg {
    /// Queries to search.
    pub queries: Vec<PropertiesSearchQuery>,
    /// Filter results to contain only properties associated with these template IDs.
    pub template_filter: TemplateFilter,
}

impl PropertiesSearchArg {
    pub fn new(queries: Vec<PropertiesSearchQuery>) -> Self {
        PropertiesSearchArg {
            queries,
            template_filter: TemplateFilter::FilterNone,
        }
    }

    pub fn with_template_filter(mut self, value: TemplateFilter) -> Self {
        self.template_filter = value;
        self
    }
}

const PROPERTIES_SEARCH_ARG_FIELDS: &[&str] = &["queries",
                                                "template_filter"];
impl PropertiesSearchArg {
    pub(crate) fn internal_deserialize<'de, V: ::serde::de::MapAccess<'de>>(
        map: V,
    ) -> Result<PropertiesSearchArg, V::Error> {
        Self::internal_deserialize_opt(map, false).map(Option::unwrap)
    }

    pub(crate) fn internal_deserialize_opt<'de, V: ::serde::de::MapAccess<'de>>(
        mut map: V,
        optional: bool,
    ) -> Result<Option<PropertiesSearchArg>, V::Error> {
        let mut field_queries = None;
        let mut field_template_filter = None;
        let mut nothing = true;
        while let Some(key) = map.next_key::<&str>()? {
            nothing = false;
            match key {
                "queries" => {
                    if field_queries.is_some() {
                        return Err(::serde::de::Error::duplicate_field("queries"));
                    }
                    field_queries = Some(map.next_value()?);
                }
                "template_filter" => {
                    if field_template_filter.is_some() {
                        return Err(::serde::de::Error::duplicate_field("template_filter"));
                    }
                    field_template_filter = Some(map.next_value()?);
                }
                _ => {
                    // unknown field allowed and ignored
                    map.next_value::<::serde_json::Value>()?;
                }
            }
        }
        if optional && nothing {
            return Ok(None);
        }
        let result = PropertiesSearchArg {
            queries: field_queries.ok_or_else(|| ::serde::de::Error::missing_field("queries"))?,
            template_filter: field_template_filter.unwrap_or(TemplateFilter::FilterNone),
        };
        Ok(Some(result))
    }

    pub(crate) fn internal_serialize<S: ::serde::ser::Serializer>(
        &self,
        s: &mut S::SerializeStruct,
    ) -> Result<(), S::Error> {
        use serde::ser::SerializeStruct;
        s.serialize_field("queries", &self.queries)?;
        s.serialize_field("template_filter", &self.template_filter)?;
        Ok(())
    }
}

impl<'de> ::serde::de::Deserialize<'de> for PropertiesSearchArg {
    fn deserialize<D: ::serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        // struct deserializer
        use serde::de::{MapAccess, Visitor};
        struct StructVisitor;
        impl<'de> Visitor<'de> for StructVisitor {
            type Value = PropertiesSearchArg;
            fn expecting(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                f.write_str("a PropertiesSearchArg struct")
            }
            fn visit_map<V: MapAccess<'de>>(self, map: V) -> Result<Self::Value, V::Error> {
                PropertiesSearchArg::internal_deserialize(map)
            }
        }
        deserializer.deserialize_struct("PropertiesSearchArg", PROPERTIES_SEARCH_ARG_FIELDS, StructVisitor)
    }
}

impl ::serde::ser::Serialize for PropertiesSearchArg {
    fn serialize<S: ::serde::ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        // struct serializer
        use serde::ser::SerializeStruct;
        let mut s = serializer.serialize_struct("PropertiesSearchArg", 2)?;
        self.internal_serialize::<S>(&mut s)?;
        s.end()
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive] // structs may have more fields added in the future.
pub struct PropertiesSearchContinueArg {
    /// The cursor returned by your last call to [`properties_search()`](properties_search) or
    /// [`properties_search_continue()`](properties_search_continue).
    pub cursor: PropertiesSearchCursor,
}

impl PropertiesSearchContinueArg {
    pub fn new(cursor: PropertiesSearchCursor) -> Self {
        PropertiesSearchContinueArg {
            cursor,
        }
    }
}

const PROPERTIES_SEARCH_CONTINUE_ARG_FIELDS: &[&str] = &["cursor"];
impl PropertiesSearchContinueArg {
    pub(crate) fn internal_deserialize<'de, V: ::serde::de::MapAccess<'de>>(
        map: V,
    ) -> Result<PropertiesSearchContinueArg, V::Error> {
        Self::internal_deserialize_opt(map, false).map(Option::unwrap)
    }

    pub(crate) fn internal_deserialize_opt<'de, V: ::serde::de::MapAccess<'de>>(
        mut map: V,
        optional: bool,
    ) -> Result<Option<PropertiesSearchContinueArg>, V::Error> {
        let mut field_cursor = None;
        let mut nothing = true;
        while let Some(key) = map.next_key::<&str>()? {
            nothing = false;
            match key {
                "cursor" => {
                    if field_cursor.is_some() {
                        return Err(::serde::de::Error::duplicate_field("cursor"));
                    }
                    field_cursor = Some(map.next_value()?);
                }
                _ => {
                    // unknown field allowed and ignored
                    map.next_value::<::serde_json::Value>()?;
                }
            }
        }
        if optional && nothing {
            return Ok(None);
        }
        let result = PropertiesSearchContinueArg {
            cursor: field_cursor.ok_or_else(|| ::serde::de::Error::missing_field("cursor"))?,
        };
        Ok(Some(result))
    }

    pub(crate) fn internal_serialize<S: ::serde::ser::Serializer>(
        &self,
        s: &mut S::SerializeStruct,
    ) -> Result<(), S::Error> {
        use serde::ser::SerializeStruct;
        s.serialize_field("cursor", &self.cursor)?;
        Ok(())
    }
}

impl<'de> ::serde::de::Deserialize<'de> for PropertiesSearchContinueArg {
    fn deserialize<D: ::serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        // struct deserializer
        use serde::de::{MapAccess, Visitor};
        struct StructVisitor;
        impl<'de> Visitor<'de> for StructVisitor {
            type Value = PropertiesSearchContinueArg;
            fn expecting(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                f.write_str("a PropertiesSearchContinueArg struct")
            }
            fn visit_map<V: MapAccess<'de>>(self, map: V) -> Result<Self::Value, V::Error> {
                PropertiesSearchContinueArg::internal_deserialize(map)
            }
        }
        deserializer.deserialize_struct("PropertiesSearchContinueArg", PROPERTIES_SEARCH_CONTINUE_ARG_FIELDS, StructVisitor)
    }
}

impl ::serde::ser::Serialize for PropertiesSearchContinueArg {
    fn serialize<S: ::serde::ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        // struct serializer
        use serde::ser::SerializeStruct;
        let mut s = serializer.serialize_struct("PropertiesSearchContinueArg", 1)?;
        self.internal_serialize::<S>(&mut s)?;
        s.end()
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive] // variants may be added in the future
pub enum PropertiesSearchContinueError {
    /// Indicates that the cursor has been invalidated. Call
    /// [`properties_search()`](properties_search) to obtain a new cursor.
    Reset,
    /// Catch-all used for unrecognized values returned from the server. Encountering this value
    /// typically indicates that this SDK version is out of date.
    Other,
}

impl<'de> ::serde::de::Deserialize<'de> for PropertiesSearchContinueError {
    fn deserialize<D: ::serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        // union deserializer
        use serde::de::{self, MapAccess, Visitor};
        struct EnumVisitor;
        impl<'de> Visitor<'de> for EnumVisitor {
            type Value = PropertiesSearchContinueError;
            fn expecting(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                f.write_str("a PropertiesSearchContinueError structure")
            }
            fn visit_map<V: MapAccess<'de>>(self, mut map: V) -> Result<Self::Value, V::Error> {
                let tag: &str = match map.next_key()? {
                    Some(".tag") => map.next_value()?,
                    _ => return Err(de::Error::missing_field(".tag"))
                };
                let value = match tag {
                    "reset" => PropertiesSearchContinueError::Reset,
                    _ => PropertiesSearchContinueError::Other,
                };
                crate::eat_json_fields(&mut map)?;
                Ok(value)
            }
        }
        const VARIANTS: &[&str] = &["reset",
                                    "other"];
        deserializer.deserialize_struct("PropertiesSearchContinueError", VARIANTS, EnumVisitor)
    }
}

impl ::serde::ser::Serialize for PropertiesSearchContinueError {
    fn serialize<S: ::serde::ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        // union serializer
        use serde::ser::SerializeStruct;
        match *self {
            PropertiesSearchContinueError::Reset => {
                // unit
                let mut s = serializer.serialize_struct("PropertiesSearchContinueError", 1)?;
                s.serialize_field(".tag", "reset")?;
                s.end()
            }
            PropertiesSearchContinueError::Other => Err(::serde::ser::Error::custom("cannot serialize 'Other' variant"))
        }
    }
}

impl ::std::error::Error for PropertiesSearchContinueError {
}

impl ::std::fmt::Display for PropertiesSearchContinueError {
    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
        write!(f, "{:?}", *self)
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive] // variants may be added in the future
pub enum PropertiesSearchError {
    PropertyGroupLookup(LookUpPropertiesError),
    /// Catch-all used for unrecognized values returned from the server. Encountering this value
    /// typically indicates that this SDK version is out of date.
    Other,
}

impl<'de> ::serde::de::Deserialize<'de> for PropertiesSearchError {
    fn deserialize<D: ::serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        // union deserializer
        use serde::de::{self, MapAccess, Visitor};
        struct EnumVisitor;
        impl<'de> Visitor<'de> for EnumVisitor {
            type Value = PropertiesSearchError;
            fn expecting(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                f.write_str("a PropertiesSearchError structure")
            }
            fn visit_map<V: MapAccess<'de>>(self, mut map: V) -> Result<Self::Value, V::Error> {
                let tag: &str = match map.next_key()? {
                    Some(".tag") => map.next_value()?,
                    _ => return Err(de::Error::missing_field(".tag"))
                };
                let value = match tag {
                    "property_group_lookup" => {
                        match map.next_key()? {
                            Some("property_group_lookup") => PropertiesSearchError::PropertyGroupLookup(map.next_value()?),
                            None => return Err(de::Error::missing_field("property_group_lookup")),
                            _ => return Err(de::Error::unknown_field(tag, VARIANTS))
                        }
                    }
                    _ => PropertiesSearchError::Other,
                };
                crate::eat_json_fields(&mut map)?;
                Ok(value)
            }
        }
        const VARIANTS: &[&str] = &["property_group_lookup",
                                    "other"];
        deserializer.deserialize_struct("PropertiesSearchError", VARIANTS, EnumVisitor)
    }
}

impl ::serde::ser::Serialize for PropertiesSearchError {
    fn serialize<S: ::serde::ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        // union serializer
        use serde::ser::SerializeStruct;
        match *self {
            PropertiesSearchError::PropertyGroupLookup(ref x) => {
                // union or polymporphic struct
                let mut s = serializer.serialize_struct("PropertiesSearchError", 2)?;
                s.serialize_field(".tag", "property_group_lookup")?;
                s.serialize_field("property_group_lookup", x)?;
                s.end()
            }
            PropertiesSearchError::Other => Err(::serde::ser::Error::custom("cannot serialize 'Other' variant"))
        }
    }
}

impl ::std::error::Error for PropertiesSearchError {
    fn source(&self) -> Option<&(dyn ::std::error::Error + 'static)> {
        match self {
            PropertiesSearchError::PropertyGroupLookup(inner) => Some(inner),
            _ => None,
        }
    }
}

impl ::std::fmt::Display for PropertiesSearchError {
    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
        match self {
            PropertiesSearchError::PropertyGroupLookup(inner) => write!(f, "{}", inner),
            _ => write!(f, "{:?}", *self),
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive] // structs may have more fields added in the future.
pub struct PropertiesSearchMatch {
    /// The ID for the matched file or folder.
    pub id: Id,
    /// The path for the matched file or folder.
    pub path: String,
    /// Whether the file or folder is deleted.
    pub is_deleted: bool,
    /// List of custom property groups associated with the file.
    pub property_groups: Vec<PropertyGroup>,
}

impl PropertiesSearchMatch {
    pub fn new(
        id: Id,
        path: String,
        is_deleted: bool,
        property_groups: Vec<PropertyGroup>,
    ) -> Self {
        PropertiesSearchMatch {
            id,
            path,
            is_deleted,
            property_groups,
        }
    }
}

const PROPERTIES_SEARCH_MATCH_FIELDS: &[&str] = &["id",
                                                  "path",
                                                  "is_deleted",
                                                  "property_groups"];
impl PropertiesSearchMatch {
    pub(crate) fn internal_deserialize<'de, V: ::serde::de::MapAccess<'de>>(
        map: V,
    ) -> Result<PropertiesSearchMatch, V::Error> {
        Self::internal_deserialize_opt(map, false).map(Option::unwrap)
    }

    pub(crate) fn internal_deserialize_opt<'de, V: ::serde::de::MapAccess<'de>>(
        mut map: V,
        optional: bool,
    ) -> Result<Option<PropertiesSearchMatch>, V::Error> {
        let mut field_id = None;
        let mut field_path = None;
        let mut field_is_deleted = None;
        let mut field_property_groups = None;
        let mut nothing = true;
        while let Some(key) = map.next_key::<&str>()? {
            nothing = false;
            match key {
                "id" => {
                    if field_id.is_some() {
                        return Err(::serde::de::Error::duplicate_field("id"));
                    }
                    field_id = Some(map.next_value()?);
                }
                "path" => {
                    if field_path.is_some() {
                        return Err(::serde::de::Error::duplicate_field("path"));
                    }
                    field_path = Some(map.next_value()?);
                }
                "is_deleted" => {
                    if field_is_deleted.is_some() {
                        return Err(::serde::de::Error::duplicate_field("is_deleted"));
                    }
                    field_is_deleted = Some(map.next_value()?);
                }
                "property_groups" => {
                    if field_property_groups.is_some() {
                        return Err(::serde::de::Error::duplicate_field("property_groups"));
                    }
                    field_property_groups = Some(map.next_value()?);
                }
                _ => {
                    // unknown field allowed and ignored
                    map.next_value::<::serde_json::Value>()?;
                }
            }
        }
        if optional && nothing {
            return Ok(None);
        }
        let result = PropertiesSearchMatch {
            id: field_id.ok_or_else(|| ::serde::de::Error::missing_field("id"))?,
            path: field_path.ok_or_else(|| ::serde::de::Error::missing_field("path"))?,
            is_deleted: field_is_deleted.ok_or_else(|| ::serde::de::Error::missing_field("is_deleted"))?,
            property_groups: field_property_groups.ok_or_else(|| ::serde::de::Error::missing_field("property_groups"))?,
        };
        Ok(Some(result))
    }

    pub(crate) fn internal_serialize<S: ::serde::ser::Serializer>(
        &self,
        s: &mut S::SerializeStruct,
    ) -> Result<(), S::Error> {
        use serde::ser::SerializeStruct;
        s.serialize_field("id", &self.id)?;
        s.serialize_field("path", &self.path)?;
        s.serialize_field("is_deleted", &self.is_deleted)?;
        s.serialize_field("property_groups", &self.property_groups)?;
        Ok(())
    }
}

impl<'de> ::serde::de::Deserialize<'de> for PropertiesSearchMatch {
    fn deserialize<D: ::serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        // struct deserializer
        use serde::de::{MapAccess, Visitor};
        struct StructVisitor;
        impl<'de> Visitor<'de> for StructVisitor {
            type Value = PropertiesSearchMatch;
            fn expecting(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                f.write_str("a PropertiesSearchMatch struct")
            }
            fn visit_map<V: MapAccess<'de>>(self, map: V) -> Result<Self::Value, V::Error> {
                PropertiesSearchMatch::internal_deserialize(map)
            }
        }
        deserializer.deserialize_struct("PropertiesSearchMatch", PROPERTIES_SEARCH_MATCH_FIELDS, StructVisitor)
    }
}

impl ::serde::ser::Serialize for PropertiesSearchMatch {
    fn serialize<S: ::serde::ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        // struct serializer
        use serde::ser::SerializeStruct;
        let mut s = serializer.serialize_struct("PropertiesSearchMatch", 4)?;
        self.internal_serialize::<S>(&mut s)?;
        s.end()
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive] // variants may be added in the future
pub enum PropertiesSearchMode {
    /// Search for a value associated with this field name.
    FieldName(String),
    /// Catch-all used for unrecognized values returned from the server. Encountering this value
    /// typically indicates that this SDK version is out of date.
    Other,
}

impl<'de> ::serde::de::Deserialize<'de> for PropertiesSearchMode {
    fn deserialize<D: ::serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        // union deserializer
        use serde::de::{self, MapAccess, Visitor};
        struct EnumVisitor;
        impl<'de> Visitor<'de> for EnumVisitor {
            type Value = PropertiesSearchMode;
            fn expecting(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                f.write_str("a PropertiesSearchMode structure")
            }
            fn visit_map<V: MapAccess<'de>>(self, mut map: V) -> Result<Self::Value, V::Error> {
                let tag: &str = match map.next_key()? {
                    Some(".tag") => map.next_value()?,
                    _ => return Err(de::Error::missing_field(".tag"))
                };
                let value = match tag {
                    "field_name" => {
                        match map.next_key()? {
                            Some("field_name") => PropertiesSearchMode::FieldName(map.next_value()?),
                            None => return Err(de::Error::missing_field("field_name")),
                            _ => return Err(de::Error::unknown_field(tag, VARIANTS))
                        }
                    }
                    _ => PropertiesSearchMode::Other,
                };
                crate::eat_json_fields(&mut map)?;
                Ok(value)
            }
        }
        const VARIANTS: &[&str] = &["field_name",
                                    "other"];
        deserializer.deserialize_struct("PropertiesSearchMode", VARIANTS, EnumVisitor)
    }
}

impl ::serde::ser::Serialize for PropertiesSearchMode {
    fn serialize<S: ::serde::ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        // union serializer
        use serde::ser::SerializeStruct;
        match *self {
            PropertiesSearchMode::FieldName(ref x) => {
                // primitive
                let mut s = serializer.serialize_struct("PropertiesSearchMode", 2)?;
                s.serialize_field(".tag", "field_name")?;
                s.serialize_field("field_name", x)?;
                s.end()
            }
            PropertiesSearchMode::Other => Err(::serde::ser::Error::custom("cannot serialize 'Other' variant"))
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive] // structs may have more fields added in the future.
pub struct PropertiesSearchQuery {
    /// The property field value for which to search across templates.
    pub query: String,
    /// The mode with which to perform the search.
    pub mode: PropertiesSearchMode,
    /// The logical operator with which to append the query.
    pub logical_operator: LogicalOperator,
}

impl PropertiesSearchQuery {
    pub fn new(query: String, mode: PropertiesSearchMode) -> Self {
        PropertiesSearchQuery {
            query,
            mode,
            logical_operator: LogicalOperator::OrOperator,
        }
    }

    pub fn with_logical_operator(mut self, value: LogicalOperator) -> Self {
        self.logical_operator = value;
        self
    }
}

const PROPERTIES_SEARCH_QUERY_FIELDS: &[&str] = &["query",
                                                  "mode",
                                                  "logical_operator"];
impl PropertiesSearchQuery {
    pub(crate) fn internal_deserialize<'de, V: ::serde::de::MapAccess<'de>>(
        map: V,
    ) -> Result<PropertiesSearchQuery, V::Error> {
        Self::internal_deserialize_opt(map, false).map(Option::unwrap)
    }

    pub(crate) fn internal_deserialize_opt<'de, V: ::serde::de::MapAccess<'de>>(
        mut map: V,
        optional: bool,
    ) -> Result<Option<PropertiesSearchQuery>, V::Error> {
        let mut field_query = None;
        let mut field_mode = None;
        let mut field_logical_operator = None;
        let mut nothing = true;
        while let Some(key) = map.next_key::<&str>()? {
            nothing = false;
            match key {
                "query" => {
                    if field_query.is_some() {
                        return Err(::serde::de::Error::duplicate_field("query"));
                    }
                    field_query = Some(map.next_value()?);
                }
                "mode" => {
                    if field_mode.is_some() {
                        return Err(::serde::de::Error::duplicate_field("mode"));
                    }
                    field_mode = Some(map.next_value()?);
                }
                "logical_operator" => {
                    if field_logical_operator.is_some() {
                        return Err(::serde::de::Error::duplicate_field("logical_operator"));
                    }
                    field_logical_operator = Some(map.next_value()?);
                }
                _ => {
                    // unknown field allowed and ignored
                    map.next_value::<::serde_json::Value>()?;
                }
            }
        }
        if optional && nothing {
            return Ok(None);
        }
        let result = PropertiesSearchQuery {
            query: field_query.ok_or_else(|| ::serde::de::Error::missing_field("query"))?,
            mode: field_mode.ok_or_else(|| ::serde::de::Error::missing_field("mode"))?,
            logical_operator: field_logical_operator.unwrap_or(LogicalOperator::OrOperator),
        };
        Ok(Some(result))
    }

    pub(crate) fn internal_serialize<S: ::serde::ser::Serializer>(
        &self,
        s: &mut S::SerializeStruct,
    ) -> Result<(), S::Error> {
        use serde::ser::SerializeStruct;
        s.serialize_field("query", &self.query)?;
        s.serialize_field("mode", &self.mode)?;
        s.serialize_field("logical_operator", &self.logical_operator)?;
        Ok(())
    }
}

impl<'de> ::serde::de::Deserialize<'de> for PropertiesSearchQuery {
    fn deserialize<D: ::serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        // struct deserializer
        use serde::de::{MapAccess, Visitor};
        struct StructVisitor;
        impl<'de> Visitor<'de> for StructVisitor {
            type Value = PropertiesSearchQuery;
            fn expecting(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                f.write_str("a PropertiesSearchQuery struct")
            }
            fn visit_map<V: MapAccess<'de>>(self, map: V) -> Result<Self::Value, V::Error> {
                PropertiesSearchQuery::internal_deserialize(map)
            }
        }
        deserializer.deserialize_struct("PropertiesSearchQuery", PROPERTIES_SEARCH_QUERY_FIELDS, StructVisitor)
    }
}

impl ::serde::ser::Serialize for PropertiesSearchQuery {
    fn serialize<S: ::serde::ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        // struct serializer
        use serde::ser::SerializeStruct;
        let mut s = serializer.serialize_struct("PropertiesSearchQuery", 3)?;
        self.internal_serialize::<S>(&mut s)?;
        s.end()
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive] // structs may have more fields added in the future.
pub struct PropertiesSearchResult {
    /// A list (possibly empty) of matches for the query.
    pub matches: Vec<PropertiesSearchMatch>,
    /// Pass the cursor into [`properties_search_continue()`](properties_search_continue) to
    /// continue to receive search results. Cursor will be null when there are no more results.
    pub cursor: Option<PropertiesSearchCursor>,
}

impl PropertiesSearchResult {
    pub fn new(matches: Vec<PropertiesSearchMatch>) -> Self {
        PropertiesSearchResult {
            matches,
            cursor: None,
        }
    }

    pub fn with_cursor(mut self, value: PropertiesSearchCursor) -> Self {
        self.cursor = Some(value);
        self
    }
}

const PROPERTIES_SEARCH_RESULT_FIELDS: &[&str] = &["matches",
                                                   "cursor"];
impl PropertiesSearchResult {
    pub(crate) fn internal_deserialize<'de, V: ::serde::de::MapAccess<'de>>(
        map: V,
    ) -> Result<PropertiesSearchResult, V::Error> {
        Self::internal_deserialize_opt(map, false).map(Option::unwrap)
    }

    pub(crate) fn internal_deserialize_opt<'de, V: ::serde::de::MapAccess<'de>>(
        mut map: V,
        optional: bool,
    ) -> Result<Option<PropertiesSearchResult>, V::Error> {
        let mut field_matches = None;
        let mut field_cursor = None;
        let mut nothing = true;
        while let Some(key) = map.next_key::<&str>()? {
            nothing = false;
            match key {
                "matches" => {
                    if field_matches.is_some() {
                        return Err(::serde::de::Error::duplicate_field("matches"));
                    }
                    field_matches = Some(map.next_value()?);
                }
                "cursor" => {
                    if field_cursor.is_some() {
                        return Err(::serde::de::Error::duplicate_field("cursor"));
                    }
                    field_cursor = Some(map.next_value()?);
                }
                _ => {
                    // unknown field allowed and ignored
                    map.next_value::<::serde_json::Value>()?;
                }
            }
        }
        if optional && nothing {
            return Ok(None);
        }
        let result = PropertiesSearchResult {
            matches: field_matches.ok_or_else(|| ::serde::de::Error::missing_field("matches"))?,
            cursor: field_cursor,
        };
        Ok(Some(result))
    }

    pub(crate) fn internal_serialize<S: ::serde::ser::Serializer>(
        &self,
        s: &mut S::SerializeStruct,
    ) -> Result<(), S::Error> {
        use serde::ser::SerializeStruct;
        s.serialize_field("matches", &self.matches)?;
        if let Some(val) = &self.cursor {
            s.serialize_field("cursor", val)?;
        }
        Ok(())
    }
}

impl<'de> ::serde::de::Deserialize<'de> for PropertiesSearchResult {
    fn deserialize<D: ::serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        // struct deserializer
        use serde::de::{MapAccess, Visitor};
        struct StructVisitor;
        impl<'de> Visitor<'de> for StructVisitor {
            type Value = PropertiesSearchResult;
            fn expecting(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                f.write_str("a PropertiesSearchResult struct")
            }
            fn visit_map<V: MapAccess<'de>>(self, map: V) -> Result<Self::Value, V::Error> {
                PropertiesSearchResult::internal_deserialize(map)
            }
        }
        deserializer.deserialize_struct("PropertiesSearchResult", PROPERTIES_SEARCH_RESULT_FIELDS, StructVisitor)
    }
}

impl ::serde::ser::Serialize for PropertiesSearchResult {
    fn serialize<S: ::serde::ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        // struct serializer
        use serde::ser::SerializeStruct;
        let mut s = serializer.serialize_struct("PropertiesSearchResult", 2)?;
        self.internal_serialize::<S>(&mut s)?;
        s.end()
    }
}

/// Raw key/value data to be associated with a Dropbox file. Property fields are added to Dropbox
/// files as a [`PropertyGroup`](PropertyGroup).
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive] // structs may have more fields added in the future.
pub struct PropertyField {
    /// Key of the property field associated with a file and template. Keys can be up to 256 bytes.
    pub name: String,
    /// Value of the property field associated with a file and template. Values can be up to 1024
    /// bytes.
    pub value: String,
}

impl PropertyField {
    pub fn new(name: String, value: String) -> Self {
        PropertyField {
            name,
            value,
        }
    }
}

const PROPERTY_FIELD_FIELDS: &[&str] = &["name",
                                         "value"];
impl PropertyField {
    pub(crate) fn internal_deserialize<'de, V: ::serde::de::MapAccess<'de>>(
        map: V,
    ) -> Result<PropertyField, V::Error> {
        Self::internal_deserialize_opt(map, false).map(Option::unwrap)
    }

    pub(crate) fn internal_deserialize_opt<'de, V: ::serde::de::MapAccess<'de>>(
        mut map: V,
        optional: bool,
    ) -> Result<Option<PropertyField>, V::Error> {
        let mut field_name = None;
        let mut field_value = None;
        let mut nothing = true;
        while let Some(key) = map.next_key::<&str>()? {
            nothing = false;
            match key {
                "name" => {
                    if field_name.is_some() {
                        return Err(::serde::de::Error::duplicate_field("name"));
                    }
                    field_name = Some(map.next_value()?);
                }
                "value" => {
                    if field_value.is_some() {
                        return Err(::serde::de::Error::duplicate_field("value"));
                    }
                    field_value = Some(map.next_value()?);
                }
                _ => {
                    // unknown field allowed and ignored
                    map.next_value::<::serde_json::Value>()?;
                }
            }
        }
        if optional && nothing {
            return Ok(None);
        }
        let result = PropertyField {
            name: field_name.ok_or_else(|| ::serde::de::Error::missing_field("name"))?,
            value: field_value.ok_or_else(|| ::serde::de::Error::missing_field("value"))?,
        };
        Ok(Some(result))
    }

    pub(crate) fn internal_serialize<S: ::serde::ser::Serializer>(
        &self,
        s: &mut S::SerializeStruct,
    ) -> Result<(), S::Error> {
        use serde::ser::SerializeStruct;
        s.serialize_field("name", &self.name)?;
        s.serialize_field("value", &self.value)?;
        Ok(())
    }
}

impl<'de> ::serde::de::Deserialize<'de> for PropertyField {
    fn deserialize<D: ::serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        // struct deserializer
        use serde::de::{MapAccess, Visitor};
        struct StructVisitor;
        impl<'de> Visitor<'de> for StructVisitor {
            type Value = PropertyField;
            fn expecting(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                f.write_str("a PropertyField struct")
            }
            fn visit_map<V: MapAccess<'de>>(self, map: V) -> Result<Self::Value, V::Error> {
                PropertyField::internal_deserialize(map)
            }
        }
        deserializer.deserialize_struct("PropertyField", PROPERTY_FIELD_FIELDS, StructVisitor)
    }
}

impl ::serde::ser::Serialize for PropertyField {
    fn serialize<S: ::serde::ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        // struct serializer
        use serde::ser::SerializeStruct;
        let mut s = serializer.serialize_struct("PropertyField", 2)?;
        self.internal_serialize::<S>(&mut s)?;
        s.end()
    }
}

/// Defines how a single property field may be structured. Used exclusively by
/// [`PropertyGroupTemplate`](PropertyGroupTemplate).
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive] // structs may have more fields added in the future.
pub struct PropertyFieldTemplate {
    /// Key of the property field being described. Property field keys can be up to 256 bytes.
    pub name: String,
    /// Description of the property field. Property field descriptions can be up to 1024 bytes.
    pub description: String,
    /// Data type of the value of this property field. This type will be enforced upon property
    /// creation and modifications.
    pub type_field: PropertyType,
}

impl PropertyFieldTemplate {
    pub fn new(name: String, description: String, type_field: PropertyType) -> Self {
        PropertyFieldTemplate {
            name,
            description,
            type_field,
        }
    }
}

const PROPERTY_FIELD_TEMPLATE_FIELDS: &[&str] = &["name",
                                                  "description",
                                                  "type"];
impl PropertyFieldTemplate {
    pub(crate) fn internal_deserialize<'de, V: ::serde::de::MapAccess<'de>>(
        map: V,
    ) -> Result<PropertyFieldTemplate, V::Error> {
        Self::internal_deserialize_opt(map, false).map(Option::unwrap)
    }

    pub(crate) fn internal_deserialize_opt<'de, V: ::serde::de::MapAccess<'de>>(
        mut map: V,
        optional: bool,
    ) -> Result<Option<PropertyFieldTemplate>, V::Error> {
        let mut field_name = None;
        let mut field_description = None;
        let mut field_type_field = None;
        let mut nothing = true;
        while let Some(key) = map.next_key::<&str>()? {
            nothing = false;
            match key {
                "name" => {
                    if field_name.is_some() {
                        return Err(::serde::de::Error::duplicate_field("name"));
                    }
                    field_name = Some(map.next_value()?);
                }
                "description" => {
                    if field_description.is_some() {
                        return Err(::serde::de::Error::duplicate_field("description"));
                    }
                    field_description = Some(map.next_value()?);
                }
                "type" => {
                    if field_type_field.is_some() {
                        return Err(::serde::de::Error::duplicate_field("type"));
                    }
                    field_type_field = Some(map.next_value()?);
                }
                _ => {
                    // unknown field allowed and ignored
                    map.next_value::<::serde_json::Value>()?;
                }
            }
        }
        if optional && nothing {
            return Ok(None);
        }
        let result = PropertyFieldTemplate {
            name: field_name.ok_or_else(|| ::serde::de::Error::missing_field("name"))?,
            description: field_description.ok_or_else(|| ::serde::de::Error::missing_field("description"))?,
            type_field: field_type_field.ok_or_else(|| ::serde::de::Error::missing_field("type"))?,
        };
        Ok(Some(result))
    }

    pub(crate) fn internal_serialize<S: ::serde::ser::Serializer>(
        &self,
        s: &mut S::SerializeStruct,
    ) -> Result<(), S::Error> {
        use serde::ser::SerializeStruct;
        s.serialize_field("name", &self.name)?;
        s.serialize_field("description", &self.description)?;
        s.serialize_field("type", &self.type_field)?;
        Ok(())
    }
}

impl<'de> ::serde::de::Deserialize<'de> for PropertyFieldTemplate {
    fn deserialize<D: ::serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        // struct deserializer
        use serde::de::{MapAccess, Visitor};
        struct StructVisitor;
        impl<'de> Visitor<'de> for StructVisitor {
            type Value = PropertyFieldTemplate;
            fn expecting(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                f.write_str("a PropertyFieldTemplate struct")
            }
            fn visit_map<V: MapAccess<'de>>(self, map: V) -> Result<Self::Value, V::Error> {
                PropertyFieldTemplate::internal_deserialize(map)
            }
        }
        deserializer.deserialize_struct("PropertyFieldTemplate", PROPERTY_FIELD_TEMPLATE_FIELDS, StructVisitor)
    }
}

impl ::serde::ser::Serialize for PropertyFieldTemplate {
    fn serialize<S: ::serde::ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        // struct serializer
        use serde::ser::SerializeStruct;
        let mut s = serializer.serialize_struct("PropertyFieldTemplate", 3)?;
        self.internal_serialize::<S>(&mut s)?;
        s.end()
    }
}

/// A subset of the property fields described by the corresponding
/// [`PropertyGroupTemplate`](PropertyGroupTemplate). Properties are always added to a Dropbox file
/// as a [`PropertyGroup`](PropertyGroup). The possible key names and value types in this group are
/// defined by the corresponding [`PropertyGroupTemplate`](PropertyGroupTemplate).
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive] // structs may have more fields added in the future.
pub struct PropertyGroup {
    /// A unique identifier for the associated template.
    pub template_id: TemplateId,
    /// The actual properties associated with the template. There can be up to 32 property types per
    /// template.
    pub fields: Vec<PropertyField>,
}

impl PropertyGroup {
    pub fn new(template_id: TemplateId, fields: Vec<PropertyField>) -> Self {
        PropertyGroup {
            template_id,
            fields,
        }
    }
}

const PROPERTY_GROUP_FIELDS: &[&str] = &["template_id",
                                         "fields"];
impl PropertyGroup {
    pub(crate) fn internal_deserialize<'de, V: ::serde::de::MapAccess<'de>>(
        map: V,
    ) -> Result<PropertyGroup, V::Error> {
        Self::internal_deserialize_opt(map, false).map(Option::unwrap)
    }

    pub(crate) fn internal_deserialize_opt<'de, V: ::serde::de::MapAccess<'de>>(
        mut map: V,
        optional: bool,
    ) -> Result<Option<PropertyGroup>, V::Error> {
        let mut field_template_id = None;
        let mut field_fields = None;
        let mut nothing = true;
        while let Some(key) = map.next_key::<&str>()? {
            nothing = false;
            match key {
                "template_id" => {
                    if field_template_id.is_some() {
                        return Err(::serde::de::Error::duplicate_field("template_id"));
                    }
                    field_template_id = Some(map.next_value()?);
                }
                "fields" => {
                    if field_fields.is_some() {
                        return Err(::serde::de::Error::duplicate_field("fields"));
                    }
                    field_fields = Some(map.next_value()?);
                }
                _ => {
                    // unknown field allowed and ignored
                    map.next_value::<::serde_json::Value>()?;
                }
            }
        }
        if optional && nothing {
            return Ok(None);
        }
        let result = PropertyGroup {
            template_id: field_template_id.ok_or_else(|| ::serde::de::Error::missing_field("template_id"))?,
            fields: field_fields.ok_or_else(|| ::serde::de::Error::missing_field("fields"))?,
        };
        Ok(Some(result))
    }

    pub(crate) fn internal_serialize<S: ::serde::ser::Serializer>(
        &self,
        s: &mut S::SerializeStruct,
    ) -> Result<(), S::Error> {
        use serde::ser::SerializeStruct;
        s.serialize_field("template_id", &self.template_id)?;
        s.serialize_field("fields", &self.fields)?;
        Ok(())
    }
}

impl<'de> ::serde::de::Deserialize<'de> for PropertyGroup {
    fn deserialize<D: ::serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        // struct deserializer
        use serde::de::{MapAccess, Visitor};
        struct StructVisitor;
        impl<'de> Visitor<'de> for StructVisitor {
            type Value = PropertyGroup;
            fn expecting(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                f.write_str("a PropertyGroup struct")
            }
            fn visit_map<V: MapAccess<'de>>(self, map: V) -> Result<Self::Value, V::Error> {
                PropertyGroup::internal_deserialize(map)
            }
        }
        deserializer.deserialize_struct("PropertyGroup", PROPERTY_GROUP_FIELDS, StructVisitor)
    }
}

impl ::serde::ser::Serialize for PropertyGroup {
    fn serialize<S: ::serde::ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        // struct serializer
        use serde::ser::SerializeStruct;
        let mut s = serializer.serialize_struct("PropertyGroup", 2)?;
        self.internal_serialize::<S>(&mut s)?;
        s.end()
    }
}

/// Defines how a property group may be structured.
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive] // structs may have more fields added in the future.
pub struct PropertyGroupTemplate {
    /// Display name for the template. Template names can be up to 256 bytes.
    pub name: String,
    /// Description for the template. Template descriptions can be up to 1024 bytes.
    pub description: String,
    /// Definitions of the property fields associated with this template. There can be up to 32
    /// properties in a single template.
    pub fields: Vec<PropertyFieldTemplate>,
}

impl PropertyGroupTemplate {
    pub fn new(name: String, description: String, fields: Vec<PropertyFieldTemplate>) -> Self {
        PropertyGroupTemplate {
            name,
            description,
            fields,
        }
    }
}

const PROPERTY_GROUP_TEMPLATE_FIELDS: &[&str] = &["name",
                                                  "description",
                                                  "fields"];
impl PropertyGroupTemplate {
    pub(crate) fn internal_deserialize<'de, V: ::serde::de::MapAccess<'de>>(
        map: V,
    ) -> Result<PropertyGroupTemplate, V::Error> {
        Self::internal_deserialize_opt(map, false).map(Option::unwrap)
    }

    pub(crate) fn internal_deserialize_opt<'de, V: ::serde::de::MapAccess<'de>>(
        mut map: V,
        optional: bool,
    ) -> Result<Option<PropertyGroupTemplate>, V::Error> {
        let mut field_name = None;
        let mut field_description = None;
        let mut field_fields = None;
        let mut nothing = true;
        while let Some(key) = map.next_key::<&str>()? {
            nothing = false;
            match key {
                "name" => {
                    if field_name.is_some() {
                        return Err(::serde::de::Error::duplicate_field("name"));
                    }
                    field_name = Some(map.next_value()?);
                }
                "description" => {
                    if field_description.is_some() {
                        return Err(::serde::de::Error::duplicate_field("description"));
                    }
                    field_description = Some(map.next_value()?);
                }
                "fields" => {
                    if field_fields.is_some() {
                        return Err(::serde::de::Error::duplicate_field("fields"));
                    }
                    field_fields = Some(map.next_value()?);
                }
                _ => {
                    // unknown field allowed and ignored
                    map.next_value::<::serde_json::Value>()?;
                }
            }
        }
        if optional && nothing {
            return Ok(None);
        }
        let result = PropertyGroupTemplate {
            name: field_name.ok_or_else(|| ::serde::de::Error::missing_field("name"))?,
            description: field_description.ok_or_else(|| ::serde::de::Error::missing_field("description"))?,
            fields: field_fields.ok_or_else(|| ::serde::de::Error::missing_field("fields"))?,
        };
        Ok(Some(result))
    }

    pub(crate) fn internal_serialize<S: ::serde::ser::Serializer>(
        &self,
        s: &mut S::SerializeStruct,
    ) -> Result<(), S::Error> {
        use serde::ser::SerializeStruct;
        s.serialize_field("name", &self.name)?;
        s.serialize_field("description", &self.description)?;
        s.serialize_field("fields", &self.fields)?;
        Ok(())
    }
}

impl<'de> ::serde::de::Deserialize<'de> for PropertyGroupTemplate {
    fn deserialize<D: ::serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        // struct deserializer
        use serde::de::{MapAccess, Visitor};
        struct StructVisitor;
        impl<'de> Visitor<'de> for StructVisitor {
            type Value = PropertyGroupTemplate;
            fn expecting(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                f.write_str("a PropertyGroupTemplate struct")
            }
            fn visit_map<V: MapAccess<'de>>(self, map: V) -> Result<Self::Value, V::Error> {
                PropertyGroupTemplate::internal_deserialize(map)
            }
        }
        deserializer.deserialize_struct("PropertyGroupTemplate", PROPERTY_GROUP_TEMPLATE_FIELDS, StructVisitor)
    }
}

impl ::serde::ser::Serialize for PropertyGroupTemplate {
    fn serialize<S: ::serde::ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        // struct serializer
        use serde::ser::SerializeStruct;
        let mut s = serializer.serialize_struct("PropertyGroupTemplate", 3)?;
        self.internal_serialize::<S>(&mut s)?;
        s.end()
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive] // structs may have more fields added in the future.
pub struct PropertyGroupUpdate {
    /// A unique identifier for a property template.
    pub template_id: TemplateId,
    /// Property fields to update. If the property field already exists, it is updated. If the
    /// property field doesn't exist, the property group is added.
    pub add_or_update_fields: Option<Vec<PropertyField>>,
    /// Property fields to remove (by name), provided they exist.
    pub remove_fields: Option<Vec<String>>,
}

impl PropertyGroupUpdate {
    pub fn new(template_id: TemplateId) -> Self {
        PropertyGroupUpdate {
            template_id,
            add_or_update_fields: None,
            remove_fields: None,
        }
    }

    pub fn with_add_or_update_fields(mut self, value: Vec<PropertyField>) -> Self {
        self.add_or_update_fields = Some(value);
        self
    }

    pub fn with_remove_fields(mut self, value: Vec<String>) -> Self {
        self.remove_fields = Some(value);
        self
    }
}

const PROPERTY_GROUP_UPDATE_FIELDS: &[&str] = &["template_id",
                                                "add_or_update_fields",
                                                "remove_fields"];
impl PropertyGroupUpdate {
    pub(crate) fn internal_deserialize<'de, V: ::serde::de::MapAccess<'de>>(
        map: V,
    ) -> Result<PropertyGroupUpdate, V::Error> {
        Self::internal_deserialize_opt(map, false).map(Option::unwrap)
    }

    pub(crate) fn internal_deserialize_opt<'de, V: ::serde::de::MapAccess<'de>>(
        mut map: V,
        optional: bool,
    ) -> Result<Option<PropertyGroupUpdate>, V::Error> {
        let mut field_template_id = None;
        let mut field_add_or_update_fields = None;
        let mut field_remove_fields = None;
        let mut nothing = true;
        while let Some(key) = map.next_key::<&str>()? {
            nothing = false;
            match key {
                "template_id" => {
                    if field_template_id.is_some() {
                        return Err(::serde::de::Error::duplicate_field("template_id"));
                    }
                    field_template_id = Some(map.next_value()?);
                }
                "add_or_update_fields" => {
                    if field_add_or_update_fields.is_some() {
                        return Err(::serde::de::Error::duplicate_field("add_or_update_fields"));
                    }
                    field_add_or_update_fields = Some(map.next_value()?);
                }
                "remove_fields" => {
                    if field_remove_fields.is_some() {
                        return Err(::serde::de::Error::duplicate_field("remove_fields"));
                    }
                    field_remove_fields = Some(map.next_value()?);
                }
                _ => {
                    // unknown field allowed and ignored
                    map.next_value::<::serde_json::Value>()?;
                }
            }
        }
        if optional && nothing {
            return Ok(None);
        }
        let result = PropertyGroupUpdate {
            template_id: field_template_id.ok_or_else(|| ::serde::de::Error::missing_field("template_id"))?,
            add_or_update_fields: field_add_or_update_fields,
            remove_fields: field_remove_fields,
        };
        Ok(Some(result))
    }

    pub(crate) fn internal_serialize<S: ::serde::ser::Serializer>(
        &self,
        s: &mut S::SerializeStruct,
    ) -> Result<(), S::Error> {
        use serde::ser::SerializeStruct;
        s.serialize_field("template_id", &self.template_id)?;
        if let Some(val) = &self.add_or_update_fields {
            s.serialize_field("add_or_update_fields", val)?;
        }
        if let Some(val) = &self.remove_fields {
            s.serialize_field("remove_fields", val)?;
        }
        Ok(())
    }
}

impl<'de> ::serde::de::Deserialize<'de> for PropertyGroupUpdate {
    fn deserialize<D: ::serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        // struct deserializer
        use serde::de::{MapAccess, Visitor};
        struct StructVisitor;
        impl<'de> Visitor<'de> for StructVisitor {
            type Value = PropertyGroupUpdate;
            fn expecting(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                f.write_str("a PropertyGroupUpdate struct")
            }
            fn visit_map<V: MapAccess<'de>>(self, map: V) -> Result<Self::Value, V::Error> {
                PropertyGroupUpdate::internal_deserialize(map)
            }
        }
        deserializer.deserialize_struct("PropertyGroupUpdate", PROPERTY_GROUP_UPDATE_FIELDS, StructVisitor)
    }
}

impl ::serde::ser::Serialize for PropertyGroupUpdate {
    fn serialize<S: ::serde::ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        // struct serializer
        use serde::ser::SerializeStruct;
        let mut s = serializer.serialize_struct("PropertyGroupUpdate", 3)?;
        self.internal_serialize::<S>(&mut s)?;
        s.end()
    }
}

/// Data type of the given property field added.
#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive] // variants may be added in the future
pub enum PropertyType {
    /// The associated property field will be of type string. Unicode is supported.
    String,
    /// Catch-all used for unrecognized values returned from the server. Encountering this value
    /// typically indicates that this SDK version is out of date.
    Other,
}

impl<'de> ::serde::de::Deserialize<'de> for PropertyType {
    fn deserialize<D: ::serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        // union deserializer
        use serde::de::{self, MapAccess, Visitor};
        struct EnumVisitor;
        impl<'de> Visitor<'de> for EnumVisitor {
            type Value = PropertyType;
            fn expecting(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                f.write_str("a PropertyType structure")
            }
            fn visit_map<V: MapAccess<'de>>(self, mut map: V) -> Result<Self::Value, V::Error> {
                let tag: &str = match map.next_key()? {
                    Some(".tag") => map.next_value()?,
                    _ => return Err(de::Error::missing_field(".tag"))
                };
                let value = match tag {
                    "string" => PropertyType::String,
                    _ => PropertyType::Other,
                };
                crate::eat_json_fields(&mut map)?;
                Ok(value)
            }
        }
        const VARIANTS: &[&str] = &["string",
                                    "other"];
        deserializer.deserialize_struct("PropertyType", VARIANTS, EnumVisitor)
    }
}

impl ::serde::ser::Serialize for PropertyType {
    fn serialize<S: ::serde::ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        // union serializer
        use serde::ser::SerializeStruct;
        match *self {
            PropertyType::String => {
                // unit
                let mut s = serializer.serialize_struct("PropertyType", 1)?;
                s.serialize_field(".tag", "string")?;
                s.end()
            }
            PropertyType::Other => Err(::serde::ser::Error::custom("cannot serialize 'Other' variant"))
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive] // structs may have more fields added in the future.
pub struct RemovePropertiesArg {
    /// A unique identifier for the file or folder.
    pub path: PathOrId,
    /// A list of identifiers for a template created by
    /// [`templates_add_for_user()`](templates_add_for_user) or
    /// [`templates_add_for_team()`](templates_add_for_team).
    pub property_template_ids: Vec<TemplateId>,
}

impl RemovePropertiesArg {
    pub fn new(path: PathOrId, property_template_ids: Vec<TemplateId>) -> Self {
        RemovePropertiesArg {
            path,
            property_template_ids,
        }
    }
}

const REMOVE_PROPERTIES_ARG_FIELDS: &[&str] = &["path",
                                                "property_template_ids"];
impl RemovePropertiesArg {
    pub(crate) fn internal_deserialize<'de, V: ::serde::de::MapAccess<'de>>(
        map: V,
    ) -> Result<RemovePropertiesArg, V::Error> {
        Self::internal_deserialize_opt(map, false).map(Option::unwrap)
    }

    pub(crate) fn internal_deserialize_opt<'de, V: ::serde::de::MapAccess<'de>>(
        mut map: V,
        optional: bool,
    ) -> Result<Option<RemovePropertiesArg>, V::Error> {
        let mut field_path = None;
        let mut field_property_template_ids = None;
        let mut nothing = true;
        while let Some(key) = map.next_key::<&str>()? {
            nothing = false;
            match key {
                "path" => {
                    if field_path.is_some() {
                        return Err(::serde::de::Error::duplicate_field("path"));
                    }
                    field_path = Some(map.next_value()?);
                }
                "property_template_ids" => {
                    if field_property_template_ids.is_some() {
                        return Err(::serde::de::Error::duplicate_field("property_template_ids"));
                    }
                    field_property_template_ids = Some(map.next_value()?);
                }
                _ => {
                    // unknown field allowed and ignored
                    map.next_value::<::serde_json::Value>()?;
                }
            }
        }
        if optional && nothing {
            return Ok(None);
        }
        let result = RemovePropertiesArg {
            path: field_path.ok_or_else(|| ::serde::de::Error::missing_field("path"))?,
            property_template_ids: field_property_template_ids.ok_or_else(|| ::serde::de::Error::missing_field("property_template_ids"))?,
        };
        Ok(Some(result))
    }

    pub(crate) fn internal_serialize<S: ::serde::ser::Serializer>(
        &self,
        s: &mut S::SerializeStruct,
    ) -> Result<(), S::Error> {
        use serde::ser::SerializeStruct;
        s.serialize_field("path", &self.path)?;
        s.serialize_field("property_template_ids", &self.property_template_ids)?;
        Ok(())
    }
}

impl<'de> ::serde::de::Deserialize<'de> for RemovePropertiesArg {
    fn deserialize<D: ::serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        // struct deserializer
        use serde::de::{MapAccess, Visitor};
        struct StructVisitor;
        impl<'de> Visitor<'de> for StructVisitor {
            type Value = RemovePropertiesArg;
            fn expecting(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                f.write_str("a RemovePropertiesArg struct")
            }
            fn visit_map<V: MapAccess<'de>>(self, map: V) -> Result<Self::Value, V::Error> {
                RemovePropertiesArg::internal_deserialize(map)
            }
        }
        deserializer.deserialize_struct("RemovePropertiesArg", REMOVE_PROPERTIES_ARG_FIELDS, StructVisitor)
    }
}

impl ::serde::ser::Serialize for RemovePropertiesArg {
    fn serialize<S: ::serde::ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        // struct serializer
        use serde::ser::SerializeStruct;
        let mut s = serializer.serialize_struct("RemovePropertiesArg", 2)?;
        self.internal_serialize::<S>(&mut s)?;
        s.end()
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive] // variants may be added in the future
pub enum RemovePropertiesError {
    /// Template does not exist for the given identifier.
    TemplateNotFound(TemplateId),
    /// You do not have permission to modify this template.
    RestrictedContent,
    Path(LookupError),
    /// This folder cannot be tagged. Tagging folders is not supported for team-owned templates.
    UnsupportedFolder,
    PropertyGroupLookup(LookUpPropertiesError),
    /// Catch-all used for unrecognized values returned from the server. Encountering this value
    /// typically indicates that this SDK version is out of date.
    Other,
}

impl<'de> ::serde::de::Deserialize<'de> for RemovePropertiesError {
    fn deserialize<D: ::serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        // union deserializer
        use serde::de::{self, MapAccess, Visitor};
        struct EnumVisitor;
        impl<'de> Visitor<'de> for EnumVisitor {
            type Value = RemovePropertiesError;
            fn expecting(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                f.write_str("a RemovePropertiesError structure")
            }
            fn visit_map<V: MapAccess<'de>>(self, mut map: V) -> Result<Self::Value, V::Error> {
                let tag: &str = match map.next_key()? {
                    Some(".tag") => map.next_value()?,
                    _ => return Err(de::Error::missing_field(".tag"))
                };
                let value = match tag {
                    "template_not_found" => {
                        match map.next_key()? {
                            Some("template_not_found") => RemovePropertiesError::TemplateNotFound(map.next_value()?),
                            None => return Err(de::Error::missing_field("template_not_found")),
                            _ => return Err(de::Error::unknown_field(tag, VARIANTS))
                        }
                    }
                    "restricted_content" => RemovePropertiesError::RestrictedContent,
                    "path" => {
                        match map.next_key()? {
                            Some("path") => RemovePropertiesError::Path(map.next_value()?),
                            None => return Err(de::Error::missing_field("path")),
                            _ => return Err(de::Error::unknown_field(tag, VARIANTS))
                        }
                    }
                    "unsupported_folder" => RemovePropertiesError::UnsupportedFolder,
                    "property_group_lookup" => {
                        match map.next_key()? {
                            Some("property_group_lookup") => RemovePropertiesError::PropertyGroupLookup(map.next_value()?),
                            None => return Err(de::Error::missing_field("property_group_lookup")),
                            _ => return Err(de::Error::unknown_field(tag, VARIANTS))
                        }
                    }
                    _ => RemovePropertiesError::Other,
                };
                crate::eat_json_fields(&mut map)?;
                Ok(value)
            }
        }
        const VARIANTS: &[&str] = &["template_not_found",
                                    "restricted_content",
                                    "other",
                                    "path",
                                    "unsupported_folder",
                                    "property_group_lookup"];
        deserializer.deserialize_struct("RemovePropertiesError", VARIANTS, EnumVisitor)
    }
}

impl ::serde::ser::Serialize for RemovePropertiesError {
    fn serialize<S: ::serde::ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        // union serializer
        use serde::ser::SerializeStruct;
        match *self {
            RemovePropertiesError::TemplateNotFound(ref x) => {
                // primitive
                let mut s = serializer.serialize_struct("RemovePropertiesError", 2)?;
                s.serialize_field(".tag", "template_not_found")?;
                s.serialize_field("template_not_found", x)?;
                s.end()
            }
            RemovePropertiesError::RestrictedContent => {
                // unit
                let mut s = serializer.serialize_struct("RemovePropertiesError", 1)?;
                s.serialize_field(".tag", "restricted_content")?;
                s.end()
            }
            RemovePropertiesError::Path(ref x) => {
                // union or polymporphic struct
                let mut s = serializer.serialize_struct("RemovePropertiesError", 2)?;
                s.serialize_field(".tag", "path")?;
                s.serialize_field("path", x)?;
                s.end()
            }
            RemovePropertiesError::UnsupportedFolder => {
                // unit
                let mut s = serializer.serialize_struct("RemovePropertiesError", 1)?;
                s.serialize_field(".tag", "unsupported_folder")?;
                s.end()
            }
            RemovePropertiesError::PropertyGroupLookup(ref x) => {
                // union or polymporphic struct
                let mut s = serializer.serialize_struct("RemovePropertiesError", 2)?;
                s.serialize_field(".tag", "property_group_lookup")?;
                s.serialize_field("property_group_lookup", x)?;
                s.end()
            }
            RemovePropertiesError::Other => Err(::serde::ser::Error::custom("cannot serialize 'Other' variant"))
        }
    }
}

impl ::std::error::Error for RemovePropertiesError {
    fn source(&self) -> Option<&(dyn ::std::error::Error + 'static)> {
        match self {
            RemovePropertiesError::Path(inner) => Some(inner),
            RemovePropertiesError::PropertyGroupLookup(inner) => Some(inner),
            _ => None,
        }
    }
}

impl ::std::fmt::Display for RemovePropertiesError {
    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
        match self {
            RemovePropertiesError::TemplateNotFound(inner) => write!(f, "Template does not exist for the given identifier: {:?}", inner),
            RemovePropertiesError::RestrictedContent => f.write_str("You do not have permission to modify this template."),
            RemovePropertiesError::Path(inner) => write!(f, "{}", inner),
            RemovePropertiesError::UnsupportedFolder => f.write_str("This folder cannot be tagged. Tagging folders is not supported for team-owned templates."),
            RemovePropertiesError::PropertyGroupLookup(inner) => write!(f, "{}", inner),
            _ => write!(f, "{:?}", *self),
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive] // structs may have more fields added in the future.
pub struct RemoveTemplateArg {
    /// An identifier for a template created by [`templates_add_for_user()`](templates_add_for_user)
    /// or [`templates_add_for_team()`](templates_add_for_team).
    pub template_id: TemplateId,
}

impl RemoveTemplateArg {
    pub fn new(template_id: TemplateId) -> Self {
        RemoveTemplateArg {
            template_id,
        }
    }
}

const REMOVE_TEMPLATE_ARG_FIELDS: &[&str] = &["template_id"];
impl RemoveTemplateArg {
    pub(crate) fn internal_deserialize<'de, V: ::serde::de::MapAccess<'de>>(
        map: V,
    ) -> Result<RemoveTemplateArg, V::Error> {
        Self::internal_deserialize_opt(map, false).map(Option::unwrap)
    }

    pub(crate) fn internal_deserialize_opt<'de, V: ::serde::de::MapAccess<'de>>(
        mut map: V,
        optional: bool,
    ) -> Result<Option<RemoveTemplateArg>, V::Error> {
        let mut field_template_id = None;
        let mut nothing = true;
        while let Some(key) = map.next_key::<&str>()? {
            nothing = false;
            match key {
                "template_id" => {
                    if field_template_id.is_some() {
                        return Err(::serde::de::Error::duplicate_field("template_id"));
                    }
                    field_template_id = Some(map.next_value()?);
                }
                _ => {
                    // unknown field allowed and ignored
                    map.next_value::<::serde_json::Value>()?;
                }
            }
        }
        if optional && nothing {
            return Ok(None);
        }
        let result = RemoveTemplateArg {
            template_id: field_template_id.ok_or_else(|| ::serde::de::Error::missing_field("template_id"))?,
        };
        Ok(Some(result))
    }

    pub(crate) fn internal_serialize<S: ::serde::ser::Serializer>(
        &self,
        s: &mut S::SerializeStruct,
    ) -> Result<(), S::Error> {
        use serde::ser::SerializeStruct;
        s.serialize_field("template_id", &self.template_id)?;
        Ok(())
    }
}

impl<'de> ::serde::de::Deserialize<'de> for RemoveTemplateArg {
    fn deserialize<D: ::serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        // struct deserializer
        use serde::de::{MapAccess, Visitor};
        struct StructVisitor;
        impl<'de> Visitor<'de> for StructVisitor {
            type Value = RemoveTemplateArg;
            fn expecting(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                f.write_str("a RemoveTemplateArg struct")
            }
            fn visit_map<V: MapAccess<'de>>(self, map: V) -> Result<Self::Value, V::Error> {
                RemoveTemplateArg::internal_deserialize(map)
            }
        }
        deserializer.deserialize_struct("RemoveTemplateArg", REMOVE_TEMPLATE_ARG_FIELDS, StructVisitor)
    }
}

impl ::serde::ser::Serialize for RemoveTemplateArg {
    fn serialize<S: ::serde::ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        // struct serializer
        use serde::ser::SerializeStruct;
        let mut s = serializer.serialize_struct("RemoveTemplateArg", 1)?;
        self.internal_serialize::<S>(&mut s)?;
        s.end()
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive] // variants may be added in the future
pub enum TemplateError {
    /// Template does not exist for the given identifier.
    TemplateNotFound(TemplateId),
    /// You do not have permission to modify this template.
    RestrictedContent,
    /// Catch-all used for unrecognized values returned from the server. Encountering this value
    /// typically indicates that this SDK version is out of date.
    Other,
}

impl<'de> ::serde::de::Deserialize<'de> for TemplateError {
    fn deserialize<D: ::serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        // union deserializer
        use serde::de::{self, MapAccess, Visitor};
        struct EnumVisitor;
        impl<'de> Visitor<'de> for EnumVisitor {
            type Value = TemplateError;
            fn expecting(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                f.write_str("a TemplateError structure")
            }
            fn visit_map<V: MapAccess<'de>>(self, mut map: V) -> Result<Self::Value, V::Error> {
                let tag: &str = match map.next_key()? {
                    Some(".tag") => map.next_value()?,
                    _ => return Err(de::Error::missing_field(".tag"))
                };
                let value = match tag {
                    "template_not_found" => {
                        match map.next_key()? {
                            Some("template_not_found") => TemplateError::TemplateNotFound(map.next_value()?),
                            None => return Err(de::Error::missing_field("template_not_found")),
                            _ => return Err(de::Error::unknown_field(tag, VARIANTS))
                        }
                    }
                    "restricted_content" => TemplateError::RestrictedContent,
                    _ => TemplateError::Other,
                };
                crate::eat_json_fields(&mut map)?;
                Ok(value)
            }
        }
        const VARIANTS: &[&str] = &["template_not_found",
                                    "restricted_content",
                                    "other"];
        deserializer.deserialize_struct("TemplateError", VARIANTS, EnumVisitor)
    }
}

impl ::serde::ser::Serialize for TemplateError {
    fn serialize<S: ::serde::ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        // union serializer
        use serde::ser::SerializeStruct;
        match *self {
            TemplateError::TemplateNotFound(ref x) => {
                // primitive
                let mut s = serializer.serialize_struct("TemplateError", 2)?;
                s.serialize_field(".tag", "template_not_found")?;
                s.serialize_field("template_not_found", x)?;
                s.end()
            }
            TemplateError::RestrictedContent => {
                // unit
                let mut s = serializer.serialize_struct("TemplateError", 1)?;
                s.serialize_field(".tag", "restricted_content")?;
                s.end()
            }
            TemplateError::Other => Err(::serde::ser::Error::custom("cannot serialize 'Other' variant"))
        }
    }
}

impl ::std::error::Error for TemplateError {
}

impl ::std::fmt::Display for TemplateError {
    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
        match self {
            TemplateError::TemplateNotFound(inner) => write!(f, "Template does not exist for the given identifier: {:?}", inner),
            TemplateError::RestrictedContent => f.write_str("You do not have permission to modify this template."),
            _ => write!(f, "{:?}", *self),
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive] // variants may be added in the future
pub enum TemplateFilter {
    /// Only templates with an ID in the supplied list will be returned (a subset of templates will
    /// be returned).
    FilterSome(Vec<TemplateId>),
    /// No templates will be filtered from the result (all templates will be returned).
    FilterNone,
    /// Catch-all used for unrecognized values returned from the server. Encountering this value
    /// typically indicates that this SDK version is out of date.
    Other,
}

impl<'de> ::serde::de::Deserialize<'de> for TemplateFilter {
    fn deserialize<D: ::serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        // union deserializer
        use serde::de::{self, MapAccess, Visitor};
        struct EnumVisitor;
        impl<'de> Visitor<'de> for EnumVisitor {
            type Value = TemplateFilter;
            fn expecting(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                f.write_str("a TemplateFilter structure")
            }
            fn visit_map<V: MapAccess<'de>>(self, mut map: V) -> Result<Self::Value, V::Error> {
                let tag: &str = match map.next_key()? {
                    Some(".tag") => map.next_value()?,
                    _ => return Err(de::Error::missing_field(".tag"))
                };
                let value = match tag {
                    "filter_some" => {
                        match map.next_key()? {
                            Some("filter_some") => TemplateFilter::FilterSome(map.next_value()?),
                            None => return Err(de::Error::missing_field("filter_some")),
                            _ => return Err(de::Error::unknown_field(tag, VARIANTS))
                        }
                    }
                    "filter_none" => TemplateFilter::FilterNone,
                    _ => TemplateFilter::Other,
                };
                crate::eat_json_fields(&mut map)?;
                Ok(value)
            }
        }
        const VARIANTS: &[&str] = &["filter_some",
                                    "other",
                                    "filter_none"];
        deserializer.deserialize_struct("TemplateFilter", VARIANTS, EnumVisitor)
    }
}

impl ::serde::ser::Serialize for TemplateFilter {
    fn serialize<S: ::serde::ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        // union serializer
        use serde::ser::SerializeStruct;
        match *self {
            TemplateFilter::FilterSome(ref x) => {
                // primitive
                let mut s = serializer.serialize_struct("TemplateFilter", 2)?;
                s.serialize_field(".tag", "filter_some")?;
                s.serialize_field("filter_some", x)?;
                s.end()
            }
            TemplateFilter::FilterNone => {
                // unit
                let mut s = serializer.serialize_struct("TemplateFilter", 1)?;
                s.serialize_field(".tag", "filter_none")?;
                s.end()
            }
            TemplateFilter::Other => Err(::serde::ser::Error::custom("cannot serialize 'Other' variant"))
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive] // variants may be added in the future
pub enum TemplateFilterBase {
    /// Only templates with an ID in the supplied list will be returned (a subset of templates will
    /// be returned).
    FilterSome(Vec<TemplateId>),
    /// Catch-all used for unrecognized values returned from the server. Encountering this value
    /// typically indicates that this SDK version is out of date.
    Other,
}

impl<'de> ::serde::de::Deserialize<'de> for TemplateFilterBase {
    fn deserialize<D: ::serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        // union deserializer
        use serde::de::{self, MapAccess, Visitor};
        struct EnumVisitor;
        impl<'de> Visitor<'de> for EnumVisitor {
            type Value = TemplateFilterBase;
            fn expecting(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                f.write_str("a TemplateFilterBase structure")
            }
            fn visit_map<V: MapAccess<'de>>(self, mut map: V) -> Result<Self::Value, V::Error> {
                let tag: &str = match map.next_key()? {
                    Some(".tag") => map.next_value()?,
                    _ => return Err(de::Error::missing_field(".tag"))
                };
                let value = match tag {
                    "filter_some" => {
                        match map.next_key()? {
                            Some("filter_some") => TemplateFilterBase::FilterSome(map.next_value()?),
                            None => return Err(de::Error::missing_field("filter_some")),
                            _ => return Err(de::Error::unknown_field(tag, VARIANTS))
                        }
                    }
                    _ => TemplateFilterBase::Other,
                };
                crate::eat_json_fields(&mut map)?;
                Ok(value)
            }
        }
        const VARIANTS: &[&str] = &["filter_some",
                                    "other"];
        deserializer.deserialize_struct("TemplateFilterBase", VARIANTS, EnumVisitor)
    }
}

impl ::serde::ser::Serialize for TemplateFilterBase {
    fn serialize<S: ::serde::ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        // union serializer
        use serde::ser::SerializeStruct;
        match *self {
            TemplateFilterBase::FilterSome(ref x) => {
                // primitive
                let mut s = serializer.serialize_struct("TemplateFilterBase", 2)?;
                s.serialize_field(".tag", "filter_some")?;
                s.serialize_field("filter_some", x)?;
                s.end()
            }
            TemplateFilterBase::Other => Err(::serde::ser::Error::custom("cannot serialize 'Other' variant"))
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive] // variants may be added in the future
pub enum TemplateOwnerType {
    /// Template will be associated with a user.
    User,
    /// Template will be associated with a team.
    Team,
    /// Catch-all used for unrecognized values returned from the server. Encountering this value
    /// typically indicates that this SDK version is out of date.
    Other,
}

impl<'de> ::serde::de::Deserialize<'de> for TemplateOwnerType {
    fn deserialize<D: ::serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        // union deserializer
        use serde::de::{self, MapAccess, Visitor};
        struct EnumVisitor;
        impl<'de> Visitor<'de> for EnumVisitor {
            type Value = TemplateOwnerType;
            fn expecting(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                f.write_str("a TemplateOwnerType structure")
            }
            fn visit_map<V: MapAccess<'de>>(self, mut map: V) -> Result<Self::Value, V::Error> {
                let tag: &str = match map.next_key()? {
                    Some(".tag") => map.next_value()?,
                    _ => return Err(de::Error::missing_field(".tag"))
                };
                let value = match tag {
                    "user" => TemplateOwnerType::User,
                    "team" => TemplateOwnerType::Team,
                    _ => TemplateOwnerType::Other,
                };
                crate::eat_json_fields(&mut map)?;
                Ok(value)
            }
        }
        const VARIANTS: &[&str] = &["user",
                                    "team",
                                    "other"];
        deserializer.deserialize_struct("TemplateOwnerType", VARIANTS, EnumVisitor)
    }
}

impl ::serde::ser::Serialize for TemplateOwnerType {
    fn serialize<S: ::serde::ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        // union serializer
        use serde::ser::SerializeStruct;
        match *self {
            TemplateOwnerType::User => {
                // unit
                let mut s = serializer.serialize_struct("TemplateOwnerType", 1)?;
                s.serialize_field(".tag", "user")?;
                s.end()
            }
            TemplateOwnerType::Team => {
                // unit
                let mut s = serializer.serialize_struct("TemplateOwnerType", 1)?;
                s.serialize_field(".tag", "team")?;
                s.end()
            }
            TemplateOwnerType::Other => Err(::serde::ser::Error::custom("cannot serialize 'Other' variant"))
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive] // structs may have more fields added in the future.
pub struct UpdatePropertiesArg {
    /// A unique identifier for the file or folder.
    pub path: PathOrId,
    /// The property groups "delta" updates to apply.
    pub update_property_groups: Vec<PropertyGroupUpdate>,
}

impl UpdatePropertiesArg {
    pub fn new(path: PathOrId, update_property_groups: Vec<PropertyGroupUpdate>) -> Self {
        UpdatePropertiesArg {
            path,
            update_property_groups,
        }
    }
}

const UPDATE_PROPERTIES_ARG_FIELDS: &[&str] = &["path",
                                                "update_property_groups"];
impl UpdatePropertiesArg {
    pub(crate) fn internal_deserialize<'de, V: ::serde::de::MapAccess<'de>>(
        map: V,
    ) -> Result<UpdatePropertiesArg, V::Error> {
        Self::internal_deserialize_opt(map, false).map(Option::unwrap)
    }

    pub(crate) fn internal_deserialize_opt<'de, V: ::serde::de::MapAccess<'de>>(
        mut map: V,
        optional: bool,
    ) -> Result<Option<UpdatePropertiesArg>, V::Error> {
        let mut field_path = None;
        let mut field_update_property_groups = None;
        let mut nothing = true;
        while let Some(key) = map.next_key::<&str>()? {
            nothing = false;
            match key {
                "path" => {
                    if field_path.is_some() {
                        return Err(::serde::de::Error::duplicate_field("path"));
                    }
                    field_path = Some(map.next_value()?);
                }
                "update_property_groups" => {
                    if field_update_property_groups.is_some() {
                        return Err(::serde::de::Error::duplicate_field("update_property_groups"));
                    }
                    field_update_property_groups = Some(map.next_value()?);
                }
                _ => {
                    // unknown field allowed and ignored
                    map.next_value::<::serde_json::Value>()?;
                }
            }
        }
        if optional && nothing {
            return Ok(None);
        }
        let result = UpdatePropertiesArg {
            path: field_path.ok_or_else(|| ::serde::de::Error::missing_field("path"))?,
            update_property_groups: field_update_property_groups.ok_or_else(|| ::serde::de::Error::missing_field("update_property_groups"))?,
        };
        Ok(Some(result))
    }

    pub(crate) fn internal_serialize<S: ::serde::ser::Serializer>(
        &self,
        s: &mut S::SerializeStruct,
    ) -> Result<(), S::Error> {
        use serde::ser::SerializeStruct;
        s.serialize_field("path", &self.path)?;
        s.serialize_field("update_property_groups", &self.update_property_groups)?;
        Ok(())
    }
}

impl<'de> ::serde::de::Deserialize<'de> for UpdatePropertiesArg {
    fn deserialize<D: ::serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        // struct deserializer
        use serde::de::{MapAccess, Visitor};
        struct StructVisitor;
        impl<'de> Visitor<'de> for StructVisitor {
            type Value = UpdatePropertiesArg;
            fn expecting(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                f.write_str("a UpdatePropertiesArg struct")
            }
            fn visit_map<V: MapAccess<'de>>(self, map: V) -> Result<Self::Value, V::Error> {
                UpdatePropertiesArg::internal_deserialize(map)
            }
        }
        deserializer.deserialize_struct("UpdatePropertiesArg", UPDATE_PROPERTIES_ARG_FIELDS, StructVisitor)
    }
}

impl ::serde::ser::Serialize for UpdatePropertiesArg {
    fn serialize<S: ::serde::ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        // struct serializer
        use serde::ser::SerializeStruct;
        let mut s = serializer.serialize_struct("UpdatePropertiesArg", 2)?;
        self.internal_serialize::<S>(&mut s)?;
        s.end()
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive] // variants may be added in the future
pub enum UpdatePropertiesError {
    /// Template does not exist for the given identifier.
    TemplateNotFound(TemplateId),
    /// You do not have permission to modify this template.
    RestrictedContent,
    Path(LookupError),
    /// This folder cannot be tagged. Tagging folders is not supported for team-owned templates.
    UnsupportedFolder,
    /// One or more of the supplied property field values is too large.
    PropertyFieldTooLarge,
    /// One or more of the supplied property fields does not conform to the template specifications.
    DoesNotFitTemplate,
    /// There are 2 or more property groups referring to the same templates in the input.
    DuplicatePropertyGroups,
    PropertyGroupLookup(LookUpPropertiesError),
    /// Catch-all used for unrecognized values returned from the server. Encountering this value
    /// typically indicates that this SDK version is out of date.
    Other,
}

impl<'de> ::serde::de::Deserialize<'de> for UpdatePropertiesError {
    fn deserialize<D: ::serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        // union deserializer
        use serde::de::{self, MapAccess, Visitor};
        struct EnumVisitor;
        impl<'de> Visitor<'de> for EnumVisitor {
            type Value = UpdatePropertiesError;
            fn expecting(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                f.write_str("a UpdatePropertiesError structure")
            }
            fn visit_map<V: MapAccess<'de>>(self, mut map: V) -> Result<Self::Value, V::Error> {
                let tag: &str = match map.next_key()? {
                    Some(".tag") => map.next_value()?,
                    _ => return Err(de::Error::missing_field(".tag"))
                };
                let value = match tag {
                    "template_not_found" => {
                        match map.next_key()? {
                            Some("template_not_found") => UpdatePropertiesError::TemplateNotFound(map.next_value()?),
                            None => return Err(de::Error::missing_field("template_not_found")),
                            _ => return Err(de::Error::unknown_field(tag, VARIANTS))
                        }
                    }
                    "restricted_content" => UpdatePropertiesError::RestrictedContent,
                    "path" => {
                        match map.next_key()? {
                            Some("path") => UpdatePropertiesError::Path(map.next_value()?),
                            None => return Err(de::Error::missing_field("path")),
                            _ => return Err(de::Error::unknown_field(tag, VARIANTS))
                        }
                    }
                    "unsupported_folder" => UpdatePropertiesError::UnsupportedFolder,
                    "property_field_too_large" => UpdatePropertiesError::PropertyFieldTooLarge,
                    "does_not_fit_template" => UpdatePropertiesError::DoesNotFitTemplate,
                    "duplicate_property_groups" => UpdatePropertiesError::DuplicatePropertyGroups,
                    "property_group_lookup" => {
                        match map.next_key()? {
                            Some("property_group_lookup") => UpdatePropertiesError::PropertyGroupLookup(map.next_value()?),
                            None => return Err(de::Error::missing_field("property_group_lookup")),
                            _ => return Err(de::Error::unknown_field(tag, VARIANTS))
                        }
                    }
                    _ => UpdatePropertiesError::Other,
                };
                crate::eat_json_fields(&mut map)?;
                Ok(value)
            }
        }
        const VARIANTS: &[&str] = &["template_not_found",
                                    "restricted_content",
                                    "other",
                                    "path",
                                    "unsupported_folder",
                                    "property_field_too_large",
                                    "does_not_fit_template",
                                    "duplicate_property_groups",
                                    "property_group_lookup"];
        deserializer.deserialize_struct("UpdatePropertiesError", VARIANTS, EnumVisitor)
    }
}

impl ::serde::ser::Serialize for UpdatePropertiesError {
    fn serialize<S: ::serde::ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        // union serializer
        use serde::ser::SerializeStruct;
        match *self {
            UpdatePropertiesError::TemplateNotFound(ref x) => {
                // primitive
                let mut s = serializer.serialize_struct("UpdatePropertiesError", 2)?;
                s.serialize_field(".tag", "template_not_found")?;
                s.serialize_field("template_not_found", x)?;
                s.end()
            }
            UpdatePropertiesError::RestrictedContent => {
                // unit
                let mut s = serializer.serialize_struct("UpdatePropertiesError", 1)?;
                s.serialize_field(".tag", "restricted_content")?;
                s.end()
            }
            UpdatePropertiesError::Path(ref x) => {
                // union or polymporphic struct
                let mut s = serializer.serialize_struct("UpdatePropertiesError", 2)?;
                s.serialize_field(".tag", "path")?;
                s.serialize_field("path", x)?;
                s.end()
            }
            UpdatePropertiesError::UnsupportedFolder => {
                // unit
                let mut s = serializer.serialize_struct("UpdatePropertiesError", 1)?;
                s.serialize_field(".tag", "unsupported_folder")?;
                s.end()
            }
            UpdatePropertiesError::PropertyFieldTooLarge => {
                // unit
                let mut s = serializer.serialize_struct("UpdatePropertiesError", 1)?;
                s.serialize_field(".tag", "property_field_too_large")?;
                s.end()
            }
            UpdatePropertiesError::DoesNotFitTemplate => {
                // unit
                let mut s = serializer.serialize_struct("UpdatePropertiesError", 1)?;
                s.serialize_field(".tag", "does_not_fit_template")?;
                s.end()
            }
            UpdatePropertiesError::DuplicatePropertyGroups => {
                // unit
                let mut s = serializer.serialize_struct("UpdatePropertiesError", 1)?;
                s.serialize_field(".tag", "duplicate_property_groups")?;
                s.end()
            }
            UpdatePropertiesError::PropertyGroupLookup(ref x) => {
                // union or polymporphic struct
                let mut s = serializer.serialize_struct("UpdatePropertiesError", 2)?;
                s.serialize_field(".tag", "property_group_lookup")?;
                s.serialize_field("property_group_lookup", x)?;
                s.end()
            }
            UpdatePropertiesError::Other => Err(::serde::ser::Error::custom("cannot serialize 'Other' variant"))
        }
    }
}

impl ::std::error::Error for UpdatePropertiesError {
    fn source(&self) -> Option<&(dyn ::std::error::Error + 'static)> {
        match self {
            UpdatePropertiesError::Path(inner) => Some(inner),
            UpdatePropertiesError::PropertyGroupLookup(inner) => Some(inner),
            _ => None,
        }
    }
}

impl ::std::fmt::Display for UpdatePropertiesError {
    fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
        match self {
            UpdatePropertiesError::TemplateNotFound(inner) => write!(f, "Template does not exist for the given identifier: {:?}", inner),
            UpdatePropertiesError::RestrictedContent => f.write_str("You do not have permission to modify this template."),
            UpdatePropertiesError::Path(inner) => write!(f, "{}", inner),
            UpdatePropertiesError::UnsupportedFolder => f.write_str("This folder cannot be tagged. Tagging folders is not supported for team-owned templates."),
            UpdatePropertiesError::PropertyFieldTooLarge => f.write_str("One or more of the supplied property field values is too large."),
            UpdatePropertiesError::DoesNotFitTemplate => f.write_str("One or more of the supplied property fields does not conform to the template specifications."),
            UpdatePropertiesError::DuplicatePropertyGroups => f.write_str("There are 2 or more property groups referring to the same templates in the input."),
            UpdatePropertiesError::PropertyGroupLookup(inner) => write!(f, "{}", inner),
            _ => write!(f, "{:?}", *self),
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive] // structs may have more fields added in the future.
pub struct UpdateTemplateArg {
    /// An identifier for template added by  See
    /// [`templates_add_for_user()`](templates_add_for_user) or
    /// [`templates_add_for_team()`](templates_add_for_team).
    pub template_id: TemplateId,
    /// A display name for the template. template names can be up to 256 bytes.
    pub name: Option<String>,
    /// Description for the new template. Template descriptions can be up to 1024 bytes.
    pub description: Option<String>,
    /// Property field templates to be added to the group template. There can be up to 32 properties
    /// in a single template.
    pub add_fields: Option<Vec<PropertyFieldTemplate>>,
}

impl UpdateTemplateArg {
    pub fn new(template_id: TemplateId) -> Self {
        UpdateTemplateArg {
            template_id,
            name: None,
            description: None,
            add_fields: None,
        }
    }

    pub fn with_name(mut self, value: String) -> Self {
        self.name = Some(value);
        self
    }

    pub fn with_description(mut self, value: String) -> Self {
        self.description = Some(value);
        self
    }

    pub fn with_add_fields(mut self, value: Vec<PropertyFieldTemplate>) -> Self {
        self.add_fields = Some(value);
        self
    }
}

const UPDATE_TEMPLATE_ARG_FIELDS: &[&str] = &["template_id",
                                              "name",
                                              "description",
                                              "add_fields"];
impl UpdateTemplateArg {
    pub(crate) fn internal_deserialize<'de, V: ::serde::de::MapAccess<'de>>(
        map: V,
    ) -> Result<UpdateTemplateArg, V::Error> {
        Self::internal_deserialize_opt(map, false).map(Option::unwrap)
    }

    pub(crate) fn internal_deserialize_opt<'de, V: ::serde::de::MapAccess<'de>>(
        mut map: V,
        optional: bool,
    ) -> Result<Option<UpdateTemplateArg>, V::Error> {
        let mut field_template_id = None;
        let mut field_name = None;
        let mut field_description = None;
        let mut field_add_fields = None;
        let mut nothing = true;
        while let Some(key) = map.next_key::<&str>()? {
            nothing = false;
            match key {
                "template_id" => {
                    if field_template_id.is_some() {
                        return Err(::serde::de::Error::duplicate_field("template_id"));
                    }
                    field_template_id = Some(map.next_value()?);
                }
                "name" => {
                    if field_name.is_some() {
                        return Err(::serde::de::Error::duplicate_field("name"));
                    }
                    field_name = Some(map.next_value()?);
                }
                "description" => {
                    if field_description.is_some() {
                        return Err(::serde::de::Error::duplicate_field("description"));
                    }
                    field_description = Some(map.next_value()?);
                }
                "add_fields" => {
                    if field_add_fields.is_some() {
                        return Err(::serde::de::Error::duplicate_field("add_fields"));
                    }
                    field_add_fields = Some(map.next_value()?);
                }
                _ => {
                    // unknown field allowed and ignored
                    map.next_value::<::serde_json::Value>()?;
                }
            }
        }
        if optional && nothing {
            return Ok(None);
        }
        let result = UpdateTemplateArg {
            template_id: field_template_id.ok_or_else(|| ::serde::de::Error::missing_field("template_id"))?,
            name: field_name,
            description: field_description,
            add_fields: field_add_fields,
        };
        Ok(Some(result))
    }

    pub(crate) fn internal_serialize<S: ::serde::ser::Serializer>(
        &self,
        s: &mut S::SerializeStruct,
    ) -> Result<(), S::Error> {
        use serde::ser::SerializeStruct;
        s.serialize_field("template_id", &self.template_id)?;
        if let Some(val) = &self.name {
            s.serialize_field("name", val)?;
        }
        if let Some(val) = &self.description {
            s.serialize_field("description", val)?;
        }
        if let Some(val) = &self.add_fields {
            s.serialize_field("add_fields", val)?;
        }
        Ok(())
    }
}

impl<'de> ::serde::de::Deserialize<'de> for UpdateTemplateArg {
    fn deserialize<D: ::serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        // struct deserializer
        use serde::de::{MapAccess, Visitor};
        struct StructVisitor;
        impl<'de> Visitor<'de> for StructVisitor {
            type Value = UpdateTemplateArg;
            fn expecting(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                f.write_str("a UpdateTemplateArg struct")
            }
            fn visit_map<V: MapAccess<'de>>(self, map: V) -> Result<Self::Value, V::Error> {
                UpdateTemplateArg::internal_deserialize(map)
            }
        }
        deserializer.deserialize_struct("UpdateTemplateArg", UPDATE_TEMPLATE_ARG_FIELDS, StructVisitor)
    }
}

impl ::serde::ser::Serialize for UpdateTemplateArg {
    fn serialize<S: ::serde::ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        // struct serializer
        use serde::ser::SerializeStruct;
        let mut s = serializer.serialize_struct("UpdateTemplateArg", 4)?;
        self.internal_serialize::<S>(&mut s)?;
        s.end()
    }
}

#[derive(Debug, Clone, PartialEq, Eq)]
#[non_exhaustive] // structs may have more fields added in the future.
pub struct UpdateTemplateResult {
    /// An identifier for template added by route  See
    /// [`templates_add_for_user()`](templates_add_for_user) or
    /// [`templates_add_for_team()`](templates_add_for_team).
    pub template_id: TemplateId,
}

impl UpdateTemplateResult {
    pub fn new(template_id: TemplateId) -> Self {
        UpdateTemplateResult {
            template_id,
        }
    }
}

const UPDATE_TEMPLATE_RESULT_FIELDS: &[&str] = &["template_id"];
impl UpdateTemplateResult {
    pub(crate) fn internal_deserialize<'de, V: ::serde::de::MapAccess<'de>>(
        map: V,
    ) -> Result<UpdateTemplateResult, V::Error> {
        Self::internal_deserialize_opt(map, false).map(Option::unwrap)
    }

    pub(crate) fn internal_deserialize_opt<'de, V: ::serde::de::MapAccess<'de>>(
        mut map: V,
        optional: bool,
    ) -> Result<Option<UpdateTemplateResult>, V::Error> {
        let mut field_template_id = None;
        let mut nothing = true;
        while let Some(key) = map.next_key::<&str>()? {
            nothing = false;
            match key {
                "template_id" => {
                    if field_template_id.is_some() {
                        return Err(::serde::de::Error::duplicate_field("template_id"));
                    }
                    field_template_id = Some(map.next_value()?);
                }
                _ => {
                    // unknown field allowed and ignored
                    map.next_value::<::serde_json::Value>()?;
                }
            }
        }
        if optional && nothing {
            return Ok(None);
        }
        let result = UpdateTemplateResult {
            template_id: field_template_id.ok_or_else(|| ::serde::de::Error::missing_field("template_id"))?,
        };
        Ok(Some(result))
    }

    pub(crate) fn internal_serialize<S: ::serde::ser::Serializer>(
        &self,
        s: &mut S::SerializeStruct,
    ) -> Result<(), S::Error> {
        use serde::ser::SerializeStruct;
        s.serialize_field("template_id", &self.template_id)?;
        Ok(())
    }
}

impl<'de> ::serde::de::Deserialize<'de> for UpdateTemplateResult {
    fn deserialize<D: ::serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
        // struct deserializer
        use serde::de::{MapAccess, Visitor};
        struct StructVisitor;
        impl<'de> Visitor<'de> for StructVisitor {
            type Value = UpdateTemplateResult;
            fn expecting(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                f.write_str("a UpdateTemplateResult struct")
            }
            fn visit_map<V: MapAccess<'de>>(self, map: V) -> Result<Self::Value, V::Error> {
                UpdateTemplateResult::internal_deserialize(map)
            }
        }
        deserializer.deserialize_struct("UpdateTemplateResult", UPDATE_TEMPLATE_RESULT_FIELDS, StructVisitor)
    }
}

impl ::serde::ser::Serialize for UpdateTemplateResult {
    fn serialize<S: ::serde::ser::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
        // struct serializer
        use serde::ser::SerializeStruct;
        let mut s = serializer.serialize_struct("UpdateTemplateResult", 1)?;
        self.internal_serialize::<S>(&mut s)?;
        s.end()
    }
}