// @generated by jacquard-lexicon. DO NOT EDIT.
//
// Lexicon: dev.keytrace.claim
//
// 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};

#[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, Datetime, 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::dev_keytrace::signature::Signature;
use crate::dev_keytrace::claim;
/// Generic identity data for the claimed account

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic, Default)]
#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))]
pub struct Identity<S: BosStr = DefaultStr> {
    ///Avatar/profile image URL
    #[serde(skip_serializing_if = "Option::is_none")]
    pub avatar_url: Option<UriValue<S>>,
    ///Display name if different from subject
    #[serde(skip_serializing_if = "Option::is_none")]
    pub display_name: Option<S>,
    ///Profile page URL
    #[serde(skip_serializing_if = "Option::is_none")]
    pub profile_url: Option<UriValue<S>>,
    ///Primary identifier (username, domain, handle, etc.)
    pub subject: S,
    #[serde(flatten, default, skip_serializing_if = "Option::is_none")]
    pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,
}

/// An identity claim linking this DID to an external account

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
#[serde(
    rename_all = "camelCase",
    rename = "dev.keytrace.claim",
    tag = "$type",
    bound(deserialize = "S: Deserialize<'de> + BosStr")
)]
pub struct Claim<S: BosStr = DefaultStr> {
    ///The identity claim URI (e.g., for github: https://gist.github.com/username/id, dns:example.com)
    pub claim_uri: S,
    ///Optional user-provided label for this claim
    #[serde(skip_serializing_if = "Option::is_none")]
    pub comment: Option<S>,
    ///Datetime when this claim was created (ISO 8601).
    pub created_at: Datetime,
    ///Timestamp when the claim last failed re-verification or was retracted
    #[serde(skip_serializing_if = "Option::is_none")]
    pub failed_at: Option<Datetime>,
    ///Structured data about the claimed identity, derived from the claimUri and knowledge inside the verification process. This is not the raw claim data, but a normalized set of fields that can be used for display and more.
    pub identity: claim::Identity<S>,
    ///Timestamp of the most recent successful re-verification by the system
    #[serde(skip_serializing_if = "Option::is_none")]
    pub last_verified_at: Option<Datetime>,
    ///Random one-time value embedded in the challenge text posted to the external service. Used by verifiers to confirm the proof was created specifically for this claim session. Keytrace itself does not use this, but other services making claims may require it for their verification process.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub nonce: Option<S>,
    ///Whether this claim was created during the prerelease/alpha period
    #[serde(skip_serializing_if = "Option::is_none")]
    pub prerelease: Option<bool>,
    ///Datetime when this claim was retracted. Present only if the claim has been retracted (ISO 8601).
    #[serde(skip_serializing_if = "Option::is_none")]
    pub retracted_at: Option<Datetime>,
    ///Cryptographic attestation signatures from verification services, for example from @keytrace.dev. These are optional, and so you can pass an empty array. Keytrace will place its attestation signature in the claim here so that the library @keytrace/claims can be used by external developers to not have to implement their own verification logic.
    pub sigs: Vec<Signature<S>>,
    ///Current verification status of this claim. Absent on legacy records, treated as 'verified'.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub status: Option<ClaimStatus<S>>,
    ///The claim type identifier
    pub r#type: ClaimType<S>,
    #[serde(flatten, default, skip_serializing_if = "Option::is_none")]
    pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,
}

/// Current verification status of this claim. Absent on legacy records, treated as 'verified'.

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum ClaimStatus<S: BosStr = DefaultStr> {
    Verified,
    Failed,
    Retracted,
    Other(S),
}

impl<S: BosStr> ClaimStatus<S> {
    pub fn as_str(&self) -> &str {
        match self {
            Self::Verified => "verified",
            Self::Failed => "failed",
            Self::Retracted => "retracted",
            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() {
            "verified" => Self::Verified,
            "failed" => Self::Failed,
            "retracted" => Self::Retracted,
            _ => Self::Other(s),
        }
    }
}

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

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

impl<S: BosStr> Serialize for ClaimStatus<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 ClaimStatus<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 ClaimStatus<S> {
    fn default() -> Self {
        Self::Other(Default::default())
    }
}

impl<S: BosStr> jacquard_common::IntoStatic for ClaimStatus<S>
where
    S: BosStr + jacquard_common::IntoStatic,
    S::Output: BosStr,
{
    type Output = ClaimStatus<S::Output>;
    fn into_static(self) -> Self::Output {
        match self {
            ClaimStatus::Verified => ClaimStatus::Verified,
            ClaimStatus::Failed => ClaimStatus::Failed,
            ClaimStatus::Retracted => ClaimStatus::Retracted,
            ClaimStatus::Other(v) => ClaimStatus::Other(v.into_static()),
        }
    }
}

/// The claim type identifier

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum ClaimType<S: BosStr = DefaultStr> {
    Github,
    Dns,
    Activitypub,
    Bsky,
    Npm,
    Tangled,
    Pgp,
    Twitter,
    Linkedin,
    Instagram,
    Reddit,
    Hackernews,
    Other(S),
}

impl<S: BosStr> ClaimType<S> {
    pub fn as_str(&self) -> &str {
        match self {
            Self::Github => "github",
            Self::Dns => "dns",
            Self::Activitypub => "activitypub",
            Self::Bsky => "bsky",
            Self::Npm => "npm",
            Self::Tangled => "tangled",
            Self::Pgp => "pgp",
            Self::Twitter => "twitter",
            Self::Linkedin => "linkedin",
            Self::Instagram => "instagram",
            Self::Reddit => "reddit",
            Self::Hackernews => "hackernews",
            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() {
            "github" => Self::Github,
            "dns" => Self::Dns,
            "activitypub" => Self::Activitypub,
            "bsky" => Self::Bsky,
            "npm" => Self::Npm,
            "tangled" => Self::Tangled,
            "pgp" => Self::Pgp,
            "twitter" => Self::Twitter,
            "linkedin" => Self::Linkedin,
            "instagram" => Self::Instagram,
            "reddit" => Self::Reddit,
            "hackernews" => Self::Hackernews,
            _ => Self::Other(s),
        }
    }
}

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

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

impl<S: BosStr> Serialize for ClaimType<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 ClaimType<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 ClaimType<S> {
    fn default() -> Self {
        Self::Other(Default::default())
    }
}

impl<S: BosStr> jacquard_common::IntoStatic for ClaimType<S>
where
    S: BosStr + jacquard_common::IntoStatic,
    S::Output: BosStr,
{
    type Output = ClaimType<S::Output>;
    fn into_static(self) -> Self::Output {
        match self {
            ClaimType::Github => ClaimType::Github,
            ClaimType::Dns => ClaimType::Dns,
            ClaimType::Activitypub => ClaimType::Activitypub,
            ClaimType::Bsky => ClaimType::Bsky,
            ClaimType::Npm => ClaimType::Npm,
            ClaimType::Tangled => ClaimType::Tangled,
            ClaimType::Pgp => ClaimType::Pgp,
            ClaimType::Twitter => ClaimType::Twitter,
            ClaimType::Linkedin => ClaimType::Linkedin,
            ClaimType::Instagram => ClaimType::Instagram,
            ClaimType::Reddit => ClaimType::Reddit,
            ClaimType::Hackernews => ClaimType::Hackernews,
            ClaimType::Other(v) => ClaimType::Other(v.into_static()),
        }
    }
}

/// 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 ClaimGetRecordOutput<S: BosStr = DefaultStr> {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub cid: Option<Cid<S>>,
    pub uri: AtUri<S>,
    pub value: Claim<S>,
}

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

impl<S: BosStr> LexiconSchema for Identity<S> {
    fn nsid() -> &'static str {
        "dev.keytrace.claim"
    }
    fn def_name() -> &'static str {
        "identity"
    }
    fn lexicon_doc() -> LexiconDoc<'static> {
        lexicon_doc_dev_keytrace_claim()
    }
    fn validate(&self) -> Result<(), ConstraintError> {
        Ok(())
    }
}

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

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

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

impl<S: BosStr> Collection for Claim<S> {
    const NSID: &'static str = "dev.keytrace.claim";
    type Record = ClaimRecord;
}

impl Collection for ClaimRecord {
    const NSID: &'static str = "dev.keytrace.claim";
    type Record = ClaimRecord;
}

impl<S: BosStr> LexiconSchema for Claim<S> {
    fn nsid() -> &'static str {
        "dev.keytrace.claim"
    }
    fn def_name() -> &'static str {
        "main"
    }
    fn lexicon_doc() -> LexiconDoc<'static> {
        lexicon_doc_dev_keytrace_claim()
    }
    fn validate(&self) -> Result<(), ConstraintError> {
        if let Some(ref value) = self.comment {
            #[allow(unused_comparisons)]
            if <str>::len(value.as_ref()) > 256usize {
                return Err(ConstraintError::MaxLength {
                    path: ValidationPath::from_field("comment"),
                    max: 256usize,
                    actual: <str>::len(value.as_ref()),
                });
            }
        }
        if let Some(ref value) = self.nonce {
            {
                let count = UnicodeSegmentation::graphemes(value.as_ref(), true).count();
                if count > 128usize {
                    return Err(ConstraintError::MaxGraphemes {
                        path: ValidationPath::from_field("nonce"),
                        max: 128usize,
                        actual: count,
                    });
                }
            }
        }
        Ok(())
    }
}

fn lexicon_doc_dev_keytrace_claim() -> 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("dev.keytrace.claim"),
        defs: {
            let mut map = BTreeMap::new();
            map.insert(
                SmolStr::new_static("identity"),
                LexUserType::Object(LexObject {
                    description: Some(
                        CowStr::new_static(
                            "Generic identity data for the claimed account",
                        ),
                    ),
                    required: Some(vec![SmolStr::new_static("subject")]),
                    properties: {
                        #[allow(unused_mut)]
                        let mut map = BTreeMap::new();
                        map.insert(
                            SmolStr::new_static("avatarUrl"),
                            LexObjectProperty::String(LexString {
                                description: Some(
                                    CowStr::new_static("Avatar/profile image URL"),
                                ),
                                format: Some(LexStringFormat::Uri),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("displayName"),
                            LexObjectProperty::String(LexString {
                                description: Some(
                                    CowStr::new_static("Display name if different from subject"),
                                ),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("profileUrl"),
                            LexObjectProperty::String(LexString {
                                description: Some(CowStr::new_static("Profile page URL")),
                                format: Some(LexStringFormat::Uri),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("subject"),
                            LexObjectProperty::String(LexString {
                                description: Some(
                                    CowStr::new_static(
                                        "Primary identifier (username, domain, handle, etc.)",
                                    ),
                                ),
                                ..Default::default()
                            }),
                        );
                        map
                    },
                    ..Default::default()
                }),
            );
            map.insert(
                SmolStr::new_static("main"),
                LexUserType::Record(LexRecord {
                    description: Some(
                        CowStr::new_static(
                            "An identity claim linking this DID to an external account",
                        ),
                    ),
                    key: Some(CowStr::new_static("tid")),
                    record: LexRecordRecord::Object(LexObject {
                        required: Some(
                            vec![
                                SmolStr::new_static("type"),
                                SmolStr::new_static("claimUri"),
                                SmolStr::new_static("identity"),
                                SmolStr::new_static("sigs"),
                                SmolStr::new_static("createdAt")
                            ],
                        ),
                        properties: {
                            #[allow(unused_mut)]
                            let mut map = BTreeMap::new();
                            map.insert(
                                SmolStr::new_static("claimUri"),
                                LexObjectProperty::String(LexString {
                                    description: Some(
                                        CowStr::new_static(
                                            "The identity claim URI (e.g., for github: https://gist.github.com/username/id, dns:example.com)",
                                        ),
                                    ),
                                    ..Default::default()
                                }),
                            );
                            map.insert(
                                SmolStr::new_static("comment"),
                                LexObjectProperty::String(LexString {
                                    description: Some(
                                        CowStr::new_static(
                                            "Optional user-provided label for this claim",
                                        ),
                                    ),
                                    max_length: Some(256usize),
                                    ..Default::default()
                                }),
                            );
                            map.insert(
                                SmolStr::new_static("createdAt"),
                                LexObjectProperty::String(LexString {
                                    description: Some(
                                        CowStr::new_static(
                                            "Datetime when this claim was created (ISO 8601).",
                                        ),
                                    ),
                                    format: Some(LexStringFormat::Datetime),
                                    ..Default::default()
                                }),
                            );
                            map.insert(
                                SmolStr::new_static("failedAt"),
                                LexObjectProperty::String(LexString {
                                    description: Some(
                                        CowStr::new_static(
                                            "Timestamp when the claim last failed re-verification or was retracted",
                                        ),
                                    ),
                                    format: Some(LexStringFormat::Datetime),
                                    ..Default::default()
                                }),
                            );
                            map.insert(
                                SmolStr::new_static("identity"),
                                LexObjectProperty::Ref(LexRef {
                                    r#ref: CowStr::new_static("#identity"),
                                    ..Default::default()
                                }),
                            );
                            map.insert(
                                SmolStr::new_static("lastVerifiedAt"),
                                LexObjectProperty::String(LexString {
                                    description: Some(
                                        CowStr::new_static(
                                            "Timestamp of the most recent successful re-verification by the system",
                                        ),
                                    ),
                                    format: Some(LexStringFormat::Datetime),
                                    ..Default::default()
                                }),
                            );
                            map.insert(
                                SmolStr::new_static("nonce"),
                                LexObjectProperty::String(LexString {
                                    description: Some(
                                        CowStr::new_static(
                                            "Random one-time value embedded in the challenge text posted to the external service. Used by verifiers to confirm the proof was created specifically for this claim session. Keytrace itself does not use this, but other services making claims may require it for their verification process.",
                                        ),
                                    ),
                                    max_graphemes: Some(128usize),
                                    ..Default::default()
                                }),
                            );
                            map.insert(
                                SmolStr::new_static("prerelease"),
                                LexObjectProperty::Boolean(LexBoolean {
                                    ..Default::default()
                                }),
                            );
                            map.insert(
                                SmolStr::new_static("retractedAt"),
                                LexObjectProperty::String(LexString {
                                    description: Some(
                                        CowStr::new_static(
                                            "Datetime when this claim was retracted. Present only if the claim has been retracted (ISO 8601).",
                                        ),
                                    ),
                                    format: Some(LexStringFormat::Datetime),
                                    ..Default::default()
                                }),
                            );
                            map.insert(
                                SmolStr::new_static("sigs"),
                                LexObjectProperty::Array(LexArray {
                                    description: Some(
                                        CowStr::new_static(
                                            "Cryptographic attestation signatures from verification services, for example from @keytrace.dev. These are optional, and so you can pass an empty array. Keytrace will place its attestation signature in the claim here so that the library @keytrace/claims can be used by external developers to not have to implement their own verification logic.",
                                        ),
                                    ),
                                    items: LexArrayItem::Ref(LexRef {
                                        r#ref: CowStr::new_static("dev.keytrace.signature#main"),
                                        ..Default::default()
                                    }),
                                    ..Default::default()
                                }),
                            );
                            map.insert(
                                SmolStr::new_static("status"),
                                LexObjectProperty::String(LexString {
                                    description: Some(
                                        CowStr::new_static(
                                            "Current verification status of this claim. Absent on legacy records, treated as 'verified'.",
                                        ),
                                    ),
                                    ..Default::default()
                                }),
                            );
                            map.insert(
                                SmolStr::new_static("type"),
                                LexObjectProperty::String(LexString {
                                    description: Some(
                                        CowStr::new_static("The claim type identifier"),
                                    ),
                                    ..Default::default()
                                }),
                            );
                            map
                        },
                        ..Default::default()
                    }),
                    ..Default::default()
                }),
            );
            map
        },
        ..Default::default()
    }
}

pub mod claim_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 ClaimUri;
        type CreatedAt;
        type Identity;
        type Sigs;
        type Type;
    }
    /// Empty state - all required fields are unset
    pub struct Empty(());
    impl sealed::Sealed for Empty {}
    impl State for Empty {
        type ClaimUri = Unset;
        type CreatedAt = Unset;
        type Identity = Unset;
        type Sigs = Unset;
        type Type = Unset;
    }
    ///State transition - sets the `claim_uri` field to Set
    pub struct SetClaimUri<St: State = Empty>(PhantomData<fn() -> St>);
    impl<St: State> sealed::Sealed for SetClaimUri<St> {}
    impl<St: State> State for SetClaimUri<St> {
        type ClaimUri = Set<members::claim_uri>;
        type CreatedAt = St::CreatedAt;
        type Identity = St::Identity;
        type Sigs = St::Sigs;
        type Type = St::Type;
    }
    ///State transition - sets the `created_at` field to Set
    pub struct SetCreatedAt<St: State = Empty>(PhantomData<fn() -> St>);
    impl<St: State> sealed::Sealed for SetCreatedAt<St> {}
    impl<St: State> State for SetCreatedAt<St> {
        type ClaimUri = St::ClaimUri;
        type CreatedAt = Set<members::created_at>;
        type Identity = St::Identity;
        type Sigs = St::Sigs;
        type Type = St::Type;
    }
    ///State transition - sets the `identity` field to Set
    pub struct SetIdentity<St: State = Empty>(PhantomData<fn() -> St>);
    impl<St: State> sealed::Sealed for SetIdentity<St> {}
    impl<St: State> State for SetIdentity<St> {
        type ClaimUri = St::ClaimUri;
        type CreatedAt = St::CreatedAt;
        type Identity = Set<members::identity>;
        type Sigs = St::Sigs;
        type Type = St::Type;
    }
    ///State transition - sets the `sigs` field to Set
    pub struct SetSigs<St: State = Empty>(PhantomData<fn() -> St>);
    impl<St: State> sealed::Sealed for SetSigs<St> {}
    impl<St: State> State for SetSigs<St> {
        type ClaimUri = St::ClaimUri;
        type CreatedAt = St::CreatedAt;
        type Identity = St::Identity;
        type Sigs = Set<members::sigs>;
        type Type = St::Type;
    }
    ///State transition - sets the `type` field to Set
    pub struct SetType<St: State = Empty>(PhantomData<fn() -> St>);
    impl<St: State> sealed::Sealed for SetType<St> {}
    impl<St: State> State for SetType<St> {
        type ClaimUri = St::ClaimUri;
        type CreatedAt = St::CreatedAt;
        type Identity = St::Identity;
        type Sigs = St::Sigs;
        type Type = Set<members::r#type>;
    }
    /// Marker types for field names
    #[allow(non_camel_case_types)]
    pub mod members {
        ///Marker type for the `claim_uri` field
        pub struct claim_uri(());
        ///Marker type for the `created_at` field
        pub struct created_at(());
        ///Marker type for the `identity` field
        pub struct identity(());
        ///Marker type for the `sigs` field
        pub struct sigs(());
        ///Marker type for the `type` field
        pub struct r#type(());
    }
}

/// Builder for constructing an instance of this type.
pub struct ClaimBuilder<St: claim_state::State, S: BosStr = DefaultStr> {
    _state: PhantomData<fn() -> St>,
    _fields: (
        Option<S>,
        Option<S>,
        Option<Datetime>,
        Option<Datetime>,
        Option<claim::Identity<S>>,
        Option<Datetime>,
        Option<S>,
        Option<bool>,
        Option<Datetime>,
        Option<Vec<Signature<S>>>,
        Option<ClaimStatus<S>>,
        Option<ClaimType<S>>,
    ),
    _type: PhantomData<fn() -> S>,
}

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

impl<S: BosStr> Claim<S> {
    /// Create a new builder for this type
    pub fn builder() -> ClaimBuilder<claim_state::Empty, S> {
        ClaimBuilder::builder()
    }
}

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

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

impl<St, S: BosStr> ClaimBuilder<St, S>
where
    St: claim_state::State,
    St::ClaimUri: claim_state::IsUnset,
{
    /// Set the `claimUri` field (required)
    pub fn claim_uri(
        mut self,
        value: impl Into<S>,
    ) -> ClaimBuilder<claim_state::SetClaimUri<St>, S> {
        self._fields.0 = Option::Some(value.into());
        ClaimBuilder {
            _state: PhantomData,
            _fields: self._fields,
            _type: PhantomData,
        }
    }
}

impl<St: claim_state::State, S: BosStr> ClaimBuilder<St, S> {
    /// Set the `comment` field (optional)
    pub fn comment(mut self, value: impl Into<Option<S>>) -> Self {
        self._fields.1 = value.into();
        self
    }
    /// Set the `comment` field to an Option value (optional)
    pub fn maybe_comment(mut self, value: Option<S>) -> Self {
        self._fields.1 = value;
        self
    }
}

impl<St, S: BosStr> ClaimBuilder<St, S>
where
    St: claim_state::State,
    St::CreatedAt: claim_state::IsUnset,
{
    /// Set the `createdAt` field (required)
    pub fn created_at(
        mut self,
        value: impl Into<Datetime>,
    ) -> ClaimBuilder<claim_state::SetCreatedAt<St>, S> {
        self._fields.2 = Option::Some(value.into());
        ClaimBuilder {
            _state: PhantomData,
            _fields: self._fields,
            _type: PhantomData,
        }
    }
}

impl<St: claim_state::State, S: BosStr> ClaimBuilder<St, S> {
    /// Set the `failedAt` field (optional)
    pub fn failed_at(mut self, value: impl Into<Option<Datetime>>) -> Self {
        self._fields.3 = value.into();
        self
    }
    /// Set the `failedAt` field to an Option value (optional)
    pub fn maybe_failed_at(mut self, value: Option<Datetime>) -> Self {
        self._fields.3 = value;
        self
    }
}

impl<St, S: BosStr> ClaimBuilder<St, S>
where
    St: claim_state::State,
    St::Identity: claim_state::IsUnset,
{
    /// Set the `identity` field (required)
    pub fn identity(
        mut self,
        value: impl Into<claim::Identity<S>>,
    ) -> ClaimBuilder<claim_state::SetIdentity<St>, S> {
        self._fields.4 = Option::Some(value.into());
        ClaimBuilder {
            _state: PhantomData,
            _fields: self._fields,
            _type: PhantomData,
        }
    }
}

impl<St: claim_state::State, S: BosStr> ClaimBuilder<St, S> {
    /// Set the `lastVerifiedAt` field (optional)
    pub fn last_verified_at(mut self, value: impl Into<Option<Datetime>>) -> Self {
        self._fields.5 = value.into();
        self
    }
    /// Set the `lastVerifiedAt` field to an Option value (optional)
    pub fn maybe_last_verified_at(mut self, value: Option<Datetime>) -> Self {
        self._fields.5 = value;
        self
    }
}

impl<St: claim_state::State, S: BosStr> ClaimBuilder<St, S> {
    /// Set the `nonce` field (optional)
    pub fn nonce(mut self, value: impl Into<Option<S>>) -> Self {
        self._fields.6 = value.into();
        self
    }
    /// Set the `nonce` field to an Option value (optional)
    pub fn maybe_nonce(mut self, value: Option<S>) -> Self {
        self._fields.6 = value;
        self
    }
}

impl<St: claim_state::State, S: BosStr> ClaimBuilder<St, S> {
    /// Set the `prerelease` field (optional)
    pub fn prerelease(mut self, value: impl Into<Option<bool>>) -> Self {
        self._fields.7 = value.into();
        self
    }
    /// Set the `prerelease` field to an Option value (optional)
    pub fn maybe_prerelease(mut self, value: Option<bool>) -> Self {
        self._fields.7 = value;
        self
    }
}

impl<St: claim_state::State, S: BosStr> ClaimBuilder<St, S> {
    /// Set the `retractedAt` field (optional)
    pub fn retracted_at(mut self, value: impl Into<Option<Datetime>>) -> Self {
        self._fields.8 = value.into();
        self
    }
    /// Set the `retractedAt` field to an Option value (optional)
    pub fn maybe_retracted_at(mut self, value: Option<Datetime>) -> Self {
        self._fields.8 = value;
        self
    }
}

impl<St, S: BosStr> ClaimBuilder<St, S>
where
    St: claim_state::State,
    St::Sigs: claim_state::IsUnset,
{
    /// Set the `sigs` field (required)
    pub fn sigs(
        mut self,
        value: impl Into<Vec<Signature<S>>>,
    ) -> ClaimBuilder<claim_state::SetSigs<St>, S> {
        self._fields.9 = Option::Some(value.into());
        ClaimBuilder {
            _state: PhantomData,
            _fields: self._fields,
            _type: PhantomData,
        }
    }
}

impl<St: claim_state::State, S: BosStr> ClaimBuilder<St, S> {
    /// Set the `status` field (optional)
    pub fn status(mut self, value: impl Into<Option<ClaimStatus<S>>>) -> Self {
        self._fields.10 = value.into();
        self
    }
    /// Set the `status` field to an Option value (optional)
    pub fn maybe_status(mut self, value: Option<ClaimStatus<S>>) -> Self {
        self._fields.10 = value;
        self
    }
}

impl<St, S: BosStr> ClaimBuilder<St, S>
where
    St: claim_state::State,
    St::Type: claim_state::IsUnset,
{
    /// Set the `type` field (required)
    pub fn r#type(
        mut self,
        value: impl Into<ClaimType<S>>,
    ) -> ClaimBuilder<claim_state::SetType<St>, S> {
        self._fields.11 = Option::Some(value.into());
        ClaimBuilder {
            _state: PhantomData,
            _fields: self._fields,
            _type: PhantomData,
        }
    }
}

impl<St, S: BosStr> ClaimBuilder<St, S>
where
    St: claim_state::State,
    St::ClaimUri: claim_state::IsSet,
    St::CreatedAt: claim_state::IsSet,
    St::Identity: claim_state::IsSet,
    St::Sigs: claim_state::IsSet,
    St::Type: claim_state::IsSet,
{
    /// Build the final struct.
    pub fn build(self) -> Claim<S> {
        Claim {
            claim_uri: self._fields.0.unwrap(),
            comment: self._fields.1,
            created_at: self._fields.2.unwrap(),
            failed_at: self._fields.3,
            identity: self._fields.4.unwrap(),
            last_verified_at: self._fields.5,
            nonce: self._fields.6,
            prerelease: self._fields.7,
            retracted_at: self._fields.8,
            sigs: self._fields.9.unwrap(),
            status: self._fields.10,
            r#type: self._fields.11.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>>) -> Claim<S> {
        Claim {
            claim_uri: self._fields.0.unwrap(),
            comment: self._fields.1,
            created_at: self._fields.2.unwrap(),
            failed_at: self._fields.3,
            identity: self._fields.4.unwrap(),
            last_verified_at: self._fields.5,
            nonce: self._fields.6,
            prerelease: self._fields.7,
            retracted_at: self._fields.8,
            sigs: self._fields.9.unwrap(),
            status: self._fields.10,
            r#type: self._fields.11.unwrap(),
            extra_data: Some(extra_data),
        }
    }
}