// @generated by jacquard-lexicon. DO NOT EDIT.
//
// Lexicon: org.hyperboards.board
//
// 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, open_union};
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_atproto::repo::strong_ref::StrongRef;
use crate::org_hypercerts::SmallImage;
use crate::org_hypercerts::SmallVideo;
use crate::org_hypercerts::Uri;
use crate::org_hypercerts::claim::activity::ContributorIdentity;
use crate::org_hyperboards::board;
/// Visual configuration for a hyperboard's background, colors, and layout.

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic, Default)]
#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))]
pub struct BoardConfig<S: BosStr = DefaultStr> {
    ///Display aspect ratio of the board.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub aspect_ratio: Option<BoardConfigAspectRatio<S>>,
    ///Background color as a hex string (e.g. '#ffffff').
    #[serde(skip_serializing_if = "Option::is_none")]
    pub background_color: Option<S>,
    ///Whether the background is rendered in grayscale. Default: true.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub background_grayscale: Option<bool>,
    ///URI of the background iframe.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub background_iframe_url: Option<UriValue<S>>,
    ///Background image as a URI or image blob.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub background_image: Option<BoardConfigBackgroundImage<S>>,
    ///Background opacity as a percentage (0–100).
    #[serde(skip_serializing_if = "Option::is_none")]
    pub background_opacity: Option<i64>,
    ///Type of background content.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub background_type: Option<BoardConfigBackgroundType<S>>,
    ///Border color as a hex string (e.g. '#000000').
    #[serde(skip_serializing_if = "Option::is_none")]
    pub border_color: Option<S>,
    ///Whether contributor images are rendered in grayscale. Default: false.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub grayscale_images: Option<bool>,
    ///Shape used to crop contributor images on this board.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub image_shape: Option<BoardConfigImageShape<S>>,
    #[serde(flatten, default, skip_serializing_if = "Option::is_none")]
    pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,
}

/// Display aspect ratio of the board.

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum BoardConfigAspectRatio<S: BosStr = DefaultStr> {
    _169,
    _43,
    _11,
    Other(S),
}

impl<S: BosStr> BoardConfigAspectRatio<S> {
    pub fn as_str(&self) -> &str {
        match self {
            Self::_169 => "16:9",
            Self::_43 => "4:3",
            Self::_11 => "1:1",
            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() {
            "16:9" => Self::_169,
            "4:3" => Self::_43,
            "1:1" => Self::_11,
            _ => Self::Other(s),
        }
    }
}

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

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

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

impl<S: BosStr> jacquard_common::IntoStatic for BoardConfigAspectRatio<S>
where
    S: BosStr + jacquard_common::IntoStatic,
    S::Output: BosStr,
{
    type Output = BoardConfigAspectRatio<S::Output>;
    fn into_static(self) -> Self::Output {
        match self {
            BoardConfigAspectRatio::_169 => BoardConfigAspectRatio::_169,
            BoardConfigAspectRatio::_43 => BoardConfigAspectRatio::_43,
            BoardConfigAspectRatio::_11 => BoardConfigAspectRatio::_11,
            BoardConfigAspectRatio::Other(v) => {
                BoardConfigAspectRatio::Other(v.into_static())
            }
        }
    }
}


#[open_union]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
#[serde(tag = "$type", bound(deserialize = "S: Deserialize<'de> + BosStr"))]
pub enum BoardConfigBackgroundImage<S: BosStr = DefaultStr> {
    #[serde(rename = "org.hypercerts.defs#uri")]
    Uri(Box<Uri<S>>),
    #[serde(rename = "org.hypercerts.defs#smallImage")]
    SmallImage(Box<SmallImage<S>>),
}

/// Type of background content.

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum BoardConfigBackgroundType<S: BosStr = DefaultStr> {
    Image,
    Iframe,
    Other(S),
}

impl<S: BosStr> BoardConfigBackgroundType<S> {
    pub fn as_str(&self) -> &str {
        match self {
            Self::Image => "image",
            Self::Iframe => "iframe",
            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() {
            "image" => Self::Image,
            "iframe" => Self::Iframe,
            _ => Self::Other(s),
        }
    }
}

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

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

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

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

/// Shape used to crop contributor images on this board.

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum BoardConfigImageShape<S: BosStr = DefaultStr> {
    Circular,
    Square,
    Other(S),
}

impl<S: BosStr> BoardConfigImageShape<S> {
    pub fn as_str(&self) -> &str {
        match self {
            Self::Circular => "circular",
            Self::Square => "square",
            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() {
            "circular" => Self::Circular,
            "square" => Self::Square,
            _ => Self::Other(s),
        }
    }
}

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

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

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

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

/// Configuration for a specific contributor within a board. Values serve as fallbacks when the contributor has not defined them on their profile. It can also be used to override contributor settings on this board without changing their global profile.

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))]
pub struct ContributorConfig<S: BosStr = DefaultStr> {
    ///Identifies the contributor being styled. A strong reference to an org.hypercerts.claim.contributorInformation record, or a contributorIdentity (DID or identifier string) for contributors without a dedicated record.
    pub contributor: ContributorConfigContributor<S>,
    ///Display name for this contributor on this board.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub display_name: Option<S>,
    ///Iframe overlay shown when hovering over this contributor.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub hover_iframe_url: Option<UriValue<S>>,
    ///Image overlay shown when hovering over this contributor, as a URI or image blob.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub hover_image: Option<ContributorConfigHoverImage<S>>,
    ///Avatar or face image for this contributor on this board, as a URI or image blob.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub image: Option<ContributorConfigImage<S>>,
    ///When true, these values take precedence over the contributor's own profile and display settings. When false or omitted, they are only used as fallbacks if the contributor has not set their own settings.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub r#override: Option<bool>,
    ///Click-through link URL for this contributor.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub url: Option<UriValue<S>>,
    ///Video for this contributor, as a URI (embed/direct link) or uploaded video blob.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub video: Option<ContributorConfigVideo<S>>,
    #[serde(flatten, default, skip_serializing_if = "Option::is_none")]
    pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,
}


#[open_union]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
#[serde(tag = "$type", bound(deserialize = "S: Deserialize<'de> + BosStr"))]
pub enum ContributorConfigContributor<S: BosStr = DefaultStr> {
    #[serde(rename = "com.atproto.repo.strongRef")]
    StrongRef(Box<StrongRef<S>>),
    #[serde(rename = "org.hypercerts.claim.activity#contributorIdentity")]
    ActivityContributorIdentity(Box<ContributorIdentity<S>>),
}


#[open_union]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
#[serde(tag = "$type", bound(deserialize = "S: Deserialize<'de> + BosStr"))]
pub enum ContributorConfigHoverImage<S: BosStr = DefaultStr> {
    #[serde(rename = "org.hypercerts.defs#uri")]
    Uri(Box<Uri<S>>),
    #[serde(rename = "org.hypercerts.defs#smallImage")]
    SmallImage(Box<SmallImage<S>>),
}


#[open_union]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
#[serde(tag = "$type", bound(deserialize = "S: Deserialize<'de> + BosStr"))]
pub enum ContributorConfigImage<S: BosStr = DefaultStr> {
    #[serde(rename = "org.hypercerts.defs#uri")]
    Uri(Box<Uri<S>>),
    #[serde(rename = "org.hypercerts.defs#smallImage")]
    SmallImage(Box<SmallImage<S>>),
}


#[open_union]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
#[serde(tag = "$type", bound(deserialize = "S: Deserialize<'de> + BosStr"))]
pub enum ContributorConfigVideo<S: BosStr = DefaultStr> {
    #[serde(rename = "org.hypercerts.defs#uri")]
    Uri(Box<Uri<S>>),
    #[serde(rename = "org.hypercerts.defs#smallVideo")]
    SmallVideo(Box<SmallVideo<S>>),
}

/// Configuration record for a hyperboard, wrapping an underlying activity or collection with visual presentation settings. Stored in the creator's PDS.

#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]
#[serde(
    rename_all = "camelCase",
    rename = "org.hyperboards.board",
    tag = "$type",
    bound(deserialize = "S: Deserialize<'de> + BosStr")
)]
pub struct Board<S: BosStr = DefaultStr> {
    ///Board-level visual configuration (background, colors, aspect ratio).
    #[serde(skip_serializing_if = "Option::is_none")]
    pub config: Option<board::BoardConfig<S>>,
    ///Per-contributor configuration entries for this board.
    #[serde(skip_serializing_if = "Option::is_none")]
    pub contributor_configs: Option<Vec<board::ContributorConfig<S>>>,
    ///Client-declared timestamp when this record was originally created.
    pub created_at: Datetime,
    ///Reference to the org.hypercerts.claim.activity or org.hypercerts.claim.collection this board visualizes.
    pub subject: StrongRef<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 BoardGetRecordOutput<S: BosStr = DefaultStr> {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub cid: Option<Cid<S>>,
    pub uri: AtUri<S>,
    pub value: Board<S>,
}

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

impl<S: BosStr> LexiconSchema for BoardConfig<S> {
    fn nsid() -> &'static str {
        "org.hyperboards.board"
    }
    fn def_name() -> &'static str {
        "boardConfig"
    }
    fn lexicon_doc() -> LexiconDoc<'static> {
        lexicon_doc_org_hyperboards_board()
    }
    fn validate(&self) -> Result<(), ConstraintError> {
        if let Some(ref value) = self.aspect_ratio {
            #[allow(unused_comparisons)]
            if <str>::len(value.as_ref()) > 10usize {
                return Err(ConstraintError::MaxLength {
                    path: ValidationPath::from_field("aspect_ratio"),
                    max: 10usize,
                    actual: <str>::len(value.as_ref()),
                });
            }
        }
        if let Some(ref value) = self.background_color {
            #[allow(unused_comparisons)]
            if <str>::len(value.as_ref()) > 20usize {
                return Err(ConstraintError::MaxLength {
                    path: ValidationPath::from_field("background_color"),
                    max: 20usize,
                    actual: <str>::len(value.as_ref()),
                });
            }
        }
        if let Some(ref value) = self.background_iframe_url {
            #[allow(unused_comparisons)]
            if <str>::len(value.as_ref()) > 2048usize {
                return Err(ConstraintError::MaxLength {
                    path: ValidationPath::from_field("background_iframe_url"),
                    max: 2048usize,
                    actual: <str>::len(value.as_ref()),
                });
            }
        }
        if let Some(ref value) = self.background_opacity {
            if *value > 100i64 {
                return Err(ConstraintError::Maximum {
                    path: ValidationPath::from_field("background_opacity"),
                    max: 100i64,
                    actual: *value,
                });
            }
        }
        if let Some(ref value) = self.background_opacity {
            if *value < 0i64 {
                return Err(ConstraintError::Minimum {
                    path: ValidationPath::from_field("background_opacity"),
                    min: 0i64,
                    actual: *value,
                });
            }
        }
        if let Some(ref value) = self.background_type {
            #[allow(unused_comparisons)]
            if <str>::len(value.as_ref()) > 10usize {
                return Err(ConstraintError::MaxLength {
                    path: ValidationPath::from_field("background_type"),
                    max: 10usize,
                    actual: <str>::len(value.as_ref()),
                });
            }
        }
        if let Some(ref value) = self.border_color {
            #[allow(unused_comparisons)]
            if <str>::len(value.as_ref()) > 20usize {
                return Err(ConstraintError::MaxLength {
                    path: ValidationPath::from_field("border_color"),
                    max: 20usize,
                    actual: <str>::len(value.as_ref()),
                });
            }
        }
        if let Some(ref value) = self.image_shape {
            #[allow(unused_comparisons)]
            if <str>::len(value.as_ref()) > 20usize {
                return Err(ConstraintError::MaxLength {
                    path: ValidationPath::from_field("image_shape"),
                    max: 20usize,
                    actual: <str>::len(value.as_ref()),
                });
            }
        }
        Ok(())
    }
}

impl<S: BosStr> LexiconSchema for ContributorConfig<S> {
    fn nsid() -> &'static str {
        "org.hyperboards.board"
    }
    fn def_name() -> &'static str {
        "contributorConfig"
    }
    fn lexicon_doc() -> LexiconDoc<'static> {
        lexicon_doc_org_hyperboards_board()
    }
    fn validate(&self) -> Result<(), ConstraintError> {
        if let Some(ref value) = self.display_name {
            #[allow(unused_comparisons)]
            if <str>::len(value.as_ref()) > 640usize {
                return Err(ConstraintError::MaxLength {
                    path: ValidationPath::from_field("display_name"),
                    max: 640usize,
                    actual: <str>::len(value.as_ref()),
                });
            }
        }
        if let Some(ref value) = self.display_name {
            {
                let count = UnicodeSegmentation::graphemes(value.as_ref(), true).count();
                if count > 64usize {
                    return Err(ConstraintError::MaxGraphemes {
                        path: ValidationPath::from_field("display_name"),
                        max: 64usize,
                        actual: count,
                    });
                }
            }
        }
        if let Some(ref value) = self.hover_iframe_url {
            #[allow(unused_comparisons)]
            if <str>::len(value.as_ref()) > 2048usize {
                return Err(ConstraintError::MaxLength {
                    path: ValidationPath::from_field("hover_iframe_url"),
                    max: 2048usize,
                    actual: <str>::len(value.as_ref()),
                });
            }
        }
        if let Some(ref value) = self.url {
            #[allow(unused_comparisons)]
            if <str>::len(value.as_ref()) > 2048usize {
                return Err(ConstraintError::MaxLength {
                    path: ValidationPath::from_field("url"),
                    max: 2048usize,
                    actual: <str>::len(value.as_ref()),
                });
            }
        }
        Ok(())
    }
}

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

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

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

impl<S: BosStr> Collection for Board<S> {
    const NSID: &'static str = "org.hyperboards.board";
    type Record = BoardRecord;
}

impl Collection for BoardRecord {
    const NSID: &'static str = "org.hyperboards.board";
    type Record = BoardRecord;
}

impl<S: BosStr> LexiconSchema for Board<S> {
    fn nsid() -> &'static str {
        "org.hyperboards.board"
    }
    fn def_name() -> &'static str {
        "main"
    }
    fn lexicon_doc() -> LexiconDoc<'static> {
        lexicon_doc_org_hyperboards_board()
    }
    fn validate(&self) -> Result<(), ConstraintError> {
        if let Some(ref value) = self.contributor_configs {
            #[allow(unused_comparisons)]
            if value.len() > 1000usize {
                return Err(ConstraintError::MaxLength {
                    path: ValidationPath::from_field("contributor_configs"),
                    max: 1000usize,
                    actual: value.len(),
                });
            }
        }
        Ok(())
    }
}

fn lexicon_doc_org_hyperboards_board() -> 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("org.hyperboards.board"),
        defs: {
            let mut map = BTreeMap::new();
            map.insert(
                SmolStr::new_static("boardConfig"),
                LexUserType::Object(LexObject {
                    description: Some(
                        CowStr::new_static(
                            "Visual configuration for a hyperboard's background, colors, and layout.",
                        ),
                    ),
                    properties: {
                        #[allow(unused_mut)]
                        let mut map = BTreeMap::new();
                        map.insert(
                            SmolStr::new_static("aspectRatio"),
                            LexObjectProperty::String(LexString {
                                description: Some(
                                    CowStr::new_static("Display aspect ratio of the board."),
                                ),
                                max_length: Some(10usize),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("backgroundColor"),
                            LexObjectProperty::String(LexString {
                                description: Some(
                                    CowStr::new_static(
                                        "Background color as a hex string (e.g. '#ffffff').",
                                    ),
                                ),
                                max_length: Some(20usize),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("backgroundGrayscale"),
                            LexObjectProperty::Boolean(LexBoolean {
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("backgroundIframeUrl"),
                            LexObjectProperty::String(LexString {
                                description: Some(
                                    CowStr::new_static("URI of the background iframe."),
                                ),
                                format: Some(LexStringFormat::Uri),
                                max_length: Some(2048usize),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("backgroundImage"),
                            LexObjectProperty::Union(LexRefUnion {
                                description: Some(
                                    CowStr::new_static(
                                        "Background image as a URI or image blob.",
                                    ),
                                ),
                                refs: vec![
                                    CowStr::new_static("org.hypercerts.defs#uri"),
                                    CowStr::new_static("org.hypercerts.defs#smallImage")
                                ],
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("backgroundOpacity"),
                            LexObjectProperty::Integer(LexInteger {
                                minimum: Some(0i64),
                                maximum: Some(100i64),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("backgroundType"),
                            LexObjectProperty::String(LexString {
                                description: Some(
                                    CowStr::new_static("Type of background content."),
                                ),
                                max_length: Some(10usize),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("borderColor"),
                            LexObjectProperty::String(LexString {
                                description: Some(
                                    CowStr::new_static(
                                        "Border color as a hex string (e.g. '#000000').",
                                    ),
                                ),
                                max_length: Some(20usize),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("grayscaleImages"),
                            LexObjectProperty::Boolean(LexBoolean {
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("imageShape"),
                            LexObjectProperty::String(LexString {
                                description: Some(
                                    CowStr::new_static(
                                        "Shape used to crop contributor images on this board.",
                                    ),
                                ),
                                max_length: Some(20usize),
                                ..Default::default()
                            }),
                        );
                        map
                    },
                    ..Default::default()
                }),
            );
            map.insert(
                SmolStr::new_static("contributorConfig"),
                LexUserType::Object(LexObject {
                    description: Some(
                        CowStr::new_static(
                            "Configuration for a specific contributor within a board. Values serve as fallbacks when the contributor has not defined them on their profile. It can also be used to override contributor settings on this board without changing their global profile.",
                        ),
                    ),
                    required: Some(vec![SmolStr::new_static("contributor")]),
                    properties: {
                        #[allow(unused_mut)]
                        let mut map = BTreeMap::new();
                        map.insert(
                            SmolStr::new_static("contributor"),
                            LexObjectProperty::Union(LexRefUnion {
                                description: Some(
                                    CowStr::new_static(
                                        "Identifies the contributor being styled. A strong reference to an org.hypercerts.claim.contributorInformation record, or a contributorIdentity (DID or identifier string) for contributors without a dedicated record.",
                                    ),
                                ),
                                refs: vec![
                                    CowStr::new_static("com.atproto.repo.strongRef"),
                                    CowStr::new_static("org.hypercerts.claim.activity#contributorIdentity")
                                ],
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("displayName"),
                            LexObjectProperty::String(LexString {
                                description: Some(
                                    CowStr::new_static(
                                        "Display name for this contributor on this board.",
                                    ),
                                ),
                                max_length: Some(640usize),
                                max_graphemes: Some(64usize),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("hoverIframeUrl"),
                            LexObjectProperty::String(LexString {
                                description: Some(
                                    CowStr::new_static(
                                        "Iframe overlay shown when hovering over this contributor.",
                                    ),
                                ),
                                format: Some(LexStringFormat::Uri),
                                max_length: Some(2048usize),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("hoverImage"),
                            LexObjectProperty::Union(LexRefUnion {
                                description: Some(
                                    CowStr::new_static(
                                        "Image overlay shown when hovering over this contributor, as a URI or image blob.",
                                    ),
                                ),
                                refs: vec![
                                    CowStr::new_static("org.hypercerts.defs#uri"),
                                    CowStr::new_static("org.hypercerts.defs#smallImage")
                                ],
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("image"),
                            LexObjectProperty::Union(LexRefUnion {
                                description: Some(
                                    CowStr::new_static(
                                        "Avatar or face image for this contributor on this board, as a URI or image blob.",
                                    ),
                                ),
                                refs: vec![
                                    CowStr::new_static("org.hypercerts.defs#uri"),
                                    CowStr::new_static("org.hypercerts.defs#smallImage")
                                ],
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("override"),
                            LexObjectProperty::Boolean(LexBoolean {
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("url"),
                            LexObjectProperty::String(LexString {
                                description: Some(
                                    CowStr::new_static(
                                        "Click-through link URL for this contributor.",
                                    ),
                                ),
                                format: Some(LexStringFormat::Uri),
                                max_length: Some(2048usize),
                                ..Default::default()
                            }),
                        );
                        map.insert(
                            SmolStr::new_static("video"),
                            LexObjectProperty::Union(LexRefUnion {
                                description: Some(
                                    CowStr::new_static(
                                        "Video for this contributor, as a URI (embed/direct link) or uploaded video blob.",
                                    ),
                                ),
                                refs: vec![
                                    CowStr::new_static("org.hypercerts.defs#uri"),
                                    CowStr::new_static("org.hypercerts.defs#smallVideo")
                                ],
                                ..Default::default()
                            }),
                        );
                        map
                    },
                    ..Default::default()
                }),
            );
            map.insert(
                SmolStr::new_static("main"),
                LexUserType::Record(LexRecord {
                    description: Some(
                        CowStr::new_static(
                            "Configuration record for a hyperboard, wrapping an underlying activity or collection with visual presentation settings. Stored in the creator's PDS.",
                        ),
                    ),
                    key: Some(CowStr::new_static("tid")),
                    record: LexRecordRecord::Object(LexObject {
                        required: Some(
                            vec![
                                SmolStr::new_static("subject"),
                                SmolStr::new_static("createdAt")
                            ],
                        ),
                        properties: {
                            #[allow(unused_mut)]
                            let mut map = BTreeMap::new();
                            map.insert(
                                SmolStr::new_static("config"),
                                LexObjectProperty::Ref(LexRef {
                                    r#ref: CowStr::new_static("#boardConfig"),
                                    ..Default::default()
                                }),
                            );
                            map.insert(
                                SmolStr::new_static("contributorConfigs"),
                                LexObjectProperty::Array(LexArray {
                                    description: Some(
                                        CowStr::new_static(
                                            "Per-contributor configuration entries for this board.",
                                        ),
                                    ),
                                    items: LexArrayItem::Ref(LexRef {
                                        r#ref: CowStr::new_static("#contributorConfig"),
                                        ..Default::default()
                                    }),
                                    max_length: Some(1000usize),
                                    ..Default::default()
                                }),
                            );
                            map.insert(
                                SmolStr::new_static("createdAt"),
                                LexObjectProperty::String(LexString {
                                    description: Some(
                                        CowStr::new_static(
                                            "Client-declared timestamp when this record was originally created.",
                                        ),
                                    ),
                                    format: Some(LexStringFormat::Datetime),
                                    ..Default::default()
                                }),
                            );
                            map.insert(
                                SmolStr::new_static("subject"),
                                LexObjectProperty::Ref(LexRef {
                                    r#ref: CowStr::new_static("com.atproto.repo.strongRef"),
                                    ..Default::default()
                                }),
                            );
                            map
                        },
                        ..Default::default()
                    }),
                    ..Default::default()
                }),
            );
            map
        },
        ..Default::default()
    }
}

pub mod contributor_config_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 Contributor;
    }
    /// Empty state - all required fields are unset
    pub struct Empty(());
    impl sealed::Sealed for Empty {}
    impl State for Empty {
        type Contributor = Unset;
    }
    ///State transition - sets the `contributor` field to Set
    pub struct SetContributor<St: State = Empty>(PhantomData<fn() -> St>);
    impl<St: State> sealed::Sealed for SetContributor<St> {}
    impl<St: State> State for SetContributor<St> {
        type Contributor = Set<members::contributor>;
    }
    /// Marker types for field names
    #[allow(non_camel_case_types)]
    pub mod members {
        ///Marker type for the `contributor` field
        pub struct contributor(());
    }
}

/// Builder for constructing an instance of this type.
pub struct ContributorConfigBuilder<
    St: contributor_config_state::State,
    S: BosStr = DefaultStr,
> {
    _state: PhantomData<fn() -> St>,
    _fields: (
        Option<ContributorConfigContributor<S>>,
        Option<S>,
        Option<UriValue<S>>,
        Option<ContributorConfigHoverImage<S>>,
        Option<ContributorConfigImage<S>>,
        Option<bool>,
        Option<UriValue<S>>,
        Option<ContributorConfigVideo<S>>,
    ),
    _type: PhantomData<fn() -> S>,
}

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

impl<S: BosStr> ContributorConfig<S> {
    /// Create a new builder for this type
    pub fn builder() -> ContributorConfigBuilder<contributor_config_state::Empty, S> {
        ContributorConfigBuilder::builder()
    }
}

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

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

impl<St, S: BosStr> ContributorConfigBuilder<St, S>
where
    St: contributor_config_state::State,
    St::Contributor: contributor_config_state::IsUnset,
{
    /// Set the `contributor` field (required)
    pub fn contributor(
        mut self,
        value: impl Into<ContributorConfigContributor<S>>,
    ) -> ContributorConfigBuilder<contributor_config_state::SetContributor<St>, S> {
        self._fields.0 = Option::Some(value.into());
        ContributorConfigBuilder {
            _state: PhantomData,
            _fields: self._fields,
            _type: PhantomData,
        }
    }
}

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

impl<St: contributor_config_state::State, S: BosStr> ContributorConfigBuilder<St, S> {
    /// Set the `hoverIframeUrl` field (optional)
    pub fn hover_iframe_url(mut self, value: impl Into<Option<UriValue<S>>>) -> Self {
        self._fields.2 = value.into();
        self
    }
    /// Set the `hoverIframeUrl` field to an Option value (optional)
    pub fn maybe_hover_iframe_url(mut self, value: Option<UriValue<S>>) -> Self {
        self._fields.2 = value;
        self
    }
}

impl<St: contributor_config_state::State, S: BosStr> ContributorConfigBuilder<St, S> {
    /// Set the `hoverImage` field (optional)
    pub fn hover_image(
        mut self,
        value: impl Into<Option<ContributorConfigHoverImage<S>>>,
    ) -> Self {
        self._fields.3 = value.into();
        self
    }
    /// Set the `hoverImage` field to an Option value (optional)
    pub fn maybe_hover_image(
        mut self,
        value: Option<ContributorConfigHoverImage<S>>,
    ) -> Self {
        self._fields.3 = value;
        self
    }
}

impl<St: contributor_config_state::State, S: BosStr> ContributorConfigBuilder<St, S> {
    /// Set the `image` field (optional)
    pub fn image(mut self, value: impl Into<Option<ContributorConfigImage<S>>>) -> Self {
        self._fields.4 = value.into();
        self
    }
    /// Set the `image` field to an Option value (optional)
    pub fn maybe_image(mut self, value: Option<ContributorConfigImage<S>>) -> Self {
        self._fields.4 = value;
        self
    }
}

impl<St: contributor_config_state::State, S: BosStr> ContributorConfigBuilder<St, S> {
    /// Set the `override` field (optional)
    pub fn r#override(mut self, value: impl Into<Option<bool>>) -> Self {
        self._fields.5 = value.into();
        self
    }
    /// Set the `override` field to an Option value (optional)
    pub fn maybe_override(mut self, value: Option<bool>) -> Self {
        self._fields.5 = value;
        self
    }
}

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

impl<St: contributor_config_state::State, S: BosStr> ContributorConfigBuilder<St, S> {
    /// Set the `video` field (optional)
    pub fn video(mut self, value: impl Into<Option<ContributorConfigVideo<S>>>) -> Self {
        self._fields.7 = value.into();
        self
    }
    /// Set the `video` field to an Option value (optional)
    pub fn maybe_video(mut self, value: Option<ContributorConfigVideo<S>>) -> Self {
        self._fields.7 = value;
        self
    }
}

impl<St, S: BosStr> ContributorConfigBuilder<St, S>
where
    St: contributor_config_state::State,
    St::Contributor: contributor_config_state::IsSet,
{
    /// Build the final struct.
    pub fn build(self) -> ContributorConfig<S> {
        ContributorConfig {
            contributor: self._fields.0.unwrap(),
            display_name: self._fields.1,
            hover_iframe_url: self._fields.2,
            hover_image: self._fields.3,
            image: self._fields.4,
            r#override: self._fields.5,
            url: self._fields.6,
            video: self._fields.7,
            extra_data: Default::default(),
        }
    }
    /// Build the final struct with custom extra_data.
    pub fn build_with_data(
        self,
        extra_data: BTreeMap<SmolStr, Data<S>>,
    ) -> ContributorConfig<S> {
        ContributorConfig {
            contributor: self._fields.0.unwrap(),
            display_name: self._fields.1,
            hover_iframe_url: self._fields.2,
            hover_image: self._fields.3,
            image: self._fields.4,
            r#override: self._fields.5,
            url: self._fields.6,
            video: self._fields.7,
            extra_data: Some(extra_data),
        }
    }
}

pub mod board_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 Subject;
    }
    /// Empty state - all required fields are unset
    pub struct Empty(());
    impl sealed::Sealed for Empty {}
    impl State for Empty {
        type CreatedAt = Unset;
        type Subject = 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 Subject = St::Subject;
    }
    ///State transition - sets the `subject` field to Set
    pub struct SetSubject<St: State = Empty>(PhantomData<fn() -> St>);
    impl<St: State> sealed::Sealed for SetSubject<St> {}
    impl<St: State> State for SetSubject<St> {
        type CreatedAt = St::CreatedAt;
        type Subject = Set<members::subject>;
    }
    /// 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 `subject` field
        pub struct subject(());
    }
}

/// Builder for constructing an instance of this type.
pub struct BoardBuilder<St: board_state::State, S: BosStr = DefaultStr> {
    _state: PhantomData<fn() -> St>,
    _fields: (
        Option<board::BoardConfig<S>>,
        Option<Vec<board::ContributorConfig<S>>>,
        Option<Datetime>,
        Option<StrongRef<S>>,
    ),
    _type: PhantomData<fn() -> S>,
}

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

impl<S: BosStr> Board<S> {
    /// Create a new builder for this type
    pub fn builder() -> BoardBuilder<board_state::Empty, S> {
        BoardBuilder::builder()
    }
}

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

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

impl<St: board_state::State, S: BosStr> BoardBuilder<St, S> {
    /// Set the `config` field (optional)
    pub fn config(mut self, value: impl Into<Option<board::BoardConfig<S>>>) -> Self {
        self._fields.0 = value.into();
        self
    }
    /// Set the `config` field to an Option value (optional)
    pub fn maybe_config(mut self, value: Option<board::BoardConfig<S>>) -> Self {
        self._fields.0 = value;
        self
    }
}

impl<St: board_state::State, S: BosStr> BoardBuilder<St, S> {
    /// Set the `contributorConfigs` field (optional)
    pub fn contributor_configs(
        mut self,
        value: impl Into<Option<Vec<board::ContributorConfig<S>>>>,
    ) -> Self {
        self._fields.1 = value.into();
        self
    }
    /// Set the `contributorConfigs` field to an Option value (optional)
    pub fn maybe_contributor_configs(
        mut self,
        value: Option<Vec<board::ContributorConfig<S>>>,
    ) -> Self {
        self._fields.1 = value;
        self
    }
}

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

impl<St, S: BosStr> BoardBuilder<St, S>
where
    St: board_state::State,
    St::Subject: board_state::IsUnset,
{
    /// Set the `subject` field (required)
    pub fn subject(
        mut self,
        value: impl Into<StrongRef<S>>,
    ) -> BoardBuilder<board_state::SetSubject<St>, S> {
        self._fields.3 = Option::Some(value.into());
        BoardBuilder {
            _state: PhantomData,
            _fields: self._fields,
            _type: PhantomData,
        }
    }
}

impl<St, S: BosStr> BoardBuilder<St, S>
where
    St: board_state::State,
    St::CreatedAt: board_state::IsSet,
    St::Subject: board_state::IsSet,
{
    /// Build the final struct.
    pub fn build(self) -> Board<S> {
        Board {
            config: self._fields.0,
            contributor_configs: self._fields.1,
            created_at: self._fields.2.unwrap(),
            subject: self._fields.3.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>>) -> Board<S> {
        Board {
            config: self._fields.0,
            contributor_configs: self._fields.1,
            created_at: self._fields.2.unwrap(),
            subject: self._fields.3.unwrap(),
            extra_data: Some(extra_data),
        }
    }
}