// @generated by jacquard-lexicon. DO NOT EDIT.
//
// Lexicon: world.ptah.temp.location
//
// 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::{Did, AtUri, Cid, Datetime};
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::world_ptah::temp::location;
/// Flexible properties for any kind of world geography. All fields optional — worlds define what matters.

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic, Default)]
#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))]
pub struct LocationProperties<S: BosStr = DefaultStr> {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub climate: Option<S>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub controlling_faction: Option<S>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub notable_history: Option<S>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub population: Option<S>,
    #[serde(flatten, default, skip_serializing_if = "Option::is_none")]
    pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,
}

/// A pin dropped on a map that does not exist yet. The pin creates the place. Hwt-ka-Ptah — the House of the Ka of Ptah — gave Egypt its name. A place becomes so significant that it names everything around it.

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
#[serde(
    rename_all = "camelCase",
    rename = "world.ptah.temp.location",
    tag = "$type",
    bound(deserialize = "S: Deserialize<'de> + BosStr")
)]
pub struct Location<S: BosStr = DefaultStr> {
    ///Permanent link to the creator. Provenance travels.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub authorship_record: Option<Did<S>>,
    ///The canonical standing of this location within its world.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub canonical_status: Option<LocationCanonicalStatus<S>>,
    ///Timestamp of location creation.
    pub created_at: Datetime,
    ///Who named and defined this place.
    pub creator_did: Did<S>,
    ///How deep in the geographic hierarchy this location sits. World-level is 0, continent is 1, country is 2, city is 3, and so on. Any rendering layer can read this single number and decide how much geographic context it needs without traversing the full parent chain.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub depth_index: Option<i64>,
    ///What kind of place this is, in plain language.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub description: Option<S>,
    ///The geographic or spatial classification. Open-ended so any kind of world geography works.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub location_type: Option<LocationLocationType<S>>,
    ///What this place is called.
    pub name: S,
    ///If this location exists inside a larger location — a tavern inside a city, a room inside a building. Lets geography nest infinitely. Places come into existence as people need them.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub parent_location: Option<AtUri<S>>,
    ///Flexible fields — climate, population, controlling faction, notable history. Whatever the world requires.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub properties: Option<location::LocationProperties<S>>,
    ///The AT URI of the world this location exists in.
    pub world_reference: AtUri<S>,
    #[serde(flatten, default, skip_serializing_if = "Option::is_none")]
    pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,
}

/// The canonical standing of this location within its world.

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum LocationCanonicalStatus<S: BosStr = DefaultStr> {
    CanonicalStatusOfficial,
    CanonicalStatusCommunity,
    CanonicalStatusApocryphal,
    Other(S),
}

impl<S: BosStr> LocationCanonicalStatus<S> {
    pub fn as_str(&self) -> &str {
        match self {
            Self::CanonicalStatusOfficial => {
                "world.ptah.temp.defs#canonicalStatusOfficial"
            }
            Self::CanonicalStatusCommunity => {
                "world.ptah.temp.defs#canonicalStatusCommunity"
            }
            Self::CanonicalStatusApocryphal => {
                "world.ptah.temp.defs#canonicalStatusApocryphal"
            }
            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() {
            "world.ptah.temp.defs#canonicalStatusOfficial" => {
                Self::CanonicalStatusOfficial
            }
            "world.ptah.temp.defs#canonicalStatusCommunity" => {
                Self::CanonicalStatusCommunity
            }
            "world.ptah.temp.defs#canonicalStatusApocryphal" => {
                Self::CanonicalStatusApocryphal
            }
            _ => Self::Other(s),
        }
    }
}

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

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

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

impl<S: BosStr> jacquard_common::IntoStatic for LocationCanonicalStatus<S>
where
    S: BosStr + jacquard_common::IntoStatic,
    S::Output: BosStr,
{
    type Output = LocationCanonicalStatus<S::Output>;
    fn into_static(self) -> Self::Output {
        match self {
            LocationCanonicalStatus::CanonicalStatusOfficial => {
                LocationCanonicalStatus::CanonicalStatusOfficial
            }
            LocationCanonicalStatus::CanonicalStatusCommunity => {
                LocationCanonicalStatus::CanonicalStatusCommunity
            }
            LocationCanonicalStatus::CanonicalStatusApocryphal => {
                LocationCanonicalStatus::CanonicalStatusApocryphal
            }
            LocationCanonicalStatus::Other(v) => {
                LocationCanonicalStatus::Other(v.into_static())
            }
        }
    }
}

/// The geographic or spatial classification. Open-ended so any kind of world geography works.

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum LocationLocationType<S: BosStr = DefaultStr> {
    City,
    Region,
    Building,
    Territory,
    Landmark,
    Vessel,
    AbstractSpace,
    Other(S),
}

impl<S: BosStr> LocationLocationType<S> {
    pub fn as_str(&self) -> &str {
        match self {
            Self::City => "city",
            Self::Region => "region",
            Self::Building => "building",
            Self::Territory => "territory",
            Self::Landmark => "landmark",
            Self::Vessel => "vessel",
            Self::AbstractSpace => "abstractSpace",
            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() {
            "city" => Self::City,
            "region" => Self::Region,
            "building" => Self::Building,
            "territory" => Self::Territory,
            "landmark" => Self::Landmark,
            "vessel" => Self::Vessel,
            "abstractSpace" => Self::AbstractSpace,
            _ => Self::Other(s),
        }
    }
}

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

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

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

impl<S: BosStr> jacquard_common::IntoStatic for LocationLocationType<S>
where
    S: BosStr + jacquard_common::IntoStatic,
    S::Output: BosStr,
{
    type Output = LocationLocationType<S::Output>;
    fn into_static(self) -> Self::Output {
        match self {
            LocationLocationType::City => LocationLocationType::City,
            LocationLocationType::Region => LocationLocationType::Region,
            LocationLocationType::Building => LocationLocationType::Building,
            LocationLocationType::Territory => LocationLocationType::Territory,
            LocationLocationType::Landmark => LocationLocationType::Landmark,
            LocationLocationType::Vessel => LocationLocationType::Vessel,
            LocationLocationType::AbstractSpace => LocationLocationType::AbstractSpace,
            LocationLocationType::Other(v) => {
                LocationLocationType::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 LocationGetRecordOutput<S: BosStr = DefaultStr> {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub cid: Option<Cid<S>>,
    pub uri: AtUri<S>,
    pub value: Location<S>,
}

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

impl<S: BosStr> LexiconSchema for LocationProperties<S> {
    fn nsid() -> &'static str {
        "world.ptah.temp.location"
    }
    fn def_name() -> &'static str {
        "locationProperties"
    }
    fn lexicon_doc() -> LexiconDoc<'static> {
        lexicon_doc_world_ptah_temp_location()
    }
    fn validate(&self) -> Result<(), ConstraintError> {
        if let Some(ref value) = self.climate {
            #[allow(unused_comparisons)]
            if <str>::len(value.as_ref()) > 2560usize {
                return Err(ConstraintError::MaxLength {
                    path: ValidationPath::from_field("climate"),
                    max: 2560usize,
                    actual: <str>::len(value.as_ref()),
                });
            }
        }
        if let Some(ref value) = self.climate {
            {
                let count = UnicodeSegmentation::graphemes(value.as_ref(), true).count();
                if count > 256usize {
                    return Err(ConstraintError::MaxGraphemes {
                        path: ValidationPath::from_field("climate"),
                        max: 256usize,
                        actual: count,
                    });
                }
            }
        }
        if let Some(ref value) = self.controlling_faction {
            #[allow(unused_comparisons)]
            if <str>::len(value.as_ref()) > 2560usize {
                return Err(ConstraintError::MaxLength {
                    path: ValidationPath::from_field("controlling_faction"),
                    max: 2560usize,
                    actual: <str>::len(value.as_ref()),
                });
            }
        }
        if let Some(ref value) = self.controlling_faction {
            {
                let count = UnicodeSegmentation::graphemes(value.as_ref(), true).count();
                if count > 256usize {
                    return Err(ConstraintError::MaxGraphemes {
                        path: ValidationPath::from_field("controlling_faction"),
                        max: 256usize,
                        actual: count,
                    });
                }
            }
        }
        if let Some(ref value) = self.notable_history {
            #[allow(unused_comparisons)]
            if <str>::len(value.as_ref()) > 10240usize {
                return Err(ConstraintError::MaxLength {
                    path: ValidationPath::from_field("notable_history"),
                    max: 10240usize,
                    actual: <str>::len(value.as_ref()),
                });
            }
        }
        if let Some(ref value) = self.notable_history {
            {
                let count = UnicodeSegmentation::graphemes(value.as_ref(), true).count();
                if count > 1024usize {
                    return Err(ConstraintError::MaxGraphemes {
                        path: ValidationPath::from_field("notable_history"),
                        max: 1024usize,
                        actual: count,
                    });
                }
            }
        }
        if let Some(ref value) = self.population {
            #[allow(unused_comparisons)]
            if <str>::len(value.as_ref()) > 2560usize {
                return Err(ConstraintError::MaxLength {
                    path: ValidationPath::from_field("population"),
                    max: 2560usize,
                    actual: <str>::len(value.as_ref()),
                });
            }
        }
        if let Some(ref value) = self.population {
            {
                let count = UnicodeSegmentation::graphemes(value.as_ref(), true).count();
                if count > 256usize {
                    return Err(ConstraintError::MaxGraphemes {
                        path: ValidationPath::from_field("population"),
                        max: 256usize,
                        actual: count,
                    });
                }
            }
        }
        Ok(())
    }
}

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

#[derive(Debug, Serialize, Deserialize)]
pub struct LocationRecord;
impl XrpcResp for LocationRecord {
    const NSID: &'static str = "world.ptah.temp.location";
    const ENCODING: &'static str = "application/json";
    type Output<S: BosStr> = LocationGetRecordOutput<S>;
    type Err = RecordError;
}

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

impl<S: BosStr> Collection for Location<S> {
    const NSID: &'static str = "world.ptah.temp.location";
    type Record = LocationRecord;
}

impl Collection for LocationRecord {
    const NSID: &'static str = "world.ptah.temp.location";
    type Record = LocationRecord;
}

impl<S: BosStr> LexiconSchema for Location<S> {
    fn nsid() -> &'static str {
        "world.ptah.temp.location"
    }
    fn def_name() -> &'static str {
        "main"
    }
    fn lexicon_doc() -> LexiconDoc<'static> {
        lexicon_doc_world_ptah_temp_location()
    }
    fn validate(&self) -> Result<(), ConstraintError> {
        if let Some(ref value) = self.depth_index {
            if *value < 0i64 {
                return Err(ConstraintError::Minimum {
                    path: ValidationPath::from_field("depth_index"),
                    min: 0i64,
                    actual: *value,
                });
            }
        }
        if let Some(ref value) = self.description {
            #[allow(unused_comparisons)]
            if <str>::len(value.as_ref()) > 10240usize {
                return Err(ConstraintError::MaxLength {
                    path: ValidationPath::from_field("description"),
                    max: 10240usize,
                    actual: <str>::len(value.as_ref()),
                });
            }
        }
        if let Some(ref value) = self.description {
            {
                let count = UnicodeSegmentation::graphemes(value.as_ref(), true).count();
                if count > 1024usize {
                    return Err(ConstraintError::MaxGraphemes {
                        path: ValidationPath::from_field("description"),
                        max: 1024usize,
                        actual: count,
                    });
                }
            }
        }
        if let Some(ref value) = self.location_type {
            #[allow(unused_comparisons)]
            if <str>::len(value.as_ref()) > 640usize {
                return Err(ConstraintError::MaxLength {
                    path: ValidationPath::from_field("location_type"),
                    max: 640usize,
                    actual: <str>::len(value.as_ref()),
                });
            }
        }
        if let Some(ref value) = self.location_type {
            {
                let count = UnicodeSegmentation::graphemes(value.as_ref(), true).count();
                if count > 64usize {
                    return Err(ConstraintError::MaxGraphemes {
                        path: ValidationPath::from_field("location_type"),
                        max: 64usize,
                        actual: count,
                    });
                }
            }
        }
        {
            let value = &self.name;
            #[allow(unused_comparisons)]
            if <str>::len(value.as_ref()) > 640usize {
                return Err(ConstraintError::MaxLength {
                    path: ValidationPath::from_field("name"),
                    max: 640usize,
                    actual: <str>::len(value.as_ref()),
                });
            }
        }
        {
            let value = &self.name;
            {
                let count = UnicodeSegmentation::graphemes(value.as_ref(), true).count();
                if count > 64usize {
                    return Err(ConstraintError::MaxGraphemes {
                        path: ValidationPath::from_field("name"),
                        max: 64usize,
                        actual: count,
                    });
                }
            }
        }
        Ok(())
    }
}

fn lexicon_doc_world_ptah_temp_location() -> 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("world.ptah.temp.location"),
        defs: {
            let mut map = BTreeMap::new();
            map.insert(
                SmolStr::new_static("locationProperties"),
                LexUserType::Object(LexObject {
                    description: Some(
                        CowStr::new_static(
                            "Flexible properties for any kind of world geography. All fields optional — worlds define what matters.",
                        ),
                    ),
                    properties: {
                        #[allow(unused_mut)]
                        let mut map = BTreeMap::new();
                        map.insert(
                            SmolStr::new_static("climate"),
                            LexObjectProperty::String(LexString {
                                max_length: Some(2560usize),
                                max_graphemes: Some(256usize),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("controllingFaction"),
                            LexObjectProperty::String(LexString {
                                max_length: Some(2560usize),
                                max_graphemes: Some(256usize),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("notableHistory"),
                            LexObjectProperty::String(LexString {
                                max_length: Some(10240usize),
                                max_graphemes: Some(1024usize),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("population"),
                            LexObjectProperty::String(LexString {
                                max_length: Some(2560usize),
                                max_graphemes: Some(256usize),
                                ..Default::default()
                            }),
                        );
                        map
                    },
                    ..Default::default()
                }),
            );
            map.insert(
                SmolStr::new_static("main"),
                LexUserType::Record(LexRecord {
                    description: Some(
                        CowStr::new_static(
                            "A pin dropped on a map that does not exist yet. The pin creates the place. Hwt-ka-Ptah — the House of the Ka of Ptah — gave Egypt its name. A place becomes so significant that it names everything around it.",
                        ),
                    ),
                    key: Some(CowStr::new_static("tid")),
                    record: LexRecordRecord::Object(LexObject {
                        required: Some(
                            vec![
                                SmolStr::new_static("name"),
                                SmolStr::new_static("creatorDID"),
                                SmolStr::new_static("worldReference"),
                                SmolStr::new_static("createdAt")
                            ],
                        ),
                        properties: {
                            #[allow(unused_mut)]
                            let mut map = BTreeMap::new();
                            map.insert(
                                SmolStr::new_static("authorshipRecord"),
                                LexObjectProperty::String(LexString {
                                    description: Some(
                                        CowStr::new_static(
                                            "Permanent link to the creator. Provenance travels.",
                                        ),
                                    ),
                                    format: Some(LexStringFormat::Did),
                                    ..Default::default()
                                }),
                            );
                            map.insert(
                                SmolStr::new_static("canonicalStatus"),
                                LexObjectProperty::String(LexString {
                                    description: Some(
                                        CowStr::new_static(
                                            "The canonical standing of this location within its world.",
                                        ),
                                    ),
                                    ..Default::default()
                                }),
                            );
                            map.insert(
                                SmolStr::new_static("createdAt"),
                                LexObjectProperty::String(LexString {
                                    description: Some(
                                        CowStr::new_static("Timestamp of location creation."),
                                    ),
                                    format: Some(LexStringFormat::Datetime),
                                    ..Default::default()
                                }),
                            );
                            map.insert(
                                SmolStr::new_static("creatorDID"),
                                LexObjectProperty::String(LexString {
                                    description: Some(
                                        CowStr::new_static("Who named and defined this place."),
                                    ),
                                    format: Some(LexStringFormat::Did),
                                    ..Default::default()
                                }),
                            );
                            map.insert(
                                SmolStr::new_static("depthIndex"),
                                LexObjectProperty::Integer(LexInteger {
                                    minimum: Some(0i64),
                                    ..Default::default()
                                }),
                            );
                            map.insert(
                                SmolStr::new_static("description"),
                                LexObjectProperty::String(LexString {
                                    description: Some(
                                        CowStr::new_static(
                                            "What kind of place this is, in plain language.",
                                        ),
                                    ),
                                    max_length: Some(10240usize),
                                    max_graphemes: Some(1024usize),
                                    ..Default::default()
                                }),
                            );
                            map.insert(
                                SmolStr::new_static("locationType"),
                                LexObjectProperty::String(LexString {
                                    description: Some(
                                        CowStr::new_static(
                                            "The geographic or spatial classification. Open-ended so any kind of world geography works.",
                                        ),
                                    ),
                                    max_length: Some(640usize),
                                    max_graphemes: Some(64usize),
                                    ..Default::default()
                                }),
                            );
                            map.insert(
                                SmolStr::new_static("name"),
                                LexObjectProperty::String(LexString {
                                    description: Some(
                                        CowStr::new_static("What this place is called."),
                                    ),
                                    max_length: Some(640usize),
                                    max_graphemes: Some(64usize),
                                    ..Default::default()
                                }),
                            );
                            map.insert(
                                SmolStr::new_static("parentLocation"),
                                LexObjectProperty::String(LexString {
                                    description: Some(
                                        CowStr::new_static(
                                            "If this location exists inside a larger location — a tavern inside a city, a room inside a building. Lets geography nest infinitely. Places come into existence as people need them.",
                                        ),
                                    ),
                                    format: Some(LexStringFormat::AtUri),
                                    ..Default::default()
                                }),
                            );
                            map.insert(
                                SmolStr::new_static("properties"),
                                LexObjectProperty::Ref(LexRef {
                                    r#ref: CowStr::new_static("#locationProperties"),
                                    ..Default::default()
                                }),
                            );
                            map.insert(
                                SmolStr::new_static("worldReference"),
                                LexObjectProperty::String(LexString {
                                    description: Some(
                                        CowStr::new_static(
                                            "The AT URI of the world this location exists in.",
                                        ),
                                    ),
                                    format: Some(LexStringFormat::AtUri),
                                    ..Default::default()
                                }),
                            );
                            map
                        },
                        ..Default::default()
                    }),
                    ..Default::default()
                }),
            );
            map
        },
        ..Default::default()
    }
}

pub mod location_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 CreatedAt;
        type CreatorDid;
        type Name;
        type WorldReference;
    }
    /// Empty state - all required fields are unset
    pub struct Empty(());
    impl sealed::Sealed for Empty {}
    impl State for Empty {
        type CreatedAt = Unset;
        type CreatorDid = Unset;
        type Name = Unset;
        type WorldReference = Unset;
    }
    ///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 CreatedAt = Set<members::created_at>;
        type CreatorDid = St::CreatorDid;
        type Name = St::Name;
        type WorldReference = St::WorldReference;
    }
    ///State transition - sets the `creator_did` field to Set
    pub struct SetCreatorDid<St: State = Empty>(PhantomData<fn() -> St>);
    impl<St: State> sealed::Sealed for SetCreatorDid<St> {}
    impl<St: State> State for SetCreatorDid<St> {
        type CreatedAt = St::CreatedAt;
        type CreatorDid = Set<members::creator_did>;
        type Name = St::Name;
        type WorldReference = St::WorldReference;
    }
    ///State transition - sets the `name` field to Set
    pub struct SetName<St: State = Empty>(PhantomData<fn() -> St>);
    impl<St: State> sealed::Sealed for SetName<St> {}
    impl<St: State> State for SetName<St> {
        type CreatedAt = St::CreatedAt;
        type CreatorDid = St::CreatorDid;
        type Name = Set<members::name>;
        type WorldReference = St::WorldReference;
    }
    ///State transition - sets the `world_reference` field to Set
    pub struct SetWorldReference<St: State = Empty>(PhantomData<fn() -> St>);
    impl<St: State> sealed::Sealed for SetWorldReference<St> {}
    impl<St: State> State for SetWorldReference<St> {
        type CreatedAt = St::CreatedAt;
        type CreatorDid = St::CreatorDid;
        type Name = St::Name;
        type WorldReference = Set<members::world_reference>;
    }
    /// Marker types for field names
    #[allow(non_camel_case_types)]
    pub mod members {
        ///Marker type for the `created_at` field
        pub struct created_at(());
        ///Marker type for the `creator_did` field
        pub struct creator_did(());
        ///Marker type for the `name` field
        pub struct name(());
        ///Marker type for the `world_reference` field
        pub struct world_reference(());
    }
}

/// Builder for constructing an instance of this type.
pub struct LocationBuilder<St: location_state::State, S: BosStr = DefaultStr> {
    _state: PhantomData<fn() -> St>,
    _fields: (
        Option<Did<S>>,
        Option<LocationCanonicalStatus<S>>,
        Option<Datetime>,
        Option<Did<S>>,
        Option<i64>,
        Option<S>,
        Option<LocationLocationType<S>>,
        Option<S>,
        Option<AtUri<S>>,
        Option<location::LocationProperties<S>>,
        Option<AtUri<S>>,
    ),
    _type: PhantomData<fn() -> S>,
}

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

impl<S: BosStr> Location<S> {
    /// Create a new builder for this type
    pub fn builder() -> LocationBuilder<location_state::Empty, S> {
        LocationBuilder::builder()
    }
}

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

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

impl<St: location_state::State, S: BosStr> LocationBuilder<St, S> {
    /// Set the `authorshipRecord` field (optional)
    pub fn authorship_record(mut self, value: impl Into<Option<Did<S>>>) -> Self {
        self._fields.0 = value.into();
        self
    }
    /// Set the `authorshipRecord` field to an Option value (optional)
    pub fn maybe_authorship_record(mut self, value: Option<Did<S>>) -> Self {
        self._fields.0 = value;
        self
    }
}

impl<St: location_state::State, S: BosStr> LocationBuilder<St, S> {
    /// Set the `canonicalStatus` field (optional)
    pub fn canonical_status(
        mut self,
        value: impl Into<Option<LocationCanonicalStatus<S>>>,
    ) -> Self {
        self._fields.1 = value.into();
        self
    }
    /// Set the `canonicalStatus` field to an Option value (optional)
    pub fn maybe_canonical_status(
        mut self,
        value: Option<LocationCanonicalStatus<S>>,
    ) -> Self {
        self._fields.1 = value;
        self
    }
}

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

impl<St, S: BosStr> LocationBuilder<St, S>
where
    St: location_state::State,
    St::CreatorDid: location_state::IsUnset,
{
    /// Set the `creatorDID` field (required)
    pub fn creator_did(
        mut self,
        value: impl Into<Did<S>>,
    ) -> LocationBuilder<location_state::SetCreatorDid<St>, S> {
        self._fields.3 = Option::Some(value.into());
        LocationBuilder {
            _state: PhantomData,
            _fields: self._fields,
            _type: PhantomData,
        }
    }
}

impl<St: location_state::State, S: BosStr> LocationBuilder<St, S> {
    /// Set the `depthIndex` field (optional)
    pub fn depth_index(mut self, value: impl Into<Option<i64>>) -> Self {
        self._fields.4 = value.into();
        self
    }
    /// Set the `depthIndex` field to an Option value (optional)
    pub fn maybe_depth_index(mut self, value: Option<i64>) -> Self {
        self._fields.4 = value;
        self
    }
}

impl<St: location_state::State, S: BosStr> LocationBuilder<St, S> {
    /// Set the `description` field (optional)
    pub fn description(mut self, value: impl Into<Option<S>>) -> Self {
        self._fields.5 = value.into();
        self
    }
    /// Set the `description` field to an Option value (optional)
    pub fn maybe_description(mut self, value: Option<S>) -> Self {
        self._fields.5 = value;
        self
    }
}

impl<St: location_state::State, S: BosStr> LocationBuilder<St, S> {
    /// Set the `locationType` field (optional)
    pub fn location_type(
        mut self,
        value: impl Into<Option<LocationLocationType<S>>>,
    ) -> Self {
        self._fields.6 = value.into();
        self
    }
    /// Set the `locationType` field to an Option value (optional)
    pub fn maybe_location_type(
        mut self,
        value: Option<LocationLocationType<S>>,
    ) -> Self {
        self._fields.6 = value;
        self
    }
}

impl<St, S: BosStr> LocationBuilder<St, S>
where
    St: location_state::State,
    St::Name: location_state::IsUnset,
{
    /// Set the `name` field (required)
    pub fn name(
        mut self,
        value: impl Into<S>,
    ) -> LocationBuilder<location_state::SetName<St>, S> {
        self._fields.7 = Option::Some(value.into());
        LocationBuilder {
            _state: PhantomData,
            _fields: self._fields,
            _type: PhantomData,
        }
    }
}

impl<St: location_state::State, S: BosStr> LocationBuilder<St, S> {
    /// Set the `parentLocation` field (optional)
    pub fn parent_location(mut self, value: impl Into<Option<AtUri<S>>>) -> Self {
        self._fields.8 = value.into();
        self
    }
    /// Set the `parentLocation` field to an Option value (optional)
    pub fn maybe_parent_location(mut self, value: Option<AtUri<S>>) -> Self {
        self._fields.8 = value;
        self
    }
}

impl<St: location_state::State, S: BosStr> LocationBuilder<St, S> {
    /// Set the `properties` field (optional)
    pub fn properties(
        mut self,
        value: impl Into<Option<location::LocationProperties<S>>>,
    ) -> Self {
        self._fields.9 = value.into();
        self
    }
    /// Set the `properties` field to an Option value (optional)
    pub fn maybe_properties(
        mut self,
        value: Option<location::LocationProperties<S>>,
    ) -> Self {
        self._fields.9 = value;
        self
    }
}

impl<St, S: BosStr> LocationBuilder<St, S>
where
    St: location_state::State,
    St::WorldReference: location_state::IsUnset,
{
    /// Set the `worldReference` field (required)
    pub fn world_reference(
        mut self,
        value: impl Into<AtUri<S>>,
    ) -> LocationBuilder<location_state::SetWorldReference<St>, S> {
        self._fields.10 = Option::Some(value.into());
        LocationBuilder {
            _state: PhantomData,
            _fields: self._fields,
            _type: PhantomData,
        }
    }
}

impl<St, S: BosStr> LocationBuilder<St, S>
where
    St: location_state::State,
    St::CreatedAt: location_state::IsSet,
    St::CreatorDid: location_state::IsSet,
    St::Name: location_state::IsSet,
    St::WorldReference: location_state::IsSet,
{
    /// Build the final struct.
    pub fn build(self) -> Location<S> {
        Location {
            authorship_record: self._fields.0,
            canonical_status: self._fields.1,
            created_at: self._fields.2.unwrap(),
            creator_did: self._fields.3.unwrap(),
            depth_index: self._fields.4,
            description: self._fields.5,
            location_type: self._fields.6,
            name: self._fields.7.unwrap(),
            parent_location: self._fields.8,
            properties: self._fields.9,
            world_reference: self._fields.10.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>>) -> Location<S> {
        Location {
            authorship_record: self._fields.0,
            canonical_status: self._fields.1,
            created_at: self._fields.2.unwrap(),
            creator_did: self._fields.3.unwrap(),
            depth_index: self._fields.4,
            description: self._fields.5,
            location_type: self._fields.6,
            name: self._fields.7.unwrap(),
            parent_location: self._fields.8,
            properties: self._fields.9,
            world_reference: self._fields.10.unwrap(),
            extra_data: Some(extra_data),
        }
    }
}