// @generated by jacquard-lexicon. DO NOT EDIT.
//
// Lexicon: com.germnetwork.declaration
//
// This file was automatically generated from Lexicon schemas.
// Any manual changes will be overwritten on the next regeneration.

#[allow(unused_imports)]
use alloc::collections::BTreeMap;

#[allow(unused_imports)]
use core::marker::PhantomData;
use jacquard_common::{CowStr, BosStr, DefaultStr, FromStaticStr};
use jacquard_common::deps::bytes::Bytes;

#[allow(unused_imports)]
use jacquard_common::deps::codegen::unicode_segmentation::UnicodeSegmentation;
use jacquard_common::deps::smol_str::SmolStr;
use jacquard_common::types::collection::{Collection, RecordError};
use jacquard_common::types::string::{AtUri, Cid, UriValue};
use jacquard_common::types::uri::{RecordUri, UriError};
use jacquard_common::types::value::Data;
use jacquard_common::xrpc::XrpcResp;
use jacquard_derive::{IntoStatic, lexicon};
use jacquard_lexicon::lexicon::LexiconDoc;
use jacquard_lexicon::schema::LexiconSchema;

#[allow(unused_imports)]
use jacquard_lexicon::validation::{ConstraintError, ValidationPath};
use serde::{Serialize, Deserialize};
use crate::com_germnetwork::declaration;
/// A declaration of a Germ Network account

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
#[serde(
    rename_all = "camelCase",
    rename = "com.germnetwork.declaration",
    tag = "$type",
    bound(deserialize = "S: Deserialize<'de> + BosStr")
)]
pub struct Declaration<S: BosStr = DefaultStr> {
    ///Array of opaque values to allow for key rolling
    #[serde(skip_serializing_if = "Option::is_none")]
    pub continuity_proofs: Option<Vec<Bytes>>,
    ///Opaque value, an ed25519 public key prefixed with a byte enum
    #[serde(with = "jacquard_common::serde_bytes_helper")]
    pub current_key: Bytes,
    ///Opaque value, contains MLS KeyPackage(s), and other signature data, and is signed by the currentKey
    #[serde(skip_serializing_if = "Option::is_none")]
    #[serde(default, with = "jacquard_common::opt_serde_bytes_helper")]
    pub key_package: Option<Bytes>,
    ///Controls who can message this account
    #[serde(skip_serializing_if = "Option::is_none")]
    pub message_me: Option<declaration::MessageMe<S>>,
    ///Semver version number, without pre-release or build information, for the format of opaque content
    pub version: S,
    #[serde(flatten, default, skip_serializing_if = "Option::is_none")]
    pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,
}

/// Typed wrapper for GetRecord response with this collection's record type.

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
#[serde(rename_all = "camelCase")]
pub struct DeclarationGetRecordOutput<S: BosStr = DefaultStr> {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub cid: Option<Cid<S>>,
    pub uri: AtUri<S>,
    pub value: Declaration<S>,
}


#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))]
pub struct MessageMe<S: BosStr = DefaultStr> {
    ///A URL to present to an account that does not have its own com.germnetwork.declaration record, must have an empty fragment component, where the app should fill in the fragment component with the DIDs of the two accounts who wish to message each other
    pub message_me_url: UriValue<S>,
    ///The policy of who can message the account, this value is included in the keyPackage, but is duplicated here to allow applications to decide if they should show a 'Message on Germ' button to the viewer.
    pub show_button_to: MessageMeShowButtonTo<S>,
    #[serde(flatten, default, skip_serializing_if = "Option::is_none")]
    pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,
}

/// The policy of who can message the account, this value is included in the keyPackage, but is duplicated here to allow applications to decide if they should show a 'Message on Germ' button to the viewer.

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum MessageMeShowButtonTo<S: BosStr = DefaultStr> {
    None,
    UsersIFollow,
    Everyone,
    Other(S),
}

impl<S: BosStr> MessageMeShowButtonTo<S> {
    pub fn as_str(&self) -> &str {
        match self {
            Self::None => "none",
            Self::UsersIFollow => "usersIFollow",
            Self::Everyone => "everyone",
            Self::Other(s) => s.as_ref(),
        }
    }
    /// Construct from a string-like value, matching known values.
    pub fn from_value(s: S) -> Self {
        match s.as_ref() {
            "none" => Self::None,
            "usersIFollow" => Self::UsersIFollow,
            "everyone" => Self::Everyone,
            _ => Self::Other(s),
        }
    }
}

impl<S: BosStr> core::fmt::Display for MessageMeShowButtonTo<S> {
    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
        write!(f, "{}", self.as_str())
    }
}

impl<S: BosStr> AsRef<str> for MessageMeShowButtonTo<S> {
    fn as_ref(&self) -> &str {
        self.as_str()
    }
}

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

impl<'de, S: Deserialize<'de> + BosStr> Deserialize<'de> for MessageMeShowButtonTo<S> {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let s = S::deserialize(deserializer)?;
        Ok(Self::from_value(s))
    }
}

impl<S: BosStr + Default> Default for MessageMeShowButtonTo<S> {
    fn default() -> Self {
        Self::Other(Default::default())
    }
}

impl<S: BosStr> jacquard_common::IntoStatic for MessageMeShowButtonTo<S>
where
    S: BosStr + jacquard_common::IntoStatic,
    S::Output: BosStr,
{
    type Output = MessageMeShowButtonTo<S::Output>;
    fn into_static(self) -> Self::Output {
        match self {
            MessageMeShowButtonTo::None => MessageMeShowButtonTo::None,
            MessageMeShowButtonTo::UsersIFollow => MessageMeShowButtonTo::UsersIFollow,
            MessageMeShowButtonTo::Everyone => MessageMeShowButtonTo::Everyone,
            MessageMeShowButtonTo::Other(v) => {
                MessageMeShowButtonTo::Other(v.into_static())
            }
        }
    }
}

impl<S: BosStr> Declaration<S> {
    pub fn uri(uri: S) -> Result<RecordUri<S, DeclarationRecord>, UriError> {
        RecordUri::try_from_uri(AtUri::new(uri)?)
    }
}

/// Marker type for deserializing records from this collection.

#[derive(Debug, Serialize, Deserialize)]
pub struct DeclarationRecord;
impl XrpcResp for DeclarationRecord {
    const NSID: &'static str = "com.germnetwork.declaration";
    const ENCODING: &'static str = "application/json";
    type Output<S: BosStr> = DeclarationGetRecordOutput<S>;
    type Err = RecordError;
}

impl<S: BosStr> From<DeclarationGetRecordOutput<S>> for Declaration<S> {
    fn from(output: DeclarationGetRecordOutput<S>) -> Self {
        output.value
    }
}

impl<S: BosStr> Collection for Declaration<S> {
    const NSID: &'static str = "com.germnetwork.declaration";
    type Record = DeclarationRecord;
}

impl Collection for DeclarationRecord {
    const NSID: &'static str = "com.germnetwork.declaration";
    type Record = DeclarationRecord;
}

impl<S: BosStr> LexiconSchema for Declaration<S> {
    fn nsid() -> &'static str {
        "com.germnetwork.declaration"
    }
    fn def_name() -> &'static str {
        "main"
    }
    fn lexicon_doc() -> LexiconDoc<'static> {
        lexicon_doc_com_germnetwork_declaration()
    }
    fn validate(&self) -> Result<(), ConstraintError> {
        if let Some(ref value) = self.continuity_proofs {
            #[allow(unused_comparisons)]
            if value.len() > 1000usize {
                return Err(ConstraintError::MaxLength {
                    path: ValidationPath::from_field("continuity_proofs"),
                    max: 1000usize,
                    actual: value.len(),
                });
            }
        }
        {
            let value = &self.version;
            #[allow(unused_comparisons)]
            if <str>::len(value.as_ref()) > 14usize {
                return Err(ConstraintError::MaxLength {
                    path: ValidationPath::from_field("version"),
                    max: 14usize,
                    actual: <str>::len(value.as_ref()),
                });
            }
        }
        {
            let value = &self.version;
            #[allow(unused_comparisons)]
            if <str>::len(value.as_ref()) < 5usize {
                return Err(ConstraintError::MinLength {
                    path: ValidationPath::from_field("version"),
                    min: 5usize,
                    actual: <str>::len(value.as_ref()),
                });
            }
        }
        Ok(())
    }
}

impl<S: BosStr> LexiconSchema for MessageMe<S> {
    fn nsid() -> &'static str {
        "com.germnetwork.declaration"
    }
    fn def_name() -> &'static str {
        "messageMe"
    }
    fn lexicon_doc() -> LexiconDoc<'static> {
        lexicon_doc_com_germnetwork_declaration()
    }
    fn validate(&self) -> Result<(), ConstraintError> {
        {
            let value = &self.message_me_url;
            #[allow(unused_comparisons)]
            if <str>::len(value.as_ref()) > 2047usize {
                return Err(ConstraintError::MaxLength {
                    path: ValidationPath::from_field("message_me_url"),
                    max: 2047usize,
                    actual: <str>::len(value.as_ref()),
                });
            }
        }
        {
            let value = &self.message_me_url;
            #[allow(unused_comparisons)]
            if <str>::len(value.as_ref()) < 1usize {
                return Err(ConstraintError::MinLength {
                    path: ValidationPath::from_field("message_me_url"),
                    min: 1usize,
                    actual: <str>::len(value.as_ref()),
                });
            }
        }
        {
            let value = &self.show_button_to;
            #[allow(unused_comparisons)]
            if <str>::len(value.as_ref()) > 100usize {
                return Err(ConstraintError::MaxLength {
                    path: ValidationPath::from_field("show_button_to"),
                    max: 100usize,
                    actual: <str>::len(value.as_ref()),
                });
            }
        }
        {
            let value = &self.show_button_to;
            #[allow(unused_comparisons)]
            if <str>::len(value.as_ref()) < 1usize {
                return Err(ConstraintError::MinLength {
                    path: ValidationPath::from_field("show_button_to"),
                    min: 1usize,
                    actual: <str>::len(value.as_ref()),
                });
            }
        }
        Ok(())
    }
}

pub mod declaration_state {

    pub use crate::builder_types::{Set, Unset, IsSet, IsUnset};
    #[allow(unused)]
    use ::core::marker::PhantomData;
    mod sealed {
        pub trait Sealed {}
    }
    /// State trait tracking which required fields have been set
    pub trait State: sealed::Sealed {
        type CurrentKey;
        type Version;
    }
    /// Empty state - all required fields are unset
    pub struct Empty(());
    impl sealed::Sealed for Empty {}
    impl State for Empty {
        type CurrentKey = Unset;
        type Version = Unset;
    }
    ///State transition - sets the `current_key` field to Set
    pub struct SetCurrentKey<St: State = Empty>(PhantomData<fn() -> St>);
    impl<St: State> sealed::Sealed for SetCurrentKey<St> {}
    impl<St: State> State for SetCurrentKey<St> {
        type CurrentKey = Set<members::current_key>;
        type Version = St::Version;
    }
    ///State transition - sets the `version` field to Set
    pub struct SetVersion<St: State = Empty>(PhantomData<fn() -> St>);
    impl<St: State> sealed::Sealed for SetVersion<St> {}
    impl<St: State> State for SetVersion<St> {
        type CurrentKey = St::CurrentKey;
        type Version = Set<members::version>;
    }
    /// Marker types for field names
    #[allow(non_camel_case_types)]
    pub mod members {
        ///Marker type for the `current_key` field
        pub struct current_key(());
        ///Marker type for the `version` field
        pub struct version(());
    }
}

/// Builder for constructing an instance of this type.
pub struct DeclarationBuilder<St: declaration_state::State, S: BosStr = DefaultStr> {
    _state: PhantomData<fn() -> St>,
    _fields: (
        Option<Vec<Bytes>>,
        Option<Bytes>,
        Option<Bytes>,
        Option<declaration::MessageMe<S>>,
        Option<S>,
    ),
    _type: PhantomData<fn() -> S>,
}

impl Declaration<DefaultStr> {
    /// Create a new builder for this type, using the default string type (DefaultStr = SmolStr) if needed
    pub fn new() -> DeclarationBuilder<declaration_state::Empty, DefaultStr> {
        DeclarationBuilder::new()
    }
}

impl<S: BosStr> Declaration<S> {
    /// Create a new builder for this type
    pub fn builder() -> DeclarationBuilder<declaration_state::Empty, S> {
        DeclarationBuilder::builder()
    }
}

impl DeclarationBuilder<declaration_state::Empty, DefaultStr> {
    /// Create a new builder with all fields unset, using the default string type, if needed
    pub fn new() -> Self {
        DeclarationBuilder {
            _state: PhantomData,
            _fields: (None, None, None, None, None),
            _type: PhantomData,
        }
    }
}

impl<S: BosStr> DeclarationBuilder<declaration_state::Empty, S> {
    /// Create a new builder with all fields unset
    pub fn builder() -> Self {
        DeclarationBuilder {
            _state: PhantomData,
            _fields: (None, None, None, None, None),
            _type: PhantomData,
        }
    }
}

impl<St: declaration_state::State, S: BosStr> DeclarationBuilder<St, S> {
    /// Set the `continuityProofs` field (optional)
    pub fn continuity_proofs(mut self, value: impl Into<Option<Vec<Bytes>>>) -> Self {
        self._fields.0 = value.into();
        self
    }
    /// Set the `continuityProofs` field to an Option value (optional)
    pub fn maybe_continuity_proofs(mut self, value: Option<Vec<Bytes>>) -> Self {
        self._fields.0 = value;
        self
    }
}

impl<St, S: BosStr> DeclarationBuilder<St, S>
where
    St: declaration_state::State,
    St::CurrentKey: declaration_state::IsUnset,
{
    /// Set the `currentKey` field (required)
    pub fn current_key(
        mut self,
        value: impl Into<Bytes>,
    ) -> DeclarationBuilder<declaration_state::SetCurrentKey<St>, S> {
        self._fields.1 = Option::Some(value.into());
        DeclarationBuilder {
            _state: PhantomData,
            _fields: self._fields,
            _type: PhantomData,
        }
    }
}

impl<St: declaration_state::State, S: BosStr> DeclarationBuilder<St, S> {
    /// Set the `keyPackage` field (optional)
    pub fn key_package(mut self, value: impl Into<Option<Bytes>>) -> Self {
        self._fields.2 = value.into();
        self
    }
    /// Set the `keyPackage` field to an Option value (optional)
    pub fn maybe_key_package(mut self, value: Option<Bytes>) -> Self {
        self._fields.2 = value;
        self
    }
}

impl<St: declaration_state::State, S: BosStr> DeclarationBuilder<St, S> {
    /// Set the `messageMe` field (optional)
    pub fn message_me(
        mut self,
        value: impl Into<Option<declaration::MessageMe<S>>>,
    ) -> Self {
        self._fields.3 = value.into();
        self
    }
    /// Set the `messageMe` field to an Option value (optional)
    pub fn maybe_message_me(mut self, value: Option<declaration::MessageMe<S>>) -> Self {
        self._fields.3 = value;
        self
    }
}

impl<St, S: BosStr> DeclarationBuilder<St, S>
where
    St: declaration_state::State,
    St::Version: declaration_state::IsUnset,
{
    /// Set the `version` field (required)
    pub fn version(
        mut self,
        value: impl Into<S>,
    ) -> DeclarationBuilder<declaration_state::SetVersion<St>, S> {
        self._fields.4 = Option::Some(value.into());
        DeclarationBuilder {
            _state: PhantomData,
            _fields: self._fields,
            _type: PhantomData,
        }
    }
}

impl<St, S: BosStr> DeclarationBuilder<St, S>
where
    St: declaration_state::State,
    St::CurrentKey: declaration_state::IsSet,
    St::Version: declaration_state::IsSet,
{
    /// Build the final struct.
    pub fn build(self) -> Declaration<S> {
        Declaration {
            continuity_proofs: self._fields.0,
            current_key: self._fields.1.unwrap(),
            key_package: self._fields.2,
            message_me: self._fields.3,
            version: self._fields.4.unwrap(),
            extra_data: Default::default(),
        }
    }
    /// Build the final struct with custom extra_data.
    pub fn build_with_data(
        self,
        extra_data: BTreeMap<SmolStr, Data<S>>,
    ) -> Declaration<S> {
        Declaration {
            continuity_proofs: self._fields.0,
            current_key: self._fields.1.unwrap(),
            key_package: self._fields.2,
            message_me: self._fields.3,
            version: self._fields.4.unwrap(),
            extra_data: Some(extra_data),
        }
    }
}

fn lexicon_doc_com_germnetwork_declaration() -> LexiconDoc<'static> {
    #[allow(unused_imports)]
    use jacquard_common::{CowStr, deps::smol_str::SmolStr, types::blob::MimeType};
    use jacquard_lexicon::lexicon::*;
    use alloc::collections::BTreeMap;
    LexiconDoc {
        lexicon: Lexicon::Lexicon1,
        id: CowStr::new_static("com.germnetwork.declaration"),
        defs: {
            let mut map = BTreeMap::new();
            map.insert(
                SmolStr::new_static("main"),
                LexUserType::Record(LexRecord {
                    description: Some(
                        CowStr::new_static("A declaration of a Germ Network account"),
                    ),
                    key: Some(CowStr::new_static("literal:self")),
                    record: LexRecordRecord::Object(LexObject {
                        required: Some(
                            vec![
                                SmolStr::new_static("version"),
                                SmolStr::new_static("currentKey")
                            ],
                        ),
                        properties: {
                            #[allow(unused_mut)]
                            let mut map = BTreeMap::new();
                            map.insert(
                                SmolStr::new_static("continuityProofs"),
                                LexObjectProperty::Array(LexArray {
                                    description: Some(
                                        CowStr::new_static(
                                            "Array of opaque values to allow for key rolling",
                                        ),
                                    ),
                                    items: LexArrayItem::Bytes(LexBytes {
                                        ..Default::default()
                                    }),
                                    max_length: Some(1000usize),
                                    ..Default::default()
                                }),
                            );
                            map.insert(
                                SmolStr::new_static("currentKey"),
                                LexObjectProperty::Bytes(LexBytes { ..Default::default() }),
                            );
                            map.insert(
                                SmolStr::new_static("keyPackage"),
                                LexObjectProperty::Bytes(LexBytes { ..Default::default() }),
                            );
                            map.insert(
                                SmolStr::new_static("messageMe"),
                                LexObjectProperty::Ref(LexRef {
                                    r#ref: CowStr::new_static("#messageMe"),
                                    ..Default::default()
                                }),
                            );
                            map.insert(
                                SmolStr::new_static("version"),
                                LexObjectProperty::String(LexString {
                                    description: Some(
                                        CowStr::new_static(
                                            "Semver version number, without pre-release or build information, for the format of opaque content",
                                        ),
                                    ),
                                    min_length: Some(5usize),
                                    max_length: Some(14usize),
                                    ..Default::default()
                                }),
                            );
                            map
                        },
                        ..Default::default()
                    }),
                    ..Default::default()
                }),
            );
            map.insert(
                SmolStr::new_static("messageMe"),
                LexUserType::Object(LexObject {
                    required: Some(
                        vec![
                            SmolStr::new_static("showButtonTo"),
                            SmolStr::new_static("messageMeUrl")
                        ],
                    ),
                    properties: {
                        #[allow(unused_mut)]
                        let mut map = BTreeMap::new();
                        map.insert(
                            SmolStr::new_static("messageMeUrl"),
                            LexObjectProperty::String(LexString {
                                description: Some(
                                    CowStr::new_static(
                                        "A URL to present to an account that does not have its own com.germnetwork.declaration record, must have an empty fragment component, where the app should fill in the fragment component with the DIDs of the two accounts who wish to message each other",
                                    ),
                                ),
                                format: Some(LexStringFormat::Uri),
                                min_length: Some(1usize),
                                max_length: Some(2047usize),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("showButtonTo"),
                            LexObjectProperty::String(LexString {
                                description: Some(
                                    CowStr::new_static(
                                        "The policy of who can message the account, this value is included in the keyPackage, but is duplicated here to allow applications to decide if they should show a 'Message on Germ' button to the viewer.",
                                    ),
                                ),
                                min_length: Some(1usize),
                                max_length: Some(100usize),
                                ..Default::default()
                            }),
                        );
                        map
                    },
                    ..Default::default()
                }),
            );
            map
        },
        ..Default::default()
    }
}

pub mod message_me_state {

    pub use crate::builder_types::{Set, Unset, IsSet, IsUnset};
    #[allow(unused)]
    use ::core::marker::PhantomData;
    mod sealed {
        pub trait Sealed {}
    }
    /// State trait tracking which required fields have been set
    pub trait State: sealed::Sealed {
        type MessageMeUrl;
        type ShowButtonTo;
    }
    /// Empty state - all required fields are unset
    pub struct Empty(());
    impl sealed::Sealed for Empty {}
    impl State for Empty {
        type MessageMeUrl = Unset;
        type ShowButtonTo = Unset;
    }
    ///State transition - sets the `message_me_url` field to Set
    pub struct SetMessageMeUrl<St: State = Empty>(PhantomData<fn() -> St>);
    impl<St: State> sealed::Sealed for SetMessageMeUrl<St> {}
    impl<St: State> State for SetMessageMeUrl<St> {
        type MessageMeUrl = Set<members::message_me_url>;
        type ShowButtonTo = St::ShowButtonTo;
    }
    ///State transition - sets the `show_button_to` field to Set
    pub struct SetShowButtonTo<St: State = Empty>(PhantomData<fn() -> St>);
    impl<St: State> sealed::Sealed for SetShowButtonTo<St> {}
    impl<St: State> State for SetShowButtonTo<St> {
        type MessageMeUrl = St::MessageMeUrl;
        type ShowButtonTo = Set<members::show_button_to>;
    }
    /// Marker types for field names
    #[allow(non_camel_case_types)]
    pub mod members {
        ///Marker type for the `message_me_url` field
        pub struct message_me_url(());
        ///Marker type for the `show_button_to` field
        pub struct show_button_to(());
    }
}

/// Builder for constructing an instance of this type.
pub struct MessageMeBuilder<St: message_me_state::State, S: BosStr = DefaultStr> {
    _state: PhantomData<fn() -> St>,
    _fields: (Option<UriValue<S>>, Option<MessageMeShowButtonTo<S>>),
    _type: PhantomData<fn() -> S>,
}

impl MessageMe<DefaultStr> {
    /// Create a new builder for this type, using the default string type (DefaultStr = SmolStr) if needed
    pub fn new() -> MessageMeBuilder<message_me_state::Empty, DefaultStr> {
        MessageMeBuilder::new()
    }
}

impl<S: BosStr> MessageMe<S> {
    /// Create a new builder for this type
    pub fn builder() -> MessageMeBuilder<message_me_state::Empty, S> {
        MessageMeBuilder::builder()
    }
}

impl MessageMeBuilder<message_me_state::Empty, DefaultStr> {
    /// Create a new builder with all fields unset, using the default string type, if needed
    pub fn new() -> Self {
        MessageMeBuilder {
            _state: PhantomData,
            _fields: (None, None),
            _type: PhantomData,
        }
    }
}

impl<S: BosStr> MessageMeBuilder<message_me_state::Empty, S> {
    /// Create a new builder with all fields unset
    pub fn builder() -> Self {
        MessageMeBuilder {
            _state: PhantomData,
            _fields: (None, None),
            _type: PhantomData,
        }
    }
}

impl<St, S: BosStr> MessageMeBuilder<St, S>
where
    St: message_me_state::State,
    St::MessageMeUrl: message_me_state::IsUnset,
{
    /// Set the `messageMeUrl` field (required)
    pub fn message_me_url(
        mut self,
        value: impl Into<UriValue<S>>,
    ) -> MessageMeBuilder<message_me_state::SetMessageMeUrl<St>, S> {
        self._fields.0 = Option::Some(value.into());
        MessageMeBuilder {
            _state: PhantomData,
            _fields: self._fields,
            _type: PhantomData,
        }
    }
}

impl<St, S: BosStr> MessageMeBuilder<St, S>
where
    St: message_me_state::State,
    St::ShowButtonTo: message_me_state::IsUnset,
{
    /// Set the `showButtonTo` field (required)
    pub fn show_button_to(
        mut self,
        value: impl Into<MessageMeShowButtonTo<S>>,
    ) -> MessageMeBuilder<message_me_state::SetShowButtonTo<St>, S> {
        self._fields.1 = Option::Some(value.into());
        MessageMeBuilder {
            _state: PhantomData,
            _fields: self._fields,
            _type: PhantomData,
        }
    }
}

impl<St, S: BosStr> MessageMeBuilder<St, S>
where
    St: message_me_state::State,
    St::MessageMeUrl: message_me_state::IsSet,
    St::ShowButtonTo: message_me_state::IsSet,
{
    /// Build the final struct.
    pub fn build(self) -> MessageMe<S> {
        MessageMe {
            message_me_url: self._fields.0.unwrap(),
            show_button_to: self._fields.1.unwrap(),
            extra_data: Default::default(),
        }
    }
    /// Build the final struct with custom extra_data.
    pub fn build_with_data(
        self,
        extra_data: BTreeMap<SmolStr, Data<S>>,
    ) -> MessageMe<S> {
        MessageMe {
            message_me_url: self._fields.0.unwrap(),
            show_button_to: self._fields.1.unwrap(),
            extra_data: Some(extra_data),
        }
    }
}