diff --git a/Cargo.lock b/Cargo.lock index 752b8e64..d332faa1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2159,7 +2159,7 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "jacquard" -version = "0.12.0-beta.1" +version = "0.12.0-beta.2" dependencies = [ "bytes", "clap", @@ -2193,7 +2193,7 @@ dependencies = [ [[package]] name = "jacquard-api" -version = "0.12.0-beta.1" +version = "0.12.0-beta.2" dependencies = [ "jacquard-common", "jacquard-derive", @@ -2203,9 +2203,25 @@ dependencies = [ "thiserror 2.0.18", ] +[[package]] +name = "jacquard-codegen-tests" +version = "0.0.0" +dependencies = [ + "inventory", + "jacquard-common", + "jacquard-derive", + "jacquard-lexicon", + "miette", + "serde", + "serde_ipld_dagcbor", + "serde_json", + "smol_str", + "thiserror 2.0.18", +] + [[package]] name = "jacquard-common" -version = "0.12.0-beta.1" +version = "0.12.0-beta.2" dependencies = [ "base64 0.22.1", "bon", @@ -2260,7 +2276,7 @@ dependencies = [ [[package]] name = "jacquard-derive" -version = "0.12.0-beta.1" +version = "0.12.0-beta.2" dependencies = [ "heck 0.5.0", "inventory", @@ -2276,7 +2292,7 @@ dependencies = [ [[package]] name = "jacquard-identity" -version = "0.12.0-beta.1" +version = "0.12.0-beta.2" dependencies = [ "bon", "bytes", @@ -2299,7 +2315,7 @@ dependencies = [ [[package]] name = "jacquard-lexgen" -version = "0.12.0-beta.1" +version = "0.12.0-beta.2" dependencies = [ "clap", "clap_complete", @@ -2325,7 +2341,7 @@ dependencies = [ [[package]] name = "jacquard-lexicon" -version = "0.12.0-beta.1" +version = "0.12.0-beta.2" dependencies = [ "bytes", "cid", @@ -2333,7 +2349,6 @@ dependencies = [ "heck 0.5.0", "inventory", "jacquard-common", - "jacquard-derive", "miette", "multihash", "prettyplease", @@ -2354,7 +2369,7 @@ dependencies = [ [[package]] name = "jacquard-oauth" -version = "0.12.0-beta.1" +version = "0.12.0-beta.2" dependencies = [ "base64 0.22.1", "bytes", @@ -2390,7 +2405,7 @@ dependencies = [ [[package]] name = "jacquard-repo" -version = "0.12.0-beta.1" +version = "0.12.0-beta.2" dependencies = [ "anyhow", "bytes", diff --git a/Cargo.toml b/Cargo.toml index 44ab0d3c..202ebd46 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,11 +1,11 @@ [workspace] resolver = "2" -members = ["crates/jacquard", "crates/jacquard-common", "crates/jacquard-api", "crates/jacquard-lexgen", "crates/jacquard-lexicon", "crates/jacquard-derive", "crates/jacquard-repo", "crates/mini-moka-wasm"] +members = ["crates/jacquard", "crates/jacquard-common", "crates/jacquard-api", "crates/jacquard-lexgen", "crates/jacquard-lexicon", "crates/jacquard-derive", "crates/jacquard-repo", "crates/jacquard-codegen-tests", "crates/mini-moka-wasm"] [workspace.package] edition = "2024" -version = "0.12.0-beta.1" +version = "0.12.0-beta.2" authors = ["Orual "] #repository = "https://github.com/rsform/jacquard" repository = "https://tangled.org/nonbinary.computer/jacquard" diff --git a/crates/jacquard-api/Cargo.toml b/crates/jacquard-api/Cargo.toml index af70a82f..d0c8774a 100644 --- a/crates/jacquard-api/Cargo.toml +++ b/crates/jacquard-api/Cargo.toml @@ -2,7 +2,7 @@ name = "jacquard-api" description = "Generated AT Protocol API bindings for Jacquard" edition.workspace = true -version = "0.12.0-beta.1" +version = "0.12.0-beta.2" authors.workspace = true repository.workspace = true keywords.workspace = true diff --git a/crates/jacquard-axum/Cargo.toml b/crates/jacquard-axum/Cargo.toml index e7c8bd01..dd6aca54 100644 --- a/crates/jacquard-axum/Cargo.toml +++ b/crates/jacquard-axum/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "jacquard-axum" edition.workspace = true -version = "0.12.0-beta.1" +version = "0.12.0-beta.2" authors.workspace = true repository.workspace = true keywords.workspace = true diff --git a/crates/jacquard-codegen-tests/.gitignore b/crates/jacquard-codegen-tests/.gitignore new file mode 100644 index 00000000..c83f90a2 --- /dev/null +++ b/crates/jacquard-codegen-tests/.gitignore @@ -0,0 +1 @@ +src/generated diff --git a/crates/jacquard-codegen-tests/Cargo.toml b/crates/jacquard-codegen-tests/Cargo.toml index a19b3f81..be5fe65c 100644 --- a/crates/jacquard-codegen-tests/Cargo.toml +++ b/crates/jacquard-codegen-tests/Cargo.toml @@ -10,6 +10,7 @@ license.workspace = true jacquard-common = { path = "../jacquard-common" } jacquard-derive = { path = "../jacquard-derive" } jacquard-lexicon = { path = "../jacquard-lexicon" } +inventory = "0.3" serde = { workspace = true } smol_str = { workspace = true } thiserror = { workspace = true } diff --git a/crates/jacquard-codegen-tests/src/generated/macro_mode/app_bsky.rs b/crates/jacquard-codegen-tests/src/generated/macro_mode/app_bsky.rs new file mode 100644 index 00000000..0dc7c1b8 --- /dev/null +++ b/crates/jacquard-codegen-tests/src/generated/macro_mode/app_bsky.rs @@ -0,0 +1,7 @@ +// @generated by jacquard-lexicon. DO NOT EDIT. +// +// This file was automatically generated from Lexicon schemas. +// Any manual changes will be overwritten on the next regeneration. + +pub mod embed; +pub mod richtext; \ No newline at end of file diff --git a/crates/jacquard-codegen-tests/src/generated/macro_mode/app_bsky/embed.rs b/crates/jacquard-codegen-tests/src/generated/macro_mode/app_bsky/embed.rs new file mode 100644 index 00000000..0d2e68d6 --- /dev/null +++ b/crates/jacquard-codegen-tests/src/generated/macro_mode/app_bsky/embed.rs @@ -0,0 +1,6 @@ +// @generated by jacquard-lexicon. DO NOT EDIT. +// +// This file was automatically generated from Lexicon schemas. +// Any manual changes will be overwritten on the next regeneration. + +pub mod external; \ No newline at end of file diff --git a/crates/jacquard-codegen-tests/src/generated/macro_mode/app_bsky/embed/external.rs b/crates/jacquard-codegen-tests/src/generated/macro_mode/app_bsky/embed/external.rs new file mode 100644 index 00000000..ebfa7afc --- /dev/null +++ b/crates/jacquard-codegen-tests/src/generated/macro_mode/app_bsky/embed/external.rs @@ -0,0 +1,1022 @@ +// @generated by jacquard-lexicon. DO NOT EDIT. +// +// Lexicon: app.bsky.embed.external +// +// This file was automatically generated from Lexicon schemas. +// Any manual changes will be overwritten on the next regeneration. + +#[derive( + serde::Serialize, + serde::Deserialize, + Debug, + Clone, + PartialEq, + Eq, + jacquard_derive::IntoStatic +)] + +#[serde( + rename_all = "camelCase", + bound(deserialize = "S: serde::Deserialize<'de> + jacquard_common::BosStr") +)] +pub struct External { + pub description: S, + #[serde(skip_serializing_if = "core::option::Option::is_none")] + pub thumb: core::option::Option>, + pub title: S, + pub uri: jacquard_common::types::string::UriValue, + #[serde(flatten, default, skip_serializing_if = "core::option::Option::is_none")] + pub extra_data: core::option::Option< + alloc::collections::BTreeMap< + jacquard_common::deps::smol_str::SmolStr, + jacquard_common::types::value::Data, + >, + >, +} + +/// A representation of some externally linked content (eg, a URL and 'card'), embedded in a Bluesky record (eg, a post). + +#[derive( + serde::Serialize, + serde::Deserialize, + Debug, + Clone, + PartialEq, + Eq, + jacquard_derive::IntoStatic +)] + +#[serde( + rename_all = "camelCase", + bound(deserialize = "S: serde::Deserialize<'de> + jacquard_common::BosStr") +)] +pub struct ExternalRecord { + pub external: crate::macro_mode::app_bsky::embed::external::External, + #[serde(flatten, default, skip_serializing_if = "core::option::Option::is_none")] + pub extra_data: core::option::Option< + alloc::collections::BTreeMap< + jacquard_common::deps::smol_str::SmolStr, + jacquard_common::types::value::Data, + >, + >, +} + + +#[derive( + serde::Serialize, + serde::Deserialize, + Debug, + Clone, + PartialEq, + Eq, + jacquard_derive::IntoStatic +)] + +#[serde( + rename_all = "camelCase", + bound(deserialize = "S: serde::Deserialize<'de> + jacquard_common::BosStr") +)] +pub struct View { + pub external: crate::macro_mode::app_bsky::embed::external::ViewExternal, + #[serde(flatten, default, skip_serializing_if = "core::option::Option::is_none")] + pub extra_data: core::option::Option< + alloc::collections::BTreeMap< + jacquard_common::deps::smol_str::SmolStr, + jacquard_common::types::value::Data, + >, + >, +} + + +#[derive( + serde::Serialize, + serde::Deserialize, + Debug, + Clone, + PartialEq, + Eq, + jacquard_derive::IntoStatic +)] + +#[serde( + rename_all = "camelCase", + bound(deserialize = "S: serde::Deserialize<'de> + jacquard_common::BosStr") +)] +pub struct ViewExternal { + pub description: S, + #[serde(skip_serializing_if = "core::option::Option::is_none")] + pub thumb: core::option::Option>, + pub title: S, + pub uri: jacquard_common::types::string::UriValue, + #[serde(flatten, default, skip_serializing_if = "core::option::Option::is_none")] + pub extra_data: core::option::Option< + alloc::collections::BTreeMap< + jacquard_common::deps::smol_str::SmolStr, + jacquard_common::types::value::Data, + >, + >, +} + +impl jacquard_lexicon::schema::LexiconSchema +for External { + fn nsid() -> &'static str { + "app.bsky.embed.external" + } + fn def_name() -> &'static str { + "external" + } + fn lexicon_doc() -> jacquard_lexicon::lexicon::LexiconDoc<'static> { + lexicon_doc_app_bsky_embed_external() + } + fn validate(&self) -> Result<(), jacquard_lexicon::validation::ConstraintError> { + if let Some(ref value) = self.thumb { + { + let size = value.blob().size; + if size > 1000000usize { + return Err(jacquard_lexicon::validation::ConstraintError::BlobTooLarge { + path: jacquard_lexicon::validation::ValidationPath::from_field( + "thumb", + ), + max: 1000000usize, + actual: size, + }); + } + } + } + if let Some(ref value) = self.thumb { + { + let mime = value.blob().mime_type.as_str(); + let accepted: &[&str] = &["image/*"]; + let matched = accepted + .iter() + .any(|pattern| { + if *pattern == "*/*" { + true + } else if pattern.ends_with("/*") { + let prefix = &pattern[..pattern.len() - 2]; + mime.starts_with(prefix) + && mime.as_bytes().get(prefix.len()) == Some(&b'/') + } else { + mime == *pattern + } + }); + if !matched { + return Err(jacquard_lexicon::validation::ConstraintError::BlobMimeTypeNotAccepted { + path: jacquard_lexicon::validation::ValidationPath::from_field( + "thumb", + ), + accepted: vec!["image/*".to_string()], + actual: mime.to_string(), + }); + } + } + } + Ok(()) + } +} + +impl jacquard_lexicon::schema::LexiconSchema +for ExternalRecord { + fn nsid() -> &'static str { + "app.bsky.embed.external" + } + fn def_name() -> &'static str { + "main" + } + fn lexicon_doc() -> jacquard_lexicon::lexicon::LexiconDoc<'static> { + lexicon_doc_app_bsky_embed_external() + } + fn validate(&self) -> Result<(), jacquard_lexicon::validation::ConstraintError> { + Ok(()) + } +} + +impl jacquard_lexicon::schema::LexiconSchema for View { + fn nsid() -> &'static str { + "app.bsky.embed.external" + } + fn def_name() -> &'static str { + "view" + } + fn lexicon_doc() -> jacquard_lexicon::lexicon::LexiconDoc<'static> { + lexicon_doc_app_bsky_embed_external() + } + fn validate(&self) -> Result<(), jacquard_lexicon::validation::ConstraintError> { + Ok(()) + } +} + +impl jacquard_lexicon::schema::LexiconSchema +for ViewExternal { + fn nsid() -> &'static str { + "app.bsky.embed.external" + } + fn def_name() -> &'static str { + "viewExternal" + } + fn lexicon_doc() -> jacquard_lexicon::lexicon::LexiconDoc<'static> { + lexicon_doc_app_bsky_embed_external() + } + fn validate(&self) -> Result<(), jacquard_lexicon::validation::ConstraintError> { + Ok(()) + } +} + +pub mod external_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 Uri; + type Title; + type Description; + } + /// Empty state - all required fields are unset + pub struct Empty(()); + impl sealed::Sealed for Empty {} + impl State for Empty { + type Uri = Unset; + type Title = Unset; + type Description = Unset; + } + ///State transition - sets the `uri` field to Set + pub struct SetUri(PhantomData St>); + impl sealed::Sealed for SetUri {} + impl State for SetUri { + type Uri = Set; + type Title = St::Title; + type Description = St::Description; + } + ///State transition - sets the `title` field to Set + pub struct SetTitle(PhantomData St>); + impl sealed::Sealed for SetTitle {} + impl State for SetTitle { + type Uri = St::Uri; + type Title = Set; + type Description = St::Description; + } + ///State transition - sets the `description` field to Set + pub struct SetDescription(PhantomData St>); + impl sealed::Sealed for SetDescription {} + impl State for SetDescription { + type Uri = St::Uri; + type Title = St::Title; + type Description = Set; + } + /// Marker types for field names + #[allow(non_camel_case_types)] + pub mod members { + ///Marker type for the `uri` field + pub struct uri(()); + ///Marker type for the `title` field + pub struct title(()); + ///Marker type for the `description` field + pub struct description(()); + } +} + +/// Builder for constructing an instance of this type. +pub struct ExternalBuilder { + _state: ::core::marker::PhantomData St>, + _fields: ( + core::option::Option, + core::option::Option>, + core::option::Option, + core::option::Option>, + ), + _type: ::core::marker::PhantomData S>, +} + +impl External { + /// Create a new builder for this type. + pub fn new() -> ExternalBuilder { + ExternalBuilder::new() + } +} + +impl ExternalBuilder { + /// Create a new builder with all fields unset. + pub fn new() -> Self { + ExternalBuilder { + _state: ::core::marker::PhantomData, + _fields: (None, None, None, None), + _type: ::core::marker::PhantomData, + } + } +} + +impl ExternalBuilder +where + St: external_state::State, + St::Description: external_state::IsUnset, +{ + /// Set the `description` field (required) + pub fn description( + mut self, + value: impl Into, + ) -> ExternalBuilder> { + self._fields.0 = ::core::option::Option::Some(value.into()); + ExternalBuilder { + _state: ::core::marker::PhantomData, + _fields: self._fields, + _type: ::core::marker::PhantomData, + } + } +} + +impl ExternalBuilder { + /// Set the `thumb` field (optional) + pub fn thumb( + mut self, + value: impl Into>>, + ) -> Self { + self._fields.1 = value.into(); + self + } + /// Set the `thumb` field to an Option value (optional) + pub fn maybe_thumb( + mut self, + value: Option>, + ) -> Self { + self._fields.1 = value; + self + } +} + +impl ExternalBuilder +where + St: external_state::State, + St::Title: external_state::IsUnset, +{ + /// Set the `title` field (required) + pub fn title( + mut self, + value: impl Into, + ) -> ExternalBuilder> { + self._fields.2 = ::core::option::Option::Some(value.into()); + ExternalBuilder { + _state: ::core::marker::PhantomData, + _fields: self._fields, + _type: ::core::marker::PhantomData, + } + } +} + +impl ExternalBuilder +where + St: external_state::State, + St::Uri: external_state::IsUnset, +{ + /// Set the `uri` field (required) + pub fn uri( + mut self, + value: impl Into>, + ) -> ExternalBuilder> { + self._fields.3 = ::core::option::Option::Some(value.into()); + ExternalBuilder { + _state: ::core::marker::PhantomData, + _fields: self._fields, + _type: ::core::marker::PhantomData, + } + } +} + +impl ExternalBuilder +where + St: external_state::State, + St::Uri: external_state::IsSet, + St::Title: external_state::IsSet, + St::Description: external_state::IsSet, +{ + /// Build the final struct. + pub fn build(self) -> External { + External { + description: self._fields.0.unwrap(), + thumb: self._fields.1, + title: self._fields.2.unwrap(), + uri: self._fields.3.unwrap(), + extra_data: Default::default(), + } + } + /// Build the final struct with custom extra_data. + pub fn build_with_data( + self, + extra_data: alloc::collections::BTreeMap< + jacquard_common::deps::smol_str::SmolStr, + jacquard_common::types::value::Data, + >, + ) -> External { + External { + description: self._fields.0.unwrap(), + thumb: self._fields.1, + title: self._fields.2.unwrap(), + uri: self._fields.3.unwrap(), + extra_data: Some(extra_data), + } + } +} + +fn lexicon_doc_app_bsky_embed_external() -> jacquard_lexicon::lexicon::LexiconDoc< + 'static, +> { + ::jacquard_lexicon::lexicon::LexiconDoc { + lexicon: ::jacquard_lexicon::lexicon::Lexicon::Lexicon1, + id: ::jacquard_common::CowStr::new_static("app.bsky.embed.external"), + defs: { + let mut map = ::alloc::collections::BTreeMap::new(); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static("external"), + ::jacquard_lexicon::lexicon::LexUserType::Object(::jacquard_lexicon::lexicon::LexObject { + required: Some( + vec![ + ::jacquard_common::deps::smol_str::SmolStr::new_static("uri"), + ::jacquard_common::deps::smol_str::SmolStr::new_static("title"), + ::jacquard_common::deps::smol_str::SmolStr::new_static("description") + ], + ), + properties: { + #[allow(unused_mut)] + let mut map = ::alloc::collections::BTreeMap::new(); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "description", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "thumb", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::Blob(::jacquard_lexicon::lexicon::LexBlob { + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "title", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "uri", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { + format: Some( + ::jacquard_lexicon::lexicon::LexStringFormat::Uri, + ), + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static("main"), + ::jacquard_lexicon::lexicon::LexUserType::Object(::jacquard_lexicon::lexicon::LexObject { + description: Some( + ::jacquard_common::CowStr::new_static( + "A representation of some externally linked content (eg, a URL and 'card'), embedded in a Bluesky record (eg, a post).", + ), + ), + required: Some( + vec![ + ::jacquard_common::deps::smol_str::SmolStr::new_static("external") + ], + ), + properties: { + #[allow(unused_mut)] + let mut map = ::alloc::collections::BTreeMap::new(); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "external", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::Ref(::jacquard_lexicon::lexicon::LexRef { + r#ref: ::jacquard_common::CowStr::new_static("#external"), + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static("view"), + ::jacquard_lexicon::lexicon::LexUserType::Object(::jacquard_lexicon::lexicon::LexObject { + required: Some( + vec![ + ::jacquard_common::deps::smol_str::SmolStr::new_static("external") + ], + ), + properties: { + #[allow(unused_mut)] + let mut map = ::alloc::collections::BTreeMap::new(); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "external", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::Ref(::jacquard_lexicon::lexicon::LexRef { + r#ref: ::jacquard_common::CowStr::new_static( + "#viewExternal", + ), + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static("viewExternal"), + ::jacquard_lexicon::lexicon::LexUserType::Object(::jacquard_lexicon::lexicon::LexObject { + required: Some( + vec![ + ::jacquard_common::deps::smol_str::SmolStr::new_static("uri"), + ::jacquard_common::deps::smol_str::SmolStr::new_static("title"), + ::jacquard_common::deps::smol_str::SmolStr::new_static("description") + ], + ), + properties: { + #[allow(unused_mut)] + let mut map = ::alloc::collections::BTreeMap::new(); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "description", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "thumb", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { + format: Some( + ::jacquard_lexicon::lexicon::LexStringFormat::Uri, + ), + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "title", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "uri", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { + format: Some( + ::jacquard_lexicon::lexicon::LexStringFormat::Uri, + ), + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map + }, + ..Default::default() + } +} + +pub mod external_record_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 External; + } + /// Empty state - all required fields are unset + pub struct Empty(()); + impl sealed::Sealed for Empty {} + impl State for Empty { + type External = Unset; + } + ///State transition - sets the `external` field to Set + pub struct SetExternal(PhantomData St>); + impl sealed::Sealed for SetExternal {} + impl State for SetExternal { + type External = Set; + } + /// Marker types for field names + #[allow(non_camel_case_types)] + pub mod members { + ///Marker type for the `external` field + pub struct external(()); + } +} + +/// Builder for constructing an instance of this type. +pub struct ExternalRecordBuilder< + S: jacquard_common::BosStr, + St: external_record_state::State, +> { + _state: ::core::marker::PhantomData St>, + _fields: ( + core::option::Option>, + ), + _type: ::core::marker::PhantomData S>, +} + +impl ExternalRecord { + /// Create a new builder for this type. + pub fn new() -> ExternalRecordBuilder { + ExternalRecordBuilder::new() + } +} + +impl ExternalRecordBuilder { + /// Create a new builder with all fields unset. + pub fn new() -> Self { + ExternalRecordBuilder { + _state: ::core::marker::PhantomData, + _fields: (None,), + _type: ::core::marker::PhantomData, + } + } +} + +impl ExternalRecordBuilder +where + St: external_record_state::State, + St::External: external_record_state::IsUnset, +{ + /// Set the `external` field (required) + pub fn external( + mut self, + value: impl Into>, + ) -> ExternalRecordBuilder> { + self._fields.0 = ::core::option::Option::Some(value.into()); + ExternalRecordBuilder { + _state: ::core::marker::PhantomData, + _fields: self._fields, + _type: ::core::marker::PhantomData, + } + } +} + +impl ExternalRecordBuilder +where + St: external_record_state::State, + St::External: external_record_state::IsSet, +{ + /// Build the final struct. + pub fn build(self) -> ExternalRecord { + ExternalRecord { + external: self._fields.0.unwrap(), + extra_data: Default::default(), + } + } + /// Build the final struct with custom extra_data. + pub fn build_with_data( + self, + extra_data: alloc::collections::BTreeMap< + jacquard_common::deps::smol_str::SmolStr, + jacquard_common::types::value::Data, + >, + ) -> ExternalRecord { + ExternalRecord { + external: self._fields.0.unwrap(), + extra_data: Some(extra_data), + } + } +} + +pub mod view_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 External; + } + /// Empty state - all required fields are unset + pub struct Empty(()); + impl sealed::Sealed for Empty {} + impl State for Empty { + type External = Unset; + } + ///State transition - sets the `external` field to Set + pub struct SetExternal(PhantomData St>); + impl sealed::Sealed for SetExternal {} + impl State for SetExternal { + type External = Set; + } + /// Marker types for field names + #[allow(non_camel_case_types)] + pub mod members { + ///Marker type for the `external` field + pub struct external(()); + } +} + +/// Builder for constructing an instance of this type. +pub struct ViewBuilder { + _state: ::core::marker::PhantomData St>, + _fields: ( + core::option::Option< + crate::macro_mode::app_bsky::embed::external::ViewExternal, + >, + ), + _type: ::core::marker::PhantomData S>, +} + +impl View { + /// Create a new builder for this type. + pub fn new() -> ViewBuilder { + ViewBuilder::new() + } +} + +impl ViewBuilder { + /// Create a new builder with all fields unset. + pub fn new() -> Self { + ViewBuilder { + _state: ::core::marker::PhantomData, + _fields: (None,), + _type: ::core::marker::PhantomData, + } + } +} + +impl ViewBuilder +where + St: view_state::State, + St::External: view_state::IsUnset, +{ + /// Set the `external` field (required) + pub fn external( + mut self, + value: impl Into>, + ) -> ViewBuilder> { + self._fields.0 = ::core::option::Option::Some(value.into()); + ViewBuilder { + _state: ::core::marker::PhantomData, + _fields: self._fields, + _type: ::core::marker::PhantomData, + } + } +} + +impl ViewBuilder +where + St: view_state::State, + St::External: view_state::IsSet, +{ + /// Build the final struct. + pub fn build(self) -> View { + View { + external: self._fields.0.unwrap(), + extra_data: Default::default(), + } + } + /// Build the final struct with custom extra_data. + pub fn build_with_data( + self, + extra_data: alloc::collections::BTreeMap< + jacquard_common::deps::smol_str::SmolStr, + jacquard_common::types::value::Data, + >, + ) -> View { + View { + external: self._fields.0.unwrap(), + extra_data: Some(extra_data), + } + } +} + +pub mod view_external_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 Title; + type Uri; + type Description; + } + /// Empty state - all required fields are unset + pub struct Empty(()); + impl sealed::Sealed for Empty {} + impl State for Empty { + type Title = Unset; + type Uri = Unset; + type Description = Unset; + } + ///State transition - sets the `title` field to Set + pub struct SetTitle(PhantomData St>); + impl sealed::Sealed for SetTitle {} + impl State for SetTitle { + type Title = Set; + type Uri = St::Uri; + type Description = St::Description; + } + ///State transition - sets the `uri` field to Set + pub struct SetUri(PhantomData St>); + impl sealed::Sealed for SetUri {} + impl State for SetUri { + type Title = St::Title; + type Uri = Set; + type Description = St::Description; + } + ///State transition - sets the `description` field to Set + pub struct SetDescription(PhantomData St>); + impl sealed::Sealed for SetDescription {} + impl State for SetDescription { + type Title = St::Title; + type Uri = St::Uri; + type Description = Set; + } + /// Marker types for field names + #[allow(non_camel_case_types)] + pub mod members { + ///Marker type for the `title` field + pub struct title(()); + ///Marker type for the `uri` field + pub struct uri(()); + ///Marker type for the `description` field + pub struct description(()); + } +} + +/// Builder for constructing an instance of this type. +pub struct ViewExternalBuilder< + S: jacquard_common::BosStr, + St: view_external_state::State, +> { + _state: ::core::marker::PhantomData St>, + _fields: ( + core::option::Option, + core::option::Option>, + core::option::Option, + core::option::Option>, + ), + _type: ::core::marker::PhantomData S>, +} + +impl ViewExternal { + /// Create a new builder for this type. + pub fn new() -> ViewExternalBuilder { + ViewExternalBuilder::new() + } +} + +impl ViewExternalBuilder { + /// Create a new builder with all fields unset. + pub fn new() -> Self { + ViewExternalBuilder { + _state: ::core::marker::PhantomData, + _fields: (None, None, None, None), + _type: ::core::marker::PhantomData, + } + } +} + +impl ViewExternalBuilder +where + St: view_external_state::State, + St::Description: view_external_state::IsUnset, +{ + /// Set the `description` field (required) + pub fn description( + mut self, + value: impl Into, + ) -> ViewExternalBuilder> { + self._fields.0 = ::core::option::Option::Some(value.into()); + ViewExternalBuilder { + _state: ::core::marker::PhantomData, + _fields: self._fields, + _type: ::core::marker::PhantomData, + } + } +} + +impl< + S: jacquard_common::BosStr, + St: view_external_state::State, +> ViewExternalBuilder { + /// Set the `thumb` field (optional) + pub fn thumb( + mut self, + value: impl Into>>, + ) -> Self { + self._fields.1 = value.into(); + self + } + /// Set the `thumb` field to an Option value (optional) + pub fn maybe_thumb( + mut self, + value: Option>, + ) -> Self { + self._fields.1 = value; + self + } +} + +impl ViewExternalBuilder +where + St: view_external_state::State, + St::Title: view_external_state::IsUnset, +{ + /// Set the `title` field (required) + pub fn title( + mut self, + value: impl Into, + ) -> ViewExternalBuilder> { + self._fields.2 = ::core::option::Option::Some(value.into()); + ViewExternalBuilder { + _state: ::core::marker::PhantomData, + _fields: self._fields, + _type: ::core::marker::PhantomData, + } + } +} + +impl ViewExternalBuilder +where + St: view_external_state::State, + St::Uri: view_external_state::IsUnset, +{ + /// Set the `uri` field (required) + pub fn uri( + mut self, + value: impl Into>, + ) -> ViewExternalBuilder> { + self._fields.3 = ::core::option::Option::Some(value.into()); + ViewExternalBuilder { + _state: ::core::marker::PhantomData, + _fields: self._fields, + _type: ::core::marker::PhantomData, + } + } +} + +impl ViewExternalBuilder +where + St: view_external_state::State, + St::Title: view_external_state::IsSet, + St::Uri: view_external_state::IsSet, + St::Description: view_external_state::IsSet, +{ + /// Build the final struct. + pub fn build(self) -> ViewExternal { + ViewExternal { + description: self._fields.0.unwrap(), + thumb: self._fields.1, + title: self._fields.2.unwrap(), + uri: self._fields.3.unwrap(), + extra_data: Default::default(), + } + } + /// Build the final struct with custom extra_data. + pub fn build_with_data( + self, + extra_data: alloc::collections::BTreeMap< + jacquard_common::deps::smol_str::SmolStr, + jacquard_common::types::value::Data, + >, + ) -> ViewExternal { + ViewExternal { + description: self._fields.0.unwrap(), + thumb: self._fields.1, + title: self._fields.2.unwrap(), + uri: self._fields.3.unwrap(), + extra_data: Some(extra_data), + } + } +} \ No newline at end of file diff --git a/crates/jacquard-codegen-tests/src/generated/macro_mode/app_bsky/richtext.rs b/crates/jacquard-codegen-tests/src/generated/macro_mode/app_bsky/richtext.rs new file mode 100644 index 00000000..b7b3177b --- /dev/null +++ b/crates/jacquard-codegen-tests/src/generated/macro_mode/app_bsky/richtext.rs @@ -0,0 +1,6 @@ +// @generated by jacquard-lexicon. DO NOT EDIT. +// +// This file was automatically generated from Lexicon schemas. +// Any manual changes will be overwritten on the next regeneration. + +pub mod facet; \ No newline at end of file diff --git a/crates/jacquard-codegen-tests/src/generated/macro_mode/app_bsky/richtext/facet.rs b/crates/jacquard-codegen-tests/src/generated/macro_mode/app_bsky/richtext/facet.rs new file mode 100644 index 00000000..0b2d5680 --- /dev/null +++ b/crates/jacquard-codegen-tests/src/generated/macro_mode/app_bsky/richtext/facet.rs @@ -0,0 +1,980 @@ +// @generated by jacquard-lexicon. DO NOT EDIT. +// +// Lexicon: app.bsky.richtext.facet +// +// This file was automatically generated from Lexicon schemas. +// Any manual changes will be overwritten on the next regeneration. + +/// Specifies the sub-string range a facet feature applies to. Start index is inclusive, end index is exclusive. Indices are zero-indexed, counting bytes of the UTF-8 encoded text. NOTE: some languages, like Javascript, use UTF-16 or Unicode codepoints for string slice indexing; in these languages, convert to byte arrays before working with facets. + +#[derive( + serde::Serialize, + serde::Deserialize, + Debug, + Clone, + PartialEq, + Eq, + jacquard_derive::IntoStatic +)] + +#[serde( + rename_all = "camelCase", + bound(deserialize = "S: serde::Deserialize<'de> + jacquard_common::BosStr") +)] +pub struct ByteSlice { + pub byte_end: i64, + pub byte_start: i64, + #[serde(flatten, default, skip_serializing_if = "core::option::Option::is_none")] + pub extra_data: core::option::Option< + alloc::collections::BTreeMap< + jacquard_common::deps::smol_str::SmolStr, + jacquard_common::types::value::Data, + >, + >, +} + +/// Facet feature for a URL. The text URL may have been simplified or truncated, but the facet reference should be a complete URL. + +#[derive( + serde::Serialize, + serde::Deserialize, + Debug, + Clone, + PartialEq, + Eq, + jacquard_derive::IntoStatic +)] + +#[serde( + rename_all = "camelCase", + bound(deserialize = "S: serde::Deserialize<'de> + jacquard_common::BosStr") +)] +pub struct Link { + pub uri: jacquard_common::types::string::UriValue, + #[serde(flatten, default, skip_serializing_if = "core::option::Option::is_none")] + pub extra_data: core::option::Option< + alloc::collections::BTreeMap< + jacquard_common::deps::smol_str::SmolStr, + jacquard_common::types::value::Data, + >, + >, +} + +/// Annotation of a sub-string within rich text. + +#[derive( + serde::Serialize, + serde::Deserialize, + Debug, + Clone, + PartialEq, + Eq, + jacquard_derive::IntoStatic +)] + +#[serde( + rename_all = "camelCase", + bound(deserialize = "S: serde::Deserialize<'de> + jacquard_common::BosStr") +)] +pub struct Facet { + pub features: Vec>, + pub index: crate::macro_mode::app_bsky::richtext::facet::ByteSlice, + #[serde(flatten, default, skip_serializing_if = "core::option::Option::is_none")] + pub extra_data: core::option::Option< + alloc::collections::BTreeMap< + jacquard_common::deps::smol_str::SmolStr, + jacquard_common::types::value::Data, + >, + >, +} + + +#[jacquard_derive::open_union] +#[derive( + serde::Serialize, + serde::Deserialize, + Debug, + Clone, + PartialEq, + Eq, + jacquard_derive::IntoStatic +)] + +#[serde( + tag = "$type", + bound(deserialize = "S: serde::Deserialize<'de> + jacquard_common::BosStr") +)] +pub enum FacetFeaturesItem { + #[serde(rename = "app.bsky.richtext.facet#mention")] + Mention(Box>), + #[serde(rename = "app.bsky.richtext.facet#link")] + Link(Box>), + #[serde(rename = "app.bsky.richtext.facet#tag")] + Tag(Box>), +} + +/// Facet feature for mention of another account. The text is usually a handle, including a '@' prefix, but the facet reference is a DID. + +#[derive( + serde::Serialize, + serde::Deserialize, + Debug, + Clone, + PartialEq, + Eq, + jacquard_derive::IntoStatic +)] + +#[serde( + rename_all = "camelCase", + bound(deserialize = "S: serde::Deserialize<'de> + jacquard_common::BosStr") +)] +pub struct Mention { + pub did: jacquard_common::types::string::Did, + #[serde(flatten, default, skip_serializing_if = "core::option::Option::is_none")] + pub extra_data: core::option::Option< + alloc::collections::BTreeMap< + jacquard_common::deps::smol_str::SmolStr, + jacquard_common::types::value::Data, + >, + >, +} + +/// Facet feature for a hashtag. The text usually includes a '#' prefix, but the facet reference should not (except in the case of 'double hash tags'). + +#[derive( + serde::Serialize, + serde::Deserialize, + Debug, + Clone, + PartialEq, + Eq, + jacquard_derive::IntoStatic, + Default +)] + +#[serde( + rename_all = "camelCase", + bound(deserialize = "S: serde::Deserialize<'de> + jacquard_common::BosStr") +)] +pub struct Tag { + pub tag: S, + #[serde(flatten, default, skip_serializing_if = "core::option::Option::is_none")] + pub extra_data: core::option::Option< + alloc::collections::BTreeMap< + jacquard_common::deps::smol_str::SmolStr, + jacquard_common::types::value::Data, + >, + >, +} + +impl jacquard_lexicon::schema::LexiconSchema +for ByteSlice { + fn nsid() -> &'static str { + "app.bsky.richtext.facet" + } + fn def_name() -> &'static str { + "byteSlice" + } + fn lexicon_doc() -> jacquard_lexicon::lexicon::LexiconDoc<'static> { + lexicon_doc_app_bsky_richtext_facet() + } + fn validate(&self) -> Result<(), jacquard_lexicon::validation::ConstraintError> { + { + let value = &self.byte_end; + if *value < 0i64 { + return Err(jacquard_lexicon::validation::ConstraintError::Minimum { + path: jacquard_lexicon::validation::ValidationPath::from_field( + "byte_end", + ), + min: 0i64, + actual: *value, + }); + } + } + { + let value = &self.byte_start; + if *value < 0i64 { + return Err(jacquard_lexicon::validation::ConstraintError::Minimum { + path: jacquard_lexicon::validation::ValidationPath::from_field( + "byte_start", + ), + min: 0i64, + actual: *value, + }); + } + } + Ok(()) + } +} + +impl jacquard_lexicon::schema::LexiconSchema for Link { + fn nsid() -> &'static str { + "app.bsky.richtext.facet" + } + fn def_name() -> &'static str { + "link" + } + fn lexicon_doc() -> jacquard_lexicon::lexicon::LexiconDoc<'static> { + lexicon_doc_app_bsky_richtext_facet() + } + fn validate(&self) -> Result<(), jacquard_lexicon::validation::ConstraintError> { + Ok(()) + } +} + +impl jacquard_lexicon::schema::LexiconSchema for Facet { + fn nsid() -> &'static str { + "app.bsky.richtext.facet" + } + fn def_name() -> &'static str { + "main" + } + fn lexicon_doc() -> jacquard_lexicon::lexicon::LexiconDoc<'static> { + lexicon_doc_app_bsky_richtext_facet() + } + fn validate(&self) -> Result<(), jacquard_lexicon::validation::ConstraintError> { + Ok(()) + } +} + +impl jacquard_lexicon::schema::LexiconSchema for Mention { + fn nsid() -> &'static str { + "app.bsky.richtext.facet" + } + fn def_name() -> &'static str { + "mention" + } + fn lexicon_doc() -> jacquard_lexicon::lexicon::LexiconDoc<'static> { + lexicon_doc_app_bsky_richtext_facet() + } + fn validate(&self) -> Result<(), jacquard_lexicon::validation::ConstraintError> { + Ok(()) + } +} + +impl jacquard_lexicon::schema::LexiconSchema for Tag { + fn nsid() -> &'static str { + "app.bsky.richtext.facet" + } + fn def_name() -> &'static str { + "tag" + } + fn lexicon_doc() -> jacquard_lexicon::lexicon::LexiconDoc<'static> { + lexicon_doc_app_bsky_richtext_facet() + } + fn validate(&self) -> Result<(), jacquard_lexicon::validation::ConstraintError> { + { + let value = &self.tag; + #[allow(unused_comparisons)] + if ::len(value.as_ref()) > 640usize { + return Err(jacquard_lexicon::validation::ConstraintError::MaxLength { + path: jacquard_lexicon::validation::ValidationPath::from_field( + "tag", + ), + max: 640usize, + actual: ::len(value.as_ref()), + }); + } + } + { + let value = &self.tag; + { + let count = jacquard_common::deps::codegen::unicode_segmentation::UnicodeSegmentation::graphemes( + value.as_ref(), + true, + ) + .count(); + if count > 64usize { + return Err(jacquard_lexicon::validation::ConstraintError::MaxGraphemes { + path: jacquard_lexicon::validation::ValidationPath::from_field( + "tag", + ), + max: 64usize, + actual: count, + }); + } + } + } + Ok(()) + } +} + +pub mod byte_slice_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 ByteEnd; + type ByteStart; + } + /// Empty state - all required fields are unset + pub struct Empty(()); + impl sealed::Sealed for Empty {} + impl State for Empty { + type ByteEnd = Unset; + type ByteStart = Unset; + } + ///State transition - sets the `byte_end` field to Set + pub struct SetByteEnd(PhantomData St>); + impl sealed::Sealed for SetByteEnd {} + impl State for SetByteEnd { + type ByteEnd = Set; + type ByteStart = St::ByteStart; + } + ///State transition - sets the `byte_start` field to Set + pub struct SetByteStart(PhantomData St>); + impl sealed::Sealed for SetByteStart {} + impl State for SetByteStart { + type ByteEnd = St::ByteEnd; + type ByteStart = Set; + } + /// Marker types for field names + #[allow(non_camel_case_types)] + pub mod members { + ///Marker type for the `byte_end` field + pub struct byte_end(()); + ///Marker type for the `byte_start` field + pub struct byte_start(()); + } +} + +/// Builder for constructing an instance of this type. +pub struct ByteSliceBuilder { + _state: ::core::marker::PhantomData St>, + _fields: (core::option::Option, core::option::Option), + _type: ::core::marker::PhantomData S>, +} + +impl ByteSlice { + /// Create a new builder for this type. + pub fn new() -> ByteSliceBuilder { + ByteSliceBuilder::new() + } +} + +impl ByteSliceBuilder { + /// Create a new builder with all fields unset. + pub fn new() -> Self { + ByteSliceBuilder { + _state: ::core::marker::PhantomData, + _fields: (None, None), + _type: ::core::marker::PhantomData, + } + } +} + +impl ByteSliceBuilder +where + St: byte_slice_state::State, + St::ByteEnd: byte_slice_state::IsUnset, +{ + /// Set the `byteEnd` field (required) + pub fn byte_end( + mut self, + value: impl Into, + ) -> ByteSliceBuilder> { + self._fields.0 = ::core::option::Option::Some(value.into()); + ByteSliceBuilder { + _state: ::core::marker::PhantomData, + _fields: self._fields, + _type: ::core::marker::PhantomData, + } + } +} + +impl ByteSliceBuilder +where + St: byte_slice_state::State, + St::ByteStart: byte_slice_state::IsUnset, +{ + /// Set the `byteStart` field (required) + pub fn byte_start( + mut self, + value: impl Into, + ) -> ByteSliceBuilder> { + self._fields.1 = ::core::option::Option::Some(value.into()); + ByteSliceBuilder { + _state: ::core::marker::PhantomData, + _fields: self._fields, + _type: ::core::marker::PhantomData, + } + } +} + +impl ByteSliceBuilder +where + St: byte_slice_state::State, + St::ByteEnd: byte_slice_state::IsSet, + St::ByteStart: byte_slice_state::IsSet, +{ + /// Build the final struct. + pub fn build(self) -> ByteSlice { + ByteSlice { + byte_end: self._fields.0.unwrap(), + byte_start: self._fields.1.unwrap(), + extra_data: Default::default(), + } + } + /// Build the final struct with custom extra_data. + pub fn build_with_data( + self, + extra_data: alloc::collections::BTreeMap< + jacquard_common::deps::smol_str::SmolStr, + jacquard_common::types::value::Data, + >, + ) -> ByteSlice { + ByteSlice { + byte_end: self._fields.0.unwrap(), + byte_start: self._fields.1.unwrap(), + extra_data: Some(extra_data), + } + } +} + +fn lexicon_doc_app_bsky_richtext_facet() -> jacquard_lexicon::lexicon::LexiconDoc< + 'static, +> { + ::jacquard_lexicon::lexicon::LexiconDoc { + lexicon: ::jacquard_lexicon::lexicon::Lexicon::Lexicon1, + id: ::jacquard_common::CowStr::new_static("app.bsky.richtext.facet"), + defs: { + let mut map = ::alloc::collections::BTreeMap::new(); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static("byteSlice"), + ::jacquard_lexicon::lexicon::LexUserType::Object(::jacquard_lexicon::lexicon::LexObject { + description: Some( + ::jacquard_common::CowStr::new_static( + "Specifies the sub-string range a facet feature applies to. Start index is inclusive, end index is exclusive. Indices are zero-indexed, counting bytes of the UTF-8 encoded text. NOTE: some languages, like Javascript, use UTF-16 or Unicode codepoints for string slice indexing; in these languages, convert to byte arrays before working with facets.", + ), + ), + required: Some( + vec![ + ::jacquard_common::deps::smol_str::SmolStr::new_static("byteStart"), + ::jacquard_common::deps::smol_str::SmolStr::new_static("byteEnd") + ], + ), + properties: { + #[allow(unused_mut)] + let mut map = ::alloc::collections::BTreeMap::new(); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "byteEnd", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::Integer(::jacquard_lexicon::lexicon::LexInteger { + minimum: Some(0i64), + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "byteStart", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::Integer(::jacquard_lexicon::lexicon::LexInteger { + minimum: Some(0i64), + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static("link"), + ::jacquard_lexicon::lexicon::LexUserType::Object(::jacquard_lexicon::lexicon::LexObject { + description: Some( + ::jacquard_common::CowStr::new_static( + "Facet feature for a URL. The text URL may have been simplified or truncated, but the facet reference should be a complete URL.", + ), + ), + required: Some( + vec![ + ::jacquard_common::deps::smol_str::SmolStr::new_static("uri") + ], + ), + properties: { + #[allow(unused_mut)] + let mut map = ::alloc::collections::BTreeMap::new(); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "uri", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { + format: Some( + ::jacquard_lexicon::lexicon::LexStringFormat::Uri, + ), + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static("main"), + ::jacquard_lexicon::lexicon::LexUserType::Object(::jacquard_lexicon::lexicon::LexObject { + description: Some( + ::jacquard_common::CowStr::new_static( + "Annotation of a sub-string within rich text.", + ), + ), + required: Some( + vec![ + ::jacquard_common::deps::smol_str::SmolStr::new_static("index"), + ::jacquard_common::deps::smol_str::SmolStr::new_static("features") + ], + ), + properties: { + #[allow(unused_mut)] + let mut map = ::alloc::collections::BTreeMap::new(); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "features", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::Array(::jacquard_lexicon::lexicon::LexArray { + items: ::jacquard_lexicon::lexicon::LexArrayItem::Union(::jacquard_lexicon::lexicon::LexRefUnion { + refs: vec![ + ::jacquard_common::CowStr::new_static("#mention"), + ::jacquard_common::CowStr::new_static("#link"), + ::jacquard_common::CowStr::new_static("#tag") + ], + ..Default::default() + }), + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "index", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::Ref(::jacquard_lexicon::lexicon::LexRef { + r#ref: ::jacquard_common::CowStr::new_static("#byteSlice"), + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static("mention"), + ::jacquard_lexicon::lexicon::LexUserType::Object(::jacquard_lexicon::lexicon::LexObject { + description: Some( + ::jacquard_common::CowStr::new_static( + "Facet feature for mention of another account. The text is usually a handle, including a '@' prefix, but the facet reference is a DID.", + ), + ), + required: Some( + vec![ + ::jacquard_common::deps::smol_str::SmolStr::new_static("did") + ], + ), + properties: { + #[allow(unused_mut)] + let mut map = ::alloc::collections::BTreeMap::new(); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "did", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { + format: Some( + ::jacquard_lexicon::lexicon::LexStringFormat::Did, + ), + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static("tag"), + ::jacquard_lexicon::lexicon::LexUserType::Object(::jacquard_lexicon::lexicon::LexObject { + description: Some( + ::jacquard_common::CowStr::new_static( + "Facet feature for a hashtag. The text usually includes a '#' prefix, but the facet reference should not (except in the case of 'double hash tags').", + ), + ), + required: Some( + vec![ + ::jacquard_common::deps::smol_str::SmolStr::new_static("tag") + ], + ), + properties: { + #[allow(unused_mut)] + let mut map = ::alloc::collections::BTreeMap::new(); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "tag", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { + max_length: Some(640usize), + max_graphemes: Some(64usize), + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map + }, + ..Default::default() + } +} + +pub mod link_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 Uri; + } + /// Empty state - all required fields are unset + pub struct Empty(()); + impl sealed::Sealed for Empty {} + impl State for Empty { + type Uri = Unset; + } + ///State transition - sets the `uri` field to Set + pub struct SetUri(PhantomData St>); + impl sealed::Sealed for SetUri {} + impl State for SetUri { + type Uri = Set; + } + /// Marker types for field names + #[allow(non_camel_case_types)] + pub mod members { + ///Marker type for the `uri` field + pub struct uri(()); + } +} + +/// Builder for constructing an instance of this type. +pub struct LinkBuilder { + _state: ::core::marker::PhantomData St>, + _fields: (core::option::Option>,), + _type: ::core::marker::PhantomData S>, +} + +impl Link { + /// Create a new builder for this type. + pub fn new() -> LinkBuilder { + LinkBuilder::new() + } +} + +impl LinkBuilder { + /// Create a new builder with all fields unset. + pub fn new() -> Self { + LinkBuilder { + _state: ::core::marker::PhantomData, + _fields: (None,), + _type: ::core::marker::PhantomData, + } + } +} + +impl LinkBuilder +where + St: link_state::State, + St::Uri: link_state::IsUnset, +{ + /// Set the `uri` field (required) + pub fn uri( + mut self, + value: impl Into>, + ) -> LinkBuilder> { + self._fields.0 = ::core::option::Option::Some(value.into()); + LinkBuilder { + _state: ::core::marker::PhantomData, + _fields: self._fields, + _type: ::core::marker::PhantomData, + } + } +} + +impl LinkBuilder +where + St: link_state::State, + St::Uri: link_state::IsSet, +{ + /// Build the final struct. + pub fn build(self) -> Link { + Link { + uri: self._fields.0.unwrap(), + extra_data: Default::default(), + } + } + /// Build the final struct with custom extra_data. + pub fn build_with_data( + self, + extra_data: alloc::collections::BTreeMap< + jacquard_common::deps::smol_str::SmolStr, + jacquard_common::types::value::Data, + >, + ) -> Link { + Link { + uri: self._fields.0.unwrap(), + extra_data: Some(extra_data), + } + } +} + +pub mod facet_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 Features; + type Index; + } + /// Empty state - all required fields are unset + pub struct Empty(()); + impl sealed::Sealed for Empty {} + impl State for Empty { + type Features = Unset; + type Index = Unset; + } + ///State transition - sets the `features` field to Set + pub struct SetFeatures(PhantomData St>); + impl sealed::Sealed for SetFeatures {} + impl State for SetFeatures { + type Features = Set; + type Index = St::Index; + } + ///State transition - sets the `index` field to Set + pub struct SetIndex(PhantomData St>); + impl sealed::Sealed for SetIndex {} + impl State for SetIndex { + type Features = St::Features; + type Index = Set; + } + /// Marker types for field names + #[allow(non_camel_case_types)] + pub mod members { + ///Marker type for the `features` field + pub struct features(()); + ///Marker type for the `index` field + pub struct index(()); + } +} + +/// Builder for constructing an instance of this type. +pub struct FacetBuilder { + _state: ::core::marker::PhantomData St>, + _fields: ( + core::option::Option>>, + core::option::Option>, + ), + _type: ::core::marker::PhantomData S>, +} + +impl Facet { + /// Create a new builder for this type. + pub fn new() -> FacetBuilder { + FacetBuilder::new() + } +} + +impl FacetBuilder { + /// Create a new builder with all fields unset. + pub fn new() -> Self { + FacetBuilder { + _state: ::core::marker::PhantomData, + _fields: (None, None), + _type: ::core::marker::PhantomData, + } + } +} + +impl FacetBuilder +where + St: facet_state::State, + St::Features: facet_state::IsUnset, +{ + /// Set the `features` field (required) + pub fn features( + mut self, + value: impl Into>>, + ) -> FacetBuilder> { + self._fields.0 = ::core::option::Option::Some(value.into()); + FacetBuilder { + _state: ::core::marker::PhantomData, + _fields: self._fields, + _type: ::core::marker::PhantomData, + } + } +} + +impl FacetBuilder +where + St: facet_state::State, + St::Index: facet_state::IsUnset, +{ + /// Set the `index` field (required) + pub fn index( + mut self, + value: impl Into>, + ) -> FacetBuilder> { + self._fields.1 = ::core::option::Option::Some(value.into()); + FacetBuilder { + _state: ::core::marker::PhantomData, + _fields: self._fields, + _type: ::core::marker::PhantomData, + } + } +} + +impl FacetBuilder +where + St: facet_state::State, + St::Features: facet_state::IsSet, + St::Index: facet_state::IsSet, +{ + /// Build the final struct. + pub fn build(self) -> Facet { + Facet { + features: self._fields.0.unwrap(), + index: self._fields.1.unwrap(), + extra_data: Default::default(), + } + } + /// Build the final struct with custom extra_data. + pub fn build_with_data( + self, + extra_data: alloc::collections::BTreeMap< + jacquard_common::deps::smol_str::SmolStr, + jacquard_common::types::value::Data, + >, + ) -> Facet { + Facet { + features: self._fields.0.unwrap(), + index: self._fields.1.unwrap(), + extra_data: Some(extra_data), + } + } +} + +pub mod mention_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 Did; + } + /// Empty state - all required fields are unset + pub struct Empty(()); + impl sealed::Sealed for Empty {} + impl State for Empty { + type Did = Unset; + } + ///State transition - sets the `did` field to Set + pub struct SetDid(PhantomData St>); + impl sealed::Sealed for SetDid {} + impl State for SetDid { + type Did = Set; + } + /// Marker types for field names + #[allow(non_camel_case_types)] + pub mod members { + ///Marker type for the `did` field + pub struct did(()); + } +} + +/// Builder for constructing an instance of this type. +pub struct MentionBuilder { + _state: ::core::marker::PhantomData St>, + _fields: (core::option::Option>,), + _type: ::core::marker::PhantomData S>, +} + +impl Mention { + /// Create a new builder for this type. + pub fn new() -> MentionBuilder { + MentionBuilder::new() + } +} + +impl MentionBuilder { + /// Create a new builder with all fields unset. + pub fn new() -> Self { + MentionBuilder { + _state: ::core::marker::PhantomData, + _fields: (None,), + _type: ::core::marker::PhantomData, + } + } +} + +impl MentionBuilder +where + St: mention_state::State, + St::Did: mention_state::IsUnset, +{ + /// Set the `did` field (required) + pub fn did( + mut self, + value: impl Into>, + ) -> MentionBuilder> { + self._fields.0 = ::core::option::Option::Some(value.into()); + MentionBuilder { + _state: ::core::marker::PhantomData, + _fields: self._fields, + _type: ::core::marker::PhantomData, + } + } +} + +impl MentionBuilder +where + St: mention_state::State, + St::Did: mention_state::IsSet, +{ + /// Build the final struct. + pub fn build(self) -> Mention { + Mention { + did: self._fields.0.unwrap(), + extra_data: Default::default(), + } + } + /// Build the final struct with custom extra_data. + pub fn build_with_data( + self, + extra_data: alloc::collections::BTreeMap< + jacquard_common::deps::smol_str::SmolStr, + jacquard_common::types::value::Data, + >, + ) -> Mention { + Mention { + did: self._fields.0.unwrap(), + extra_data: Some(extra_data), + } + } +} \ No newline at end of file diff --git a/crates/jacquard-codegen-tests/src/generated/macro_mode/builder_types.rs b/crates/jacquard-codegen-tests/src/generated/macro_mode/builder_types.rs new file mode 100644 index 00000000..cd45c2e4 --- /dev/null +++ b/crates/jacquard-codegen-tests/src/generated/macro_mode/builder_types.rs @@ -0,0 +1,45 @@ +// @generated by jacquard-lexicon. DO NOT EDIT. +// +// This file was automatically generated from Lexicon schemas. +// Any manual changes will be overwritten on the next regeneration. + +/// Marker type indicating a builder field has been set +pub struct Set(pub T); +impl Set { + /// Extract the inner value + #[inline] + pub fn into_inner(self) -> T { + self.0 + } +} + +/// Marker type indicating a builder field has not been set +pub struct Unset; +/// Trait indicating a builder field is set (has a value) + +#[jacquard_common::deps::codegen::rustversion::attr( + since(1.78.0), + diagnostic::on_unimplemented( + message = "the field `{Self}` was not set, but this method requires it to be set", + label = "the field `{Self}` was not set" + ) +)] +pub trait IsSet: private::Sealed {} +/// Trait indicating a builder field is unset (no value yet) + +#[jacquard_common::deps::codegen::rustversion::attr( + since(1.78.0), + diagnostic::on_unimplemented( + message = "the field `{Self}` was already set, but this method requires it to be unset", + label = "the field `{Self}` was already set" + ) +)] +pub trait IsUnset: private::Sealed {} +impl IsSet for Set {} +impl IsUnset for Unset {} +mod private { + /// Sealed trait to prevent external implementations + pub trait Sealed {} + impl Sealed for super::Set {} + impl Sealed for super::Unset {} +} \ No newline at end of file diff --git a/crates/jacquard-codegen-tests/src/generated/macro_mode/com_atproto.rs b/crates/jacquard-codegen-tests/src/generated/macro_mode/com_atproto.rs new file mode 100644 index 00000000..09e30369 --- /dev/null +++ b/crates/jacquard-codegen-tests/src/generated/macro_mode/com_atproto.rs @@ -0,0 +1,7 @@ +// @generated by jacquard-lexicon. DO NOT EDIT. +// +// This file was automatically generated from Lexicon schemas. +// Any manual changes will be overwritten on the next regeneration. + +pub mod label; +pub mod repo; \ No newline at end of file diff --git a/crates/jacquard-codegen-tests/src/generated/macro_mode/com_atproto/label.rs b/crates/jacquard-codegen-tests/src/generated/macro_mode/com_atproto/label.rs new file mode 100644 index 00000000..1800f142 --- /dev/null +++ b/crates/jacquard-codegen-tests/src/generated/macro_mode/com_atproto/label.rs @@ -0,0 +1,2077 @@ +// @generated by jacquard-lexicon. DO NOT EDIT. +// +// Lexicon: com.atproto.label.defs +// +// This file was automatically generated from Lexicon schemas. +// Any manual changes will be overwritten on the next regeneration. + +/// Metadata tag on an atproto resource (eg, repo or record). + +#[derive( + serde::Serialize, + serde::Deserialize, + Debug, + Clone, + PartialEq, + Eq, + jacquard_derive::IntoStatic +)] + +#[serde( + rename_all = "camelCase", + bound(deserialize = "S: serde::Deserialize<'de> + jacquard_common::BosStr") +)] +pub struct Label { + ///Optionally, CID specifying the specific version of 'uri' resource this label applies to. + #[serde(skip_serializing_if = "core::option::Option::is_none")] + pub cid: core::option::Option>, + ///Timestamp when this label was created. + pub cts: jacquard_common::types::string::Datetime, + ///Timestamp at which this label expires (no longer applies). + #[serde(skip_serializing_if = "core::option::Option::is_none")] + pub exp: core::option::Option, + ///If true, this is a negation label, overwriting a previous label. + #[serde(skip_serializing_if = "core::option::Option::is_none")] + pub neg: core::option::Option, + ///Signature of dag-cbor encoded label. + #[serde(skip_serializing_if = "core::option::Option::is_none")] + #[serde(default, with = "jacquard_common::opt_serde_bytes_helper")] + pub sig: core::option::Option, + ///DID of the actor who created this label. + pub src: jacquard_common::types::string::Did, + ///AT URI of the record, repository (account), or other resource that this label applies to. + pub uri: jacquard_common::types::string::UriValue, + ///The short string name of the value or type of this label. + pub val: S, + ///The AT Protocol version of the label object. + #[serde(skip_serializing_if = "core::option::Option::is_none")] + pub ver: core::option::Option, + #[serde(flatten, default, skip_serializing_if = "core::option::Option::is_none")] + pub extra_data: core::option::Option< + alloc::collections::BTreeMap< + jacquard_common::deps::smol_str::SmolStr, + jacquard_common::types::value::Data, + >, + >, +} + + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum LabelValue { + Hide, + NoPromote, + Warn, + NoUnauthenticated, + DmcaViolation, + Doxxing, + Porn, + Sexual, + Nudity, + Nsfl, + Gore, + Other(S), +} + +impl LabelValue { + pub fn as_str(&self) -> &str { + match self { + Self::Hide => "!hide", + Self::NoPromote => "!no-promote", + Self::Warn => "!warn", + Self::NoUnauthenticated => "!no-unauthenticated", + Self::DmcaViolation => "dmca-violation", + Self::Doxxing => "doxxing", + Self::Porn => "porn", + Self::Sexual => "sexual", + Self::Nudity => "nudity", + Self::Nsfl => "nsfl", + Self::Gore => "gore", + 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() { + "!hide" => Self::Hide, + "!no-promote" => Self::NoPromote, + "!warn" => Self::Warn, + "!no-unauthenticated" => Self::NoUnauthenticated, + "dmca-violation" => Self::DmcaViolation, + "doxxing" => Self::Doxxing, + "porn" => Self::Porn, + "sexual" => Self::Sexual, + "nudity" => Self::Nudity, + "nsfl" => Self::Nsfl, + "gore" => Self::Gore, + _ => Self::Other(s), + } + } +} + +impl AsRef for LabelValue { + fn as_ref(&self) -> &str { + self.as_str() + } +} + +impl core::fmt::Display for LabelValue { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, "{}", self.as_str()) + } +} + +impl serde::Serialize for LabelValue { + fn serialize(&self, serializer: Ser) -> Result + where + Ser: serde::Serializer, + { + serializer.serialize_str(self.as_str()) + } +} + +impl<'de, S: serde::Deserialize<'de> + jacquard_common::BosStr> serde::Deserialize<'de> +for LabelValue { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let s = S::deserialize(deserializer)?; + Ok(Self::from_value(s)) + } +} + +impl jacquard_common::IntoStatic for LabelValue +where + S: jacquard_common::BosStr + jacquard_common::IntoStatic, + S::Output: jacquard_common::BosStr, +{ + type Output = LabelValue; + fn into_static(self) -> Self::Output { + match self { + LabelValue::Hide => LabelValue::Hide, + LabelValue::NoPromote => LabelValue::NoPromote, + LabelValue::Warn => LabelValue::Warn, + LabelValue::NoUnauthenticated => LabelValue::NoUnauthenticated, + LabelValue::DmcaViolation => LabelValue::DmcaViolation, + LabelValue::Doxxing => LabelValue::Doxxing, + LabelValue::Porn => LabelValue::Porn, + LabelValue::Sexual => LabelValue::Sexual, + LabelValue::Nudity => LabelValue::Nudity, + LabelValue::Nsfl => LabelValue::Nsfl, + LabelValue::Gore => LabelValue::Gore, + LabelValue::Other(v) => LabelValue::Other(v.into_static()), + } + } +} + +/// Declares a label value and its expected interpretations and behaviors. + +#[derive( + serde::Serialize, + serde::Deserialize, + Debug, + Clone, + PartialEq, + Eq, + jacquard_derive::IntoStatic +)] + +#[serde( + rename_all = "camelCase", + bound(deserialize = "S: serde::Deserialize<'de> + jacquard_common::BosStr") +)] +pub struct LabelValueDefinition< + S: jacquard_common::BosStr = jacquard_common::DefaultStr, +> { + ///Does the user need to have adult content enabled in order to configure this label? + #[serde(skip_serializing_if = "core::option::Option::is_none")] + pub adult_only: core::option::Option, + ///What should this label hide in the UI, if applied? 'content' hides all of the target; 'media' hides the images/video/audio; 'none' hides nothing. + pub blurs: LabelValueDefinitionBlurs, + ///The default setting for this label. + #[serde(skip_serializing_if = "core::option::Option::is_none")] + pub default_setting: core::option::Option>, + ///The value of the label being defined. Must only include lowercase ascii and the '-' character ([a-z-]+). + pub identifier: S, + pub locales: Vec< + crate::macro_mode::com_atproto::label::LabelValueDefinitionStrings, + >, + ///How should a client visually convey this label? 'inform' means neutral and informational; 'alert' means negative and warning; 'none' means show nothing. + pub severity: LabelValueDefinitionSeverity, + #[serde(flatten, default, skip_serializing_if = "core::option::Option::is_none")] + pub extra_data: core::option::Option< + alloc::collections::BTreeMap< + jacquard_common::deps::smol_str::SmolStr, + jacquard_common::types::value::Data, + >, + >, +} + +/// What should this label hide in the UI, if applied? 'content' hides all of the target; 'media' hides the images/video/audio; 'none' hides nothing. + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum LabelValueDefinitionBlurs< + S: jacquard_common::BosStr = jacquard_common::DefaultStr, +> { + Content, + Media, + None, + Other(S), +} + +impl LabelValueDefinitionBlurs { + pub fn as_str(&self) -> &str { + match self { + Self::Content => "content", + Self::Media => "media", + Self::None => "none", + 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() { + "content" => Self::Content, + "media" => Self::Media, + "none" => Self::None, + _ => Self::Other(s), + } + } +} + +impl core::fmt::Display for LabelValueDefinitionBlurs { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, "{}", self.as_str()) + } +} + +impl AsRef for LabelValueDefinitionBlurs { + fn as_ref(&self) -> &str { + self.as_str() + } +} + +impl serde::Serialize for LabelValueDefinitionBlurs { + fn serialize(&self, serializer: Ser) -> Result + where + Ser: serde::Serializer, + { + serializer.serialize_str(self.as_str()) + } +} + +impl<'de, S: serde::Deserialize<'de> + jacquard_common::BosStr> serde::Deserialize<'de> +for LabelValueDefinitionBlurs { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let s = S::deserialize(deserializer)?; + Ok(Self::from_value(s)) + } +} + +impl Default for LabelValueDefinitionBlurs { + fn default() -> Self { + Self::Other(Default::default()) + } +} + +impl jacquard_common::IntoStatic +for LabelValueDefinitionBlurs +where + S: jacquard_common::BosStr + jacquard_common::IntoStatic, + S::Output: jacquard_common::BosStr, +{ + type Output = LabelValueDefinitionBlurs; + fn into_static(self) -> Self::Output { + match self { + LabelValueDefinitionBlurs::Content => LabelValueDefinitionBlurs::Content, + LabelValueDefinitionBlurs::Media => LabelValueDefinitionBlurs::Media, + LabelValueDefinitionBlurs::None => LabelValueDefinitionBlurs::None, + LabelValueDefinitionBlurs::Other(v) => { + LabelValueDefinitionBlurs::Other(v.into_static()) + } + } + } +} + +/// The default setting for this label. + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum LabelValueDefinitionDefaultSetting< + S: jacquard_common::BosStr = jacquard_common::DefaultStr, +> { + Ignore, + Warn, + Hide, + Other(S), +} + +impl LabelValueDefinitionDefaultSetting { + pub fn as_str(&self) -> &str { + match self { + Self::Ignore => "ignore", + Self::Warn => "warn", + Self::Hide => "hide", + 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() { + "ignore" => Self::Ignore, + "warn" => Self::Warn, + "hide" => Self::Hide, + _ => Self::Other(s), + } + } +} + +impl core::fmt::Display +for LabelValueDefinitionDefaultSetting { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, "{}", self.as_str()) + } +} + +impl AsRef for LabelValueDefinitionDefaultSetting { + fn as_ref(&self) -> &str { + self.as_str() + } +} + +impl serde::Serialize +for LabelValueDefinitionDefaultSetting { + fn serialize(&self, serializer: Ser) -> Result + where + Ser: serde::Serializer, + { + serializer.serialize_str(self.as_str()) + } +} + +impl<'de, S: serde::Deserialize<'de> + jacquard_common::BosStr> serde::Deserialize<'de> +for LabelValueDefinitionDefaultSetting { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let s = S::deserialize(deserializer)?; + Ok(Self::from_value(s)) + } +} + +impl Default +for LabelValueDefinitionDefaultSetting { + fn default() -> Self { + Self::Other(Default::default()) + } +} + +impl jacquard_common::IntoStatic +for LabelValueDefinitionDefaultSetting +where + S: jacquard_common::BosStr + jacquard_common::IntoStatic, + S::Output: jacquard_common::BosStr, +{ + type Output = LabelValueDefinitionDefaultSetting; + fn into_static(self) -> Self::Output { + match self { + LabelValueDefinitionDefaultSetting::Ignore => { + LabelValueDefinitionDefaultSetting::Ignore + } + LabelValueDefinitionDefaultSetting::Warn => { + LabelValueDefinitionDefaultSetting::Warn + } + LabelValueDefinitionDefaultSetting::Hide => { + LabelValueDefinitionDefaultSetting::Hide + } + LabelValueDefinitionDefaultSetting::Other(v) => { + LabelValueDefinitionDefaultSetting::Other(v.into_static()) + } + } + } +} + +/// How should a client visually convey this label? 'inform' means neutral and informational; 'alert' means negative and warning; 'none' means show nothing. + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum LabelValueDefinitionSeverity< + S: jacquard_common::BosStr = jacquard_common::DefaultStr, +> { + Inform, + Alert, + None, + Other(S), +} + +impl LabelValueDefinitionSeverity { + pub fn as_str(&self) -> &str { + match self { + Self::Inform => "inform", + Self::Alert => "alert", + Self::None => "none", + 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() { + "inform" => Self::Inform, + "alert" => Self::Alert, + "none" => Self::None, + _ => Self::Other(s), + } + } +} + +impl core::fmt::Display for LabelValueDefinitionSeverity { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, "{}", self.as_str()) + } +} + +impl AsRef for LabelValueDefinitionSeverity { + fn as_ref(&self) -> &str { + self.as_str() + } +} + +impl serde::Serialize for LabelValueDefinitionSeverity { + fn serialize(&self, serializer: Ser) -> Result + where + Ser: serde::Serializer, + { + serializer.serialize_str(self.as_str()) + } +} + +impl<'de, S: serde::Deserialize<'de> + jacquard_common::BosStr> serde::Deserialize<'de> +for LabelValueDefinitionSeverity { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let s = S::deserialize(deserializer)?; + Ok(Self::from_value(s)) + } +} + +impl Default for LabelValueDefinitionSeverity { + fn default() -> Self { + Self::Other(Default::default()) + } +} + +impl jacquard_common::IntoStatic +for LabelValueDefinitionSeverity +where + S: jacquard_common::BosStr + jacquard_common::IntoStatic, + S::Output: jacquard_common::BosStr, +{ + type Output = LabelValueDefinitionSeverity; + fn into_static(self) -> Self::Output { + match self { + LabelValueDefinitionSeverity::Inform => LabelValueDefinitionSeverity::Inform, + LabelValueDefinitionSeverity::Alert => LabelValueDefinitionSeverity::Alert, + LabelValueDefinitionSeverity::None => LabelValueDefinitionSeverity::None, + LabelValueDefinitionSeverity::Other(v) => { + LabelValueDefinitionSeverity::Other(v.into_static()) + } + } + } +} + +/// Strings which describe the label in the UI, localized into a specific language. + +#[derive( + serde::Serialize, + serde::Deserialize, + Debug, + Clone, + PartialEq, + Eq, + jacquard_derive::IntoStatic +)] + +#[serde( + rename_all = "camelCase", + bound(deserialize = "S: serde::Deserialize<'de> + jacquard_common::BosStr") +)] +pub struct LabelValueDefinitionStrings< + S: jacquard_common::BosStr = jacquard_common::DefaultStr, +> { + ///A longer description of what the label means and why it might be applied. + pub description: S, + ///The code of the language these strings are written in. + pub lang: jacquard_common::types::string::Language, + ///A short human-readable name for the label. + pub name: S, + #[serde(flatten, default, skip_serializing_if = "core::option::Option::is_none")] + pub extra_data: core::option::Option< + alloc::collections::BTreeMap< + jacquard_common::deps::smol_str::SmolStr, + jacquard_common::types::value::Data, + >, + >, +} + +/// Metadata tag on an atproto record, published by the author within the record. Note that schemas should use #selfLabels, not #selfLabel. + +#[derive( + serde::Serialize, + serde::Deserialize, + Debug, + Clone, + PartialEq, + Eq, + jacquard_derive::IntoStatic, + Default +)] + +#[serde( + rename_all = "camelCase", + bound(deserialize = "S: serde::Deserialize<'de> + jacquard_common::BosStr") +)] +pub struct SelfLabel { + ///The short string name of the value or type of this label. + pub val: S, + #[serde(flatten, default, skip_serializing_if = "core::option::Option::is_none")] + pub extra_data: core::option::Option< + alloc::collections::BTreeMap< + jacquard_common::deps::smol_str::SmolStr, + jacquard_common::types::value::Data, + >, + >, +} + +/// Metadata tags on an atproto record, published by the author within the record. + +#[derive( + serde::Serialize, + serde::Deserialize, + Debug, + Clone, + PartialEq, + Eq, + jacquard_derive::IntoStatic +)] + +#[serde( + rename_all = "camelCase", + bound(deserialize = "S: serde::Deserialize<'de> + jacquard_common::BosStr") +)] +pub struct SelfLabels { + pub values: Vec>, + #[serde(flatten, default, skip_serializing_if = "core::option::Option::is_none")] + pub extra_data: core::option::Option< + alloc::collections::BTreeMap< + jacquard_common::deps::smol_str::SmolStr, + jacquard_common::types::value::Data, + >, + >, +} + +impl jacquard_lexicon::schema::LexiconSchema for Label { + fn nsid() -> &'static str { + "com.atproto.label.defs" + } + fn def_name() -> &'static str { + "label" + } + fn lexicon_doc() -> jacquard_lexicon::lexicon::LexiconDoc<'static> { + lexicon_doc_com_atproto_label_defs() + } + fn validate(&self) -> Result<(), jacquard_lexicon::validation::ConstraintError> { + { + let value = &self.val; + #[allow(unused_comparisons)] + if ::len(value.as_ref()) > 128usize { + return Err(jacquard_lexicon::validation::ConstraintError::MaxLength { + path: jacquard_lexicon::validation::ValidationPath::from_field( + "val", + ), + max: 128usize, + actual: ::len(value.as_ref()), + }); + } + } + Ok(()) + } +} + +impl jacquard_lexicon::schema::LexiconSchema +for LabelValueDefinition { + fn nsid() -> &'static str { + "com.atproto.label.defs" + } + fn def_name() -> &'static str { + "labelValueDefinition" + } + fn lexicon_doc() -> jacquard_lexicon::lexicon::LexiconDoc<'static> { + lexicon_doc_com_atproto_label_defs() + } + fn validate(&self) -> Result<(), jacquard_lexicon::validation::ConstraintError> { + { + let value = &self.identifier; + #[allow(unused_comparisons)] + if ::len(value.as_ref()) > 100usize { + return Err(jacquard_lexicon::validation::ConstraintError::MaxLength { + path: jacquard_lexicon::validation::ValidationPath::from_field( + "identifier", + ), + max: 100usize, + actual: ::len(value.as_ref()), + }); + } + } + { + let value = &self.identifier; + { + let count = jacquard_common::deps::codegen::unicode_segmentation::UnicodeSegmentation::graphemes( + value.as_ref(), + true, + ) + .count(); + if count > 100usize { + return Err(jacquard_lexicon::validation::ConstraintError::MaxGraphemes { + path: jacquard_lexicon::validation::ValidationPath::from_field( + "identifier", + ), + max: 100usize, + actual: count, + }); + } + } + } + Ok(()) + } +} + +impl jacquard_lexicon::schema::LexiconSchema +for LabelValueDefinitionStrings { + fn nsid() -> &'static str { + "com.atproto.label.defs" + } + fn def_name() -> &'static str { + "labelValueDefinitionStrings" + } + fn lexicon_doc() -> jacquard_lexicon::lexicon::LexiconDoc<'static> { + lexicon_doc_com_atproto_label_defs() + } + fn validate(&self) -> Result<(), jacquard_lexicon::validation::ConstraintError> { + { + let value = &self.description; + #[allow(unused_comparisons)] + if ::len(value.as_ref()) > 100000usize { + return Err(jacquard_lexicon::validation::ConstraintError::MaxLength { + path: jacquard_lexicon::validation::ValidationPath::from_field( + "description", + ), + max: 100000usize, + actual: ::len(value.as_ref()), + }); + } + } + { + let value = &self.description; + { + let count = jacquard_common::deps::codegen::unicode_segmentation::UnicodeSegmentation::graphemes( + value.as_ref(), + true, + ) + .count(); + if count > 10000usize { + return Err(jacquard_lexicon::validation::ConstraintError::MaxGraphemes { + path: jacquard_lexicon::validation::ValidationPath::from_field( + "description", + ), + max: 10000usize, + actual: count, + }); + } + } + } + { + let value = &self.name; + #[allow(unused_comparisons)] + if ::len(value.as_ref()) > 640usize { + return Err(jacquard_lexicon::validation::ConstraintError::MaxLength { + path: jacquard_lexicon::validation::ValidationPath::from_field( + "name", + ), + max: 640usize, + actual: ::len(value.as_ref()), + }); + } + } + { + let value = &self.name; + { + let count = jacquard_common::deps::codegen::unicode_segmentation::UnicodeSegmentation::graphemes( + value.as_ref(), + true, + ) + .count(); + if count > 64usize { + return Err(jacquard_lexicon::validation::ConstraintError::MaxGraphemes { + path: jacquard_lexicon::validation::ValidationPath::from_field( + "name", + ), + max: 64usize, + actual: count, + }); + } + } + } + Ok(()) + } +} + +impl jacquard_lexicon::schema::LexiconSchema +for SelfLabel { + fn nsid() -> &'static str { + "com.atproto.label.defs" + } + fn def_name() -> &'static str { + "selfLabel" + } + fn lexicon_doc() -> jacquard_lexicon::lexicon::LexiconDoc<'static> { + lexicon_doc_com_atproto_label_defs() + } + fn validate(&self) -> Result<(), jacquard_lexicon::validation::ConstraintError> { + { + let value = &self.val; + #[allow(unused_comparisons)] + if ::len(value.as_ref()) > 128usize { + return Err(jacquard_lexicon::validation::ConstraintError::MaxLength { + path: jacquard_lexicon::validation::ValidationPath::from_field( + "val", + ), + max: 128usize, + actual: ::len(value.as_ref()), + }); + } + } + Ok(()) + } +} + +impl jacquard_lexicon::schema::LexiconSchema +for SelfLabels { + fn nsid() -> &'static str { + "com.atproto.label.defs" + } + fn def_name() -> &'static str { + "selfLabels" + } + fn lexicon_doc() -> jacquard_lexicon::lexicon::LexiconDoc<'static> { + lexicon_doc_com_atproto_label_defs() + } + fn validate(&self) -> Result<(), jacquard_lexicon::validation::ConstraintError> { + { + let value = &self.values; + #[allow(unused_comparisons)] + if value.len() > 10usize { + return Err(jacquard_lexicon::validation::ConstraintError::MaxLength { + path: jacquard_lexicon::validation::ValidationPath::from_field( + "values", + ), + max: 10usize, + actual: value.len(), + }); + } + } + Ok(()) + } +} + +pub mod label_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 Cts; + type Uri; + type Src; + type Val; + } + /// Empty state - all required fields are unset + pub struct Empty(()); + impl sealed::Sealed for Empty {} + impl State for Empty { + type Cts = Unset; + type Uri = Unset; + type Src = Unset; + type Val = Unset; + } + ///State transition - sets the `cts` field to Set + pub struct SetCts(PhantomData St>); + impl sealed::Sealed for SetCts {} + impl State for SetCts { + type Cts = Set; + type Uri = St::Uri; + type Src = St::Src; + type Val = St::Val; + } + ///State transition - sets the `uri` field to Set + pub struct SetUri(PhantomData St>); + impl sealed::Sealed for SetUri {} + impl State for SetUri { + type Cts = St::Cts; + type Uri = Set; + type Src = St::Src; + type Val = St::Val; + } + ///State transition - sets the `src` field to Set + pub struct SetSrc(PhantomData St>); + impl sealed::Sealed for SetSrc {} + impl State for SetSrc { + type Cts = St::Cts; + type Uri = St::Uri; + type Src = Set; + type Val = St::Val; + } + ///State transition - sets the `val` field to Set + pub struct SetVal(PhantomData St>); + impl sealed::Sealed for SetVal {} + impl State for SetVal { + type Cts = St::Cts; + type Uri = St::Uri; + type Src = St::Src; + type Val = Set; + } + /// Marker types for field names + #[allow(non_camel_case_types)] + pub mod members { + ///Marker type for the `cts` field + pub struct cts(()); + ///Marker type for the `uri` field + pub struct uri(()); + ///Marker type for the `src` field + pub struct src(()); + ///Marker type for the `val` field + pub struct val(()); + } +} + +/// Builder for constructing an instance of this type. +pub struct LabelBuilder { + _state: ::core::marker::PhantomData St>, + _fields: ( + core::option::Option>, + core::option::Option, + core::option::Option, + core::option::Option, + core::option::Option, + core::option::Option>, + core::option::Option>, + core::option::Option, + core::option::Option, + ), + _type: ::core::marker::PhantomData S>, +} + +impl Label { + /// Create a new builder for this type. + pub fn new() -> LabelBuilder { + LabelBuilder::new() + } +} + +impl LabelBuilder { + /// Create a new builder with all fields unset. + pub fn new() -> Self { + LabelBuilder { + _state: ::core::marker::PhantomData, + _fields: (None, None, None, None, None, None, None, None, None), + _type: ::core::marker::PhantomData, + } + } +} + +impl LabelBuilder { + /// Set the `cid` field (optional) + pub fn cid( + mut self, + value: impl Into>>, + ) -> Self { + self._fields.0 = value.into(); + self + } + /// Set the `cid` field to an Option value (optional) + pub fn maybe_cid( + mut self, + value: Option>, + ) -> Self { + self._fields.0 = value; + self + } +} + +impl LabelBuilder +where + St: label_state::State, + St::Cts: label_state::IsUnset, +{ + /// Set the `cts` field (required) + pub fn cts( + mut self, + value: impl Into, + ) -> LabelBuilder> { + self._fields.1 = ::core::option::Option::Some(value.into()); + LabelBuilder { + _state: ::core::marker::PhantomData, + _fields: self._fields, + _type: ::core::marker::PhantomData, + } + } +} + +impl LabelBuilder { + /// Set the `exp` field (optional) + pub fn exp( + mut self, + value: impl Into>, + ) -> Self { + self._fields.2 = value.into(); + self + } + /// Set the `exp` field to an Option value (optional) + pub fn maybe_exp( + mut self, + value: Option, + ) -> Self { + self._fields.2 = value; + self + } +} + +impl LabelBuilder { + /// Set the `neg` field (optional) + pub fn neg(mut self, value: impl Into>) -> Self { + self._fields.3 = value.into(); + self + } + /// Set the `neg` field to an Option value (optional) + pub fn maybe_neg(mut self, value: Option) -> Self { + self._fields.3 = value; + self + } +} + +impl LabelBuilder { + /// Set the `sig` field (optional) + pub fn sig( + mut self, + value: impl Into>, + ) -> Self { + self._fields.4 = value.into(); + self + } + /// Set the `sig` field to an Option value (optional) + pub fn maybe_sig( + mut self, + value: Option, + ) -> Self { + self._fields.4 = value; + self + } +} + +impl LabelBuilder +where + St: label_state::State, + St::Src: label_state::IsUnset, +{ + /// Set the `src` field (required) + pub fn src( + mut self, + value: impl Into>, + ) -> LabelBuilder> { + self._fields.5 = ::core::option::Option::Some(value.into()); + LabelBuilder { + _state: ::core::marker::PhantomData, + _fields: self._fields, + _type: ::core::marker::PhantomData, + } + } +} + +impl LabelBuilder +where + St: label_state::State, + St::Uri: label_state::IsUnset, +{ + /// Set the `uri` field (required) + pub fn uri( + mut self, + value: impl Into>, + ) -> LabelBuilder> { + self._fields.6 = ::core::option::Option::Some(value.into()); + LabelBuilder { + _state: ::core::marker::PhantomData, + _fields: self._fields, + _type: ::core::marker::PhantomData, + } + } +} + +impl LabelBuilder +where + St: label_state::State, + St::Val: label_state::IsUnset, +{ + /// Set the `val` field (required) + pub fn val( + mut self, + value: impl Into, + ) -> LabelBuilder> { + self._fields.7 = ::core::option::Option::Some(value.into()); + LabelBuilder { + _state: ::core::marker::PhantomData, + _fields: self._fields, + _type: ::core::marker::PhantomData, + } + } +} + +impl LabelBuilder { + /// Set the `ver` field (optional) + pub fn ver(mut self, value: impl Into>) -> Self { + self._fields.8 = value.into(); + self + } + /// Set the `ver` field to an Option value (optional) + pub fn maybe_ver(mut self, value: Option) -> Self { + self._fields.8 = value; + self + } +} + +impl LabelBuilder +where + St: label_state::State, + St::Cts: label_state::IsSet, + St::Uri: label_state::IsSet, + St::Src: label_state::IsSet, + St::Val: label_state::IsSet, +{ + /// Build the final struct. + pub fn build(self) -> Label { + Label { + cid: self._fields.0, + cts: self._fields.1.unwrap(), + exp: self._fields.2, + neg: self._fields.3, + sig: self._fields.4, + src: self._fields.5.unwrap(), + uri: self._fields.6.unwrap(), + val: self._fields.7.unwrap(), + ver: self._fields.8, + extra_data: Default::default(), + } + } + /// Build the final struct with custom extra_data. + pub fn build_with_data( + self, + extra_data: alloc::collections::BTreeMap< + jacquard_common::deps::smol_str::SmolStr, + jacquard_common::types::value::Data, + >, + ) -> Label { + Label { + cid: self._fields.0, + cts: self._fields.1.unwrap(), + exp: self._fields.2, + neg: self._fields.3, + sig: self._fields.4, + src: self._fields.5.unwrap(), + uri: self._fields.6.unwrap(), + val: self._fields.7.unwrap(), + ver: self._fields.8, + extra_data: Some(extra_data), + } + } +} + +fn lexicon_doc_com_atproto_label_defs() -> jacquard_lexicon::lexicon::LexiconDoc< + 'static, +> { + ::jacquard_lexicon::lexicon::LexiconDoc { + lexicon: ::jacquard_lexicon::lexicon::Lexicon::Lexicon1, + id: ::jacquard_common::CowStr::new_static("com.atproto.label.defs"), + defs: { + let mut map = ::alloc::collections::BTreeMap::new(); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static("label"), + ::jacquard_lexicon::lexicon::LexUserType::Object(::jacquard_lexicon::lexicon::LexObject { + description: Some( + ::jacquard_common::CowStr::new_static( + "Metadata tag on an atproto resource (eg, repo or record).", + ), + ), + required: Some( + vec![ + ::jacquard_common::deps::smol_str::SmolStr::new_static("src"), + ::jacquard_common::deps::smol_str::SmolStr::new_static("uri"), + ::jacquard_common::deps::smol_str::SmolStr::new_static("val"), + ::jacquard_common::deps::smol_str::SmolStr::new_static("cts") + ], + ), + properties: { + #[allow(unused_mut)] + let mut map = ::alloc::collections::BTreeMap::new(); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "cid", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { + description: Some( + ::jacquard_common::CowStr::new_static( + "Optionally, CID specifying the specific version of 'uri' resource this label applies to.", + ), + ), + format: Some( + ::jacquard_lexicon::lexicon::LexStringFormat::Cid, + ), + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "cts", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { + description: Some( + ::jacquard_common::CowStr::new_static( + "Timestamp when this label was created.", + ), + ), + format: Some( + ::jacquard_lexicon::lexicon::LexStringFormat::Datetime, + ), + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "exp", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { + description: Some( + ::jacquard_common::CowStr::new_static( + "Timestamp at which this label expires (no longer applies).", + ), + ), + format: Some( + ::jacquard_lexicon::lexicon::LexStringFormat::Datetime, + ), + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "neg", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::Boolean(::jacquard_lexicon::lexicon::LexBoolean { + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "sig", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::Bytes(::jacquard_lexicon::lexicon::LexBytes { + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "src", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { + description: Some( + ::jacquard_common::CowStr::new_static( + "DID of the actor who created this label.", + ), + ), + format: Some( + ::jacquard_lexicon::lexicon::LexStringFormat::Did, + ), + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "uri", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { + description: Some( + ::jacquard_common::CowStr::new_static( + "AT URI of the record, repository (account), or other resource that this label applies to.", + ), + ), + format: Some( + ::jacquard_lexicon::lexicon::LexStringFormat::Uri, + ), + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "val", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { + description: Some( + ::jacquard_common::CowStr::new_static( + "The short string name of the value or type of this label.", + ), + ), + max_length: Some(128usize), + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "ver", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::Integer(::jacquard_lexicon::lexicon::LexInteger { + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static("labelValue"), + ::jacquard_lexicon::lexicon::LexUserType::String(::jacquard_lexicon::lexicon::LexString { + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "labelValueDefinition", + ), + ::jacquard_lexicon::lexicon::LexUserType::Object(::jacquard_lexicon::lexicon::LexObject { + description: Some( + ::jacquard_common::CowStr::new_static( + "Declares a label value and its expected interpretations and behaviors.", + ), + ), + required: Some( + vec![ + ::jacquard_common::deps::smol_str::SmolStr::new_static("identifier"), + ::jacquard_common::deps::smol_str::SmolStr::new_static("severity"), + ::jacquard_common::deps::smol_str::SmolStr::new_static("blurs"), + ::jacquard_common::deps::smol_str::SmolStr::new_static("locales") + ], + ), + properties: { + #[allow(unused_mut)] + let mut map = ::alloc::collections::BTreeMap::new(); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "adultOnly", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::Boolean(::jacquard_lexicon::lexicon::LexBoolean { + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "blurs", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { + description: Some( + ::jacquard_common::CowStr::new_static( + "What should this label hide in the UI, if applied? 'content' hides all of the target; 'media' hides the images/video/audio; 'none' hides nothing.", + ), + ), + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "defaultSetting", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { + description: Some( + ::jacquard_common::CowStr::new_static( + "The default setting for this label.", + ), + ), + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "identifier", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { + description: Some( + ::jacquard_common::CowStr::new_static( + "The value of the label being defined. Must only include lowercase ascii and the '-' character ([a-z-]+).", + ), + ), + max_length: Some(100usize), + max_graphemes: Some(100usize), + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "locales", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::Array(::jacquard_lexicon::lexicon::LexArray { + items: ::jacquard_lexicon::lexicon::LexArrayItem::Ref(::jacquard_lexicon::lexicon::LexRef { + r#ref: ::jacquard_common::CowStr::new_static( + "#labelValueDefinitionStrings", + ), + ..Default::default() + }), + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "severity", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { + description: Some( + ::jacquard_common::CowStr::new_static( + "How should a client visually convey this label? 'inform' means neutral and informational; 'alert' means negative and warning; 'none' means show nothing.", + ), + ), + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "labelValueDefinitionStrings", + ), + ::jacquard_lexicon::lexicon::LexUserType::Object(::jacquard_lexicon::lexicon::LexObject { + description: Some( + ::jacquard_common::CowStr::new_static( + "Strings which describe the label in the UI, localized into a specific language.", + ), + ), + required: Some( + vec![ + ::jacquard_common::deps::smol_str::SmolStr::new_static("lang"), + ::jacquard_common::deps::smol_str::SmolStr::new_static("name"), + ::jacquard_common::deps::smol_str::SmolStr::new_static("description") + ], + ), + properties: { + #[allow(unused_mut)] + let mut map = ::alloc::collections::BTreeMap::new(); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "description", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { + description: Some( + ::jacquard_common::CowStr::new_static( + "A longer description of what the label means and why it might be applied.", + ), + ), + max_length: Some(100000usize), + max_graphemes: Some(10000usize), + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "lang", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { + description: Some( + ::jacquard_common::CowStr::new_static( + "The code of the language these strings are written in.", + ), + ), + format: Some( + ::jacquard_lexicon::lexicon::LexStringFormat::Language, + ), + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "name", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { + description: Some( + ::jacquard_common::CowStr::new_static( + "A short human-readable name for the label.", + ), + ), + max_length: Some(640usize), + max_graphemes: Some(64usize), + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static("selfLabel"), + ::jacquard_lexicon::lexicon::LexUserType::Object(::jacquard_lexicon::lexicon::LexObject { + description: Some( + ::jacquard_common::CowStr::new_static( + "Metadata tag on an atproto record, published by the author within the record. Note that schemas should use #selfLabels, not #selfLabel.", + ), + ), + required: Some( + vec![ + ::jacquard_common::deps::smol_str::SmolStr::new_static("val") + ], + ), + properties: { + #[allow(unused_mut)] + let mut map = ::alloc::collections::BTreeMap::new(); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "val", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { + description: Some( + ::jacquard_common::CowStr::new_static( + "The short string name of the value or type of this label.", + ), + ), + max_length: Some(128usize), + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static("selfLabels"), + ::jacquard_lexicon::lexicon::LexUserType::Object(::jacquard_lexicon::lexicon::LexObject { + description: Some( + ::jacquard_common::CowStr::new_static( + "Metadata tags on an atproto record, published by the author within the record.", + ), + ), + required: Some( + vec![ + ::jacquard_common::deps::smol_str::SmolStr::new_static("values") + ], + ), + properties: { + #[allow(unused_mut)] + let mut map = ::alloc::collections::BTreeMap::new(); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "values", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::Array(::jacquard_lexicon::lexicon::LexArray { + items: ::jacquard_lexicon::lexicon::LexArrayItem::Ref(::jacquard_lexicon::lexicon::LexRef { + r#ref: ::jacquard_common::CowStr::new_static("#selfLabel"), + ..Default::default() + }), + max_length: Some(10usize), + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map + }, + ..Default::default() + } +} + +pub mod label_value_definition_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 Locales; + type Severity; + type Blurs; + type Identifier; + } + /// Empty state - all required fields are unset + pub struct Empty(()); + impl sealed::Sealed for Empty {} + impl State for Empty { + type Locales = Unset; + type Severity = Unset; + type Blurs = Unset; + type Identifier = Unset; + } + ///State transition - sets the `locales` field to Set + pub struct SetLocales(PhantomData St>); + impl sealed::Sealed for SetLocales {} + impl State for SetLocales { + type Locales = Set; + type Severity = St::Severity; + type Blurs = St::Blurs; + type Identifier = St::Identifier; + } + ///State transition - sets the `severity` field to Set + pub struct SetSeverity(PhantomData St>); + impl sealed::Sealed for SetSeverity {} + impl State for SetSeverity { + type Locales = St::Locales; + type Severity = Set; + type Blurs = St::Blurs; + type Identifier = St::Identifier; + } + ///State transition - sets the `blurs` field to Set + pub struct SetBlurs(PhantomData St>); + impl sealed::Sealed for SetBlurs {} + impl State for SetBlurs { + type Locales = St::Locales; + type Severity = St::Severity; + type Blurs = Set; + type Identifier = St::Identifier; + } + ///State transition - sets the `identifier` field to Set + pub struct SetIdentifier(PhantomData St>); + impl sealed::Sealed for SetIdentifier {} + impl State for SetIdentifier { + type Locales = St::Locales; + type Severity = St::Severity; + type Blurs = St::Blurs; + type Identifier = Set; + } + /// Marker types for field names + #[allow(non_camel_case_types)] + pub mod members { + ///Marker type for the `locales` field + pub struct locales(()); + ///Marker type for the `severity` field + pub struct severity(()); + ///Marker type for the `blurs` field + pub struct blurs(()); + ///Marker type for the `identifier` field + pub struct identifier(()); + } +} + +/// Builder for constructing an instance of this type. +pub struct LabelValueDefinitionBuilder< + S: jacquard_common::BosStr, + St: label_value_definition_state::State, +> { + _state: ::core::marker::PhantomData St>, + _fields: ( + core::option::Option, + core::option::Option>, + core::option::Option>, + core::option::Option, + core::option::Option< + Vec>, + >, + core::option::Option>, + ), + _type: ::core::marker::PhantomData S>, +} + +impl LabelValueDefinition { + /// Create a new builder for this type. + pub fn new() -> LabelValueDefinitionBuilder { + LabelValueDefinitionBuilder::new() + } +} + +impl< + S: jacquard_common::BosStr, +> LabelValueDefinitionBuilder { + /// Create a new builder with all fields unset. + pub fn new() -> Self { + LabelValueDefinitionBuilder { + _state: ::core::marker::PhantomData, + _fields: (None, None, None, None, None, None), + _type: ::core::marker::PhantomData, + } + } +} + +impl< + S: jacquard_common::BosStr, + St: label_value_definition_state::State, +> LabelValueDefinitionBuilder { + /// Set the `adultOnly` field (optional) + pub fn adult_only(mut self, value: impl Into>) -> Self { + self._fields.0 = value.into(); + self + } + /// Set the `adultOnly` field to an Option value (optional) + pub fn maybe_adult_only(mut self, value: Option) -> Self { + self._fields.0 = value; + self + } +} + +impl LabelValueDefinitionBuilder +where + St: label_value_definition_state::State, + St::Blurs: label_value_definition_state::IsUnset, +{ + /// Set the `blurs` field (required) + pub fn blurs( + mut self, + value: impl Into>, + ) -> LabelValueDefinitionBuilder> { + self._fields.1 = ::core::option::Option::Some(value.into()); + LabelValueDefinitionBuilder { + _state: ::core::marker::PhantomData, + _fields: self._fields, + _type: ::core::marker::PhantomData, + } + } +} + +impl< + S: jacquard_common::BosStr, + St: label_value_definition_state::State, +> LabelValueDefinitionBuilder { + /// Set the `defaultSetting` field (optional) + pub fn default_setting( + mut self, + value: impl Into>>, + ) -> Self { + self._fields.2 = value.into(); + self + } + /// Set the `defaultSetting` field to an Option value (optional) + pub fn maybe_default_setting( + mut self, + value: Option>, + ) -> Self { + self._fields.2 = value; + self + } +} + +impl LabelValueDefinitionBuilder +where + St: label_value_definition_state::State, + St::Identifier: label_value_definition_state::IsUnset, +{ + /// Set the `identifier` field (required) + pub fn identifier( + mut self, + value: impl Into, + ) -> LabelValueDefinitionBuilder< + S, + label_value_definition_state::SetIdentifier, + > { + self._fields.3 = ::core::option::Option::Some(value.into()); + LabelValueDefinitionBuilder { + _state: ::core::marker::PhantomData, + _fields: self._fields, + _type: ::core::marker::PhantomData, + } + } +} + +impl LabelValueDefinitionBuilder +where + St: label_value_definition_state::State, + St::Locales: label_value_definition_state::IsUnset, +{ + /// Set the `locales` field (required) + pub fn locales( + mut self, + value: impl Into< + Vec>, + >, + ) -> LabelValueDefinitionBuilder> { + self._fields.4 = ::core::option::Option::Some(value.into()); + LabelValueDefinitionBuilder { + _state: ::core::marker::PhantomData, + _fields: self._fields, + _type: ::core::marker::PhantomData, + } + } +} + +impl LabelValueDefinitionBuilder +where + St: label_value_definition_state::State, + St::Severity: label_value_definition_state::IsUnset, +{ + /// Set the `severity` field (required) + pub fn severity( + mut self, + value: impl Into>, + ) -> LabelValueDefinitionBuilder> { + self._fields.5 = ::core::option::Option::Some(value.into()); + LabelValueDefinitionBuilder { + _state: ::core::marker::PhantomData, + _fields: self._fields, + _type: ::core::marker::PhantomData, + } + } +} + +impl LabelValueDefinitionBuilder +where + St: label_value_definition_state::State, + St::Locales: label_value_definition_state::IsSet, + St::Severity: label_value_definition_state::IsSet, + St::Blurs: label_value_definition_state::IsSet, + St::Identifier: label_value_definition_state::IsSet, +{ + /// Build the final struct. + pub fn build(self) -> LabelValueDefinition { + LabelValueDefinition { + adult_only: self._fields.0, + blurs: self._fields.1.unwrap(), + default_setting: self._fields.2, + identifier: self._fields.3.unwrap(), + locales: self._fields.4.unwrap(), + severity: self._fields.5.unwrap(), + extra_data: Default::default(), + } + } + /// Build the final struct with custom extra_data. + pub fn build_with_data( + self, + extra_data: alloc::collections::BTreeMap< + jacquard_common::deps::smol_str::SmolStr, + jacquard_common::types::value::Data, + >, + ) -> LabelValueDefinition { + LabelValueDefinition { + adult_only: self._fields.0, + blurs: self._fields.1.unwrap(), + default_setting: self._fields.2, + identifier: self._fields.3.unwrap(), + locales: self._fields.4.unwrap(), + severity: self._fields.5.unwrap(), + extra_data: Some(extra_data), + } + } +} + +pub mod label_value_definition_strings_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 Lang; + type Name; + type Description; + } + /// Empty state - all required fields are unset + pub struct Empty(()); + impl sealed::Sealed for Empty {} + impl State for Empty { + type Lang = Unset; + type Name = Unset; + type Description = Unset; + } + ///State transition - sets the `lang` field to Set + pub struct SetLang(PhantomData St>); + impl sealed::Sealed for SetLang {} + impl State for SetLang { + type Lang = Set; + type Name = St::Name; + type Description = St::Description; + } + ///State transition - sets the `name` field to Set + pub struct SetName(PhantomData St>); + impl sealed::Sealed for SetName {} + impl State for SetName { + type Lang = St::Lang; + type Name = Set; + type Description = St::Description; + } + ///State transition - sets the `description` field to Set + pub struct SetDescription(PhantomData St>); + impl sealed::Sealed for SetDescription {} + impl State for SetDescription { + type Lang = St::Lang; + type Name = St::Name; + type Description = Set; + } + /// Marker types for field names + #[allow(non_camel_case_types)] + pub mod members { + ///Marker type for the `lang` field + pub struct lang(()); + ///Marker type for the `name` field + pub struct name(()); + ///Marker type for the `description` field + pub struct description(()); + } +} + +/// Builder for constructing an instance of this type. +pub struct LabelValueDefinitionStringsBuilder< + S: jacquard_common::BosStr, + St: label_value_definition_strings_state::State, +> { + _state: ::core::marker::PhantomData St>, + _fields: ( + core::option::Option, + core::option::Option, + core::option::Option, + ), + _type: ::core::marker::PhantomData S>, +} + +impl LabelValueDefinitionStrings { + /// Create a new builder for this type. + pub fn new() -> LabelValueDefinitionStringsBuilder< + S, + label_value_definition_strings_state::Empty, + > { + LabelValueDefinitionStringsBuilder::new() + } +} + +impl< + S: jacquard_common::BosStr, +> LabelValueDefinitionStringsBuilder { + /// Create a new builder with all fields unset. + pub fn new() -> Self { + LabelValueDefinitionStringsBuilder { + _state: ::core::marker::PhantomData, + _fields: (None, None, None), + _type: ::core::marker::PhantomData, + } + } +} + +impl LabelValueDefinitionStringsBuilder +where + St: label_value_definition_strings_state::State, + St::Description: label_value_definition_strings_state::IsUnset, +{ + /// Set the `description` field (required) + pub fn description( + mut self, + value: impl Into, + ) -> LabelValueDefinitionStringsBuilder< + S, + label_value_definition_strings_state::SetDescription, + > { + self._fields.0 = ::core::option::Option::Some(value.into()); + LabelValueDefinitionStringsBuilder { + _state: ::core::marker::PhantomData, + _fields: self._fields, + _type: ::core::marker::PhantomData, + } + } +} + +impl LabelValueDefinitionStringsBuilder +where + St: label_value_definition_strings_state::State, + St::Lang: label_value_definition_strings_state::IsUnset, +{ + /// Set the `lang` field (required) + pub fn lang( + mut self, + value: impl Into, + ) -> LabelValueDefinitionStringsBuilder< + S, + label_value_definition_strings_state::SetLang, + > { + self._fields.1 = ::core::option::Option::Some(value.into()); + LabelValueDefinitionStringsBuilder { + _state: ::core::marker::PhantomData, + _fields: self._fields, + _type: ::core::marker::PhantomData, + } + } +} + +impl LabelValueDefinitionStringsBuilder +where + St: label_value_definition_strings_state::State, + St::Name: label_value_definition_strings_state::IsUnset, +{ + /// Set the `name` field (required) + pub fn name( + mut self, + value: impl Into, + ) -> LabelValueDefinitionStringsBuilder< + S, + label_value_definition_strings_state::SetName, + > { + self._fields.2 = ::core::option::Option::Some(value.into()); + LabelValueDefinitionStringsBuilder { + _state: ::core::marker::PhantomData, + _fields: self._fields, + _type: ::core::marker::PhantomData, + } + } +} + +impl LabelValueDefinitionStringsBuilder +where + St: label_value_definition_strings_state::State, + St::Lang: label_value_definition_strings_state::IsSet, + St::Name: label_value_definition_strings_state::IsSet, + St::Description: label_value_definition_strings_state::IsSet, +{ + /// Build the final struct. + pub fn build(self) -> LabelValueDefinitionStrings { + LabelValueDefinitionStrings { + description: self._fields.0.unwrap(), + lang: self._fields.1.unwrap(), + name: self._fields.2.unwrap(), + extra_data: Default::default(), + } + } + /// Build the final struct with custom extra_data. + pub fn build_with_data( + self, + extra_data: alloc::collections::BTreeMap< + jacquard_common::deps::smol_str::SmolStr, + jacquard_common::types::value::Data, + >, + ) -> LabelValueDefinitionStrings { + LabelValueDefinitionStrings { + description: self._fields.0.unwrap(), + lang: self._fields.1.unwrap(), + name: self._fields.2.unwrap(), + extra_data: Some(extra_data), + } + } +} + +pub mod self_labels_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 Values; + } + /// Empty state - all required fields are unset + pub struct Empty(()); + impl sealed::Sealed for Empty {} + impl State for Empty { + type Values = Unset; + } + ///State transition - sets the `values` field to Set + pub struct SetValues(PhantomData St>); + impl sealed::Sealed for SetValues {} + impl State for SetValues { + type Values = Set; + } + /// Marker types for field names + #[allow(non_camel_case_types)] + pub mod members { + ///Marker type for the `values` field + pub struct values(()); + } +} + +/// Builder for constructing an instance of this type. +pub struct SelfLabelsBuilder { + _state: ::core::marker::PhantomData St>, + _fields: ( + core::option::Option>>, + ), + _type: ::core::marker::PhantomData S>, +} + +impl SelfLabels { + /// Create a new builder for this type. + pub fn new() -> SelfLabelsBuilder { + SelfLabelsBuilder::new() + } +} + +impl SelfLabelsBuilder { + /// Create a new builder with all fields unset. + pub fn new() -> Self { + SelfLabelsBuilder { + _state: ::core::marker::PhantomData, + _fields: (None,), + _type: ::core::marker::PhantomData, + } + } +} + +impl SelfLabelsBuilder +where + St: self_labels_state::State, + St::Values: self_labels_state::IsUnset, +{ + /// Set the `values` field (required) + pub fn values( + mut self, + value: impl Into>>, + ) -> SelfLabelsBuilder> { + self._fields.0 = ::core::option::Option::Some(value.into()); + SelfLabelsBuilder { + _state: ::core::marker::PhantomData, + _fields: self._fields, + _type: ::core::marker::PhantomData, + } + } +} + +impl SelfLabelsBuilder +where + St: self_labels_state::State, + St::Values: self_labels_state::IsSet, +{ + /// Build the final struct. + pub fn build(self) -> SelfLabels { + SelfLabels { + values: self._fields.0.unwrap(), + extra_data: Default::default(), + } + } + /// Build the final struct with custom extra_data. + pub fn build_with_data( + self, + extra_data: alloc::collections::BTreeMap< + jacquard_common::deps::smol_str::SmolStr, + jacquard_common::types::value::Data, + >, + ) -> SelfLabels { + SelfLabels { + values: self._fields.0.unwrap(), + extra_data: Some(extra_data), + } + } +} \ No newline at end of file diff --git a/crates/jacquard-codegen-tests/src/generated/macro_mode/com_atproto/repo.rs b/crates/jacquard-codegen-tests/src/generated/macro_mode/com_atproto/repo.rs new file mode 100644 index 00000000..3c65f8fd --- /dev/null +++ b/crates/jacquard-codegen-tests/src/generated/macro_mode/com_atproto/repo.rs @@ -0,0 +1,6 @@ +// @generated by jacquard-lexicon. DO NOT EDIT. +// +// This file was automatically generated from Lexicon schemas. +// Any manual changes will be overwritten on the next regeneration. + +pub mod strong_ref; \ No newline at end of file diff --git a/crates/jacquard-codegen-tests/src/generated/macro_mode/com_atproto/repo/strong_ref.rs b/crates/jacquard-codegen-tests/src/generated/macro_mode/com_atproto/repo/strong_ref.rs new file mode 100644 index 00000000..2cc7e7c5 --- /dev/null +++ b/crates/jacquard-codegen-tests/src/generated/macro_mode/com_atproto/repo/strong_ref.rs @@ -0,0 +1,241 @@ +// @generated by jacquard-lexicon. DO NOT EDIT. +// +// Lexicon: com.atproto.repo.strongRef +// +// This file was automatically generated from Lexicon schemas. +// Any manual changes will be overwritten on the next regeneration. + +#[derive( + serde::Serialize, + serde::Deserialize, + Debug, + Clone, + PartialEq, + Eq, + jacquard_derive::IntoStatic +)] + +#[serde( + rename_all = "camelCase", + bound(deserialize = "S: serde::Deserialize<'de> + jacquard_common::BosStr") +)] +pub struct StrongRef { + pub cid: jacquard_common::types::string::Cid, + pub uri: jacquard_common::types::string::AtUri, + #[serde(flatten, default, skip_serializing_if = "core::option::Option::is_none")] + pub extra_data: core::option::Option< + alloc::collections::BTreeMap< + jacquard_common::deps::smol_str::SmolStr, + jacquard_common::types::value::Data, + >, + >, +} + +impl jacquard_lexicon::schema::LexiconSchema +for StrongRef { + fn nsid() -> &'static str { + "com.atproto.repo.strongRef" + } + fn def_name() -> &'static str { + "main" + } + fn lexicon_doc() -> jacquard_lexicon::lexicon::LexiconDoc<'static> { + lexicon_doc_com_atproto_repo_strongRef() + } + fn validate(&self) -> Result<(), jacquard_lexicon::validation::ConstraintError> { + Ok(()) + } +} + +pub mod strong_ref_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 Cid; + type Uri; + } + /// Empty state - all required fields are unset + pub struct Empty(()); + impl sealed::Sealed for Empty {} + impl State for Empty { + type Cid = Unset; + type Uri = Unset; + } + ///State transition - sets the `cid` field to Set + pub struct SetCid(PhantomData St>); + impl sealed::Sealed for SetCid {} + impl State for SetCid { + type Cid = Set; + type Uri = St::Uri; + } + ///State transition - sets the `uri` field to Set + pub struct SetUri(PhantomData St>); + impl sealed::Sealed for SetUri {} + impl State for SetUri { + type Cid = St::Cid; + type Uri = Set; + } + /// Marker types for field names + #[allow(non_camel_case_types)] + pub mod members { + ///Marker type for the `cid` field + pub struct cid(()); + ///Marker type for the `uri` field + pub struct uri(()); + } +} + +/// Builder for constructing an instance of this type. +pub struct StrongRefBuilder { + _state: ::core::marker::PhantomData St>, + _fields: ( + core::option::Option>, + core::option::Option>, + ), + _type: ::core::marker::PhantomData S>, +} + +impl StrongRef { + /// Create a new builder for this type. + pub fn new() -> StrongRefBuilder { + StrongRefBuilder::new() + } +} + +impl StrongRefBuilder { + /// Create a new builder with all fields unset. + pub fn new() -> Self { + StrongRefBuilder { + _state: ::core::marker::PhantomData, + _fields: (None, None), + _type: ::core::marker::PhantomData, + } + } +} + +impl StrongRefBuilder +where + St: strong_ref_state::State, + St::Cid: strong_ref_state::IsUnset, +{ + /// Set the `cid` field (required) + pub fn cid( + mut self, + value: impl Into>, + ) -> StrongRefBuilder> { + self._fields.0 = ::core::option::Option::Some(value.into()); + StrongRefBuilder { + _state: ::core::marker::PhantomData, + _fields: self._fields, + _type: ::core::marker::PhantomData, + } + } +} + +impl StrongRefBuilder +where + St: strong_ref_state::State, + St::Uri: strong_ref_state::IsUnset, +{ + /// Set the `uri` field (required) + pub fn uri( + mut self, + value: impl Into>, + ) -> StrongRefBuilder> { + self._fields.1 = ::core::option::Option::Some(value.into()); + StrongRefBuilder { + _state: ::core::marker::PhantomData, + _fields: self._fields, + _type: ::core::marker::PhantomData, + } + } +} + +impl StrongRefBuilder +where + St: strong_ref_state::State, + St::Cid: strong_ref_state::IsSet, + St::Uri: strong_ref_state::IsSet, +{ + /// Build the final struct. + pub fn build(self) -> StrongRef { + StrongRef { + cid: self._fields.0.unwrap(), + uri: self._fields.1.unwrap(), + extra_data: Default::default(), + } + } + /// Build the final struct with custom extra_data. + pub fn build_with_data( + self, + extra_data: alloc::collections::BTreeMap< + jacquard_common::deps::smol_str::SmolStr, + jacquard_common::types::value::Data, + >, + ) -> StrongRef { + StrongRef { + cid: self._fields.0.unwrap(), + uri: self._fields.1.unwrap(), + extra_data: Some(extra_data), + } + } +} + +fn lexicon_doc_com_atproto_repo_strongRef() -> jacquard_lexicon::lexicon::LexiconDoc< + 'static, +> { + ::jacquard_lexicon::lexicon::LexiconDoc { + lexicon: ::jacquard_lexicon::lexicon::Lexicon::Lexicon1, + id: ::jacquard_common::CowStr::new_static("com.atproto.repo.strongRef"), + defs: { + let mut map = ::alloc::collections::BTreeMap::new(); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static("main"), + ::jacquard_lexicon::lexicon::LexUserType::Object(::jacquard_lexicon::lexicon::LexObject { + required: Some( + vec![ + ::jacquard_common::deps::smol_str::SmolStr::new_static("uri"), + ::jacquard_common::deps::smol_str::SmolStr::new_static("cid") + ], + ), + properties: { + #[allow(unused_mut)] + let mut map = ::alloc::collections::BTreeMap::new(); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "cid", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { + format: Some( + ::jacquard_lexicon::lexicon::LexStringFormat::Cid, + ), + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "uri", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { + format: Some( + ::jacquard_lexicon::lexicon::LexStringFormat::AtUri, + ), + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map + }, + ..Default::default() + } +} \ No newline at end of file diff --git a/crates/jacquard-codegen-tests/src/generated/macro_mode/lib.rs b/crates/jacquard-codegen-tests/src/generated/macro_mode/lib.rs new file mode 100644 index 00000000..90f780c8 --- /dev/null +++ b/crates/jacquard-codegen-tests/src/generated/macro_mode/lib.rs @@ -0,0 +1,30 @@ +// @generated by jacquard-lexicon. DO NOT EDIT. +// +// This file was automatically generated from Lexicon schemas. +// Any manual changes will be overwritten on the next regeneration. + +extern crate alloc; + +#[cfg(feature = "app_bsky")] +pub mod app_bsky; +pub mod builder_types; + + +#[cfg(feature = "com_atproto")] +pub mod com_atproto; + + +#[cfg(feature = "test_collision")] +pub mod test_collision; + + +#[cfg(feature = "test_ns1")] +pub mod test_ns1; + + +#[cfg(feature = "test_ns2")] +pub mod test_ns2; + + +#[cfg(feature = "test_ns3")] +pub mod test_ns3; \ No newline at end of file diff --git a/crates/jacquard-codegen-tests/src/generated/macro_mode/test_collision.rs b/crates/jacquard-codegen-tests/src/generated/macro_mode/test_collision.rs new file mode 100644 index 00000000..89a1e91c --- /dev/null +++ b/crates/jacquard-codegen-tests/src/generated/macro_mode/test_collision.rs @@ -0,0 +1,8 @@ +// @generated by jacquard-lexicon. DO NOT EDIT. +// +// This file was automatically generated from Lexicon schemas. +// Any manual changes will be overwritten on the next regeneration. + +pub mod collection; +pub mod did; +pub mod option; \ No newline at end of file diff --git a/crates/jacquard-codegen-tests/src/generated/macro_mode/test_collision/collection.rs b/crates/jacquard-codegen-tests/src/generated/macro_mode/test_collision/collection.rs new file mode 100644 index 00000000..dbdac46e --- /dev/null +++ b/crates/jacquard-codegen-tests/src/generated/macro_mode/test_collision/collection.rs @@ -0,0 +1,486 @@ +// @generated by jacquard-lexicon. DO NOT EDIT. +// +// Lexicon: test.collision.collection +// +// This file was automatically generated from Lexicon schemas. +// Any manual changes will be overwritten on the next regeneration. + +/// A locally-defined type named Collection that collides with the trait import. + +#[derive( + serde::Serialize, + serde::Deserialize, + Debug, + Clone, + PartialEq, + Eq, + jacquard_derive::IntoStatic, + Default +)] + +#[serde( + rename_all = "camelCase", + bound(deserialize = "S: serde::Deserialize<'de> + jacquard_common::BosStr") +)] +pub struct Collection { + #[serde(skip_serializing_if = "core::option::Option::is_none")] + pub count: core::option::Option, + pub label: S, + #[serde(flatten, default, skip_serializing_if = "core::option::Option::is_none")] + pub extra_data: core::option::Option< + alloc::collections::BTreeMap< + jacquard_common::deps::smol_str::SmolStr, + jacquard_common::types::value::Data, + >, + >, +} + +/// A record that itself references the Collection trait via its NSID. + +#[derive( + serde::Serialize, + serde::Deserialize, + Debug, + Clone, + PartialEq, + Eq, + jacquard_derive::IntoStatic +)] + +#[serde( + rename_all = "camelCase", + rename = "test.collision.collection", + tag = "$type", + bound(deserialize = "S: serde::Deserialize<'de> + jacquard_common::BosStr") +)] +pub struct CollectionRecord { + #[serde(skip_serializing_if = "core::option::Option::is_none")] + pub created_at: core::option::Option, + pub items: Vec>, + pub name: S, + #[serde(flatten, default, skip_serializing_if = "core::option::Option::is_none")] + pub extra_data: core::option::Option< + alloc::collections::BTreeMap< + jacquard_common::deps::smol_str::SmolStr, + jacquard_common::types::value::Data, + >, + >, +} + +/// Typed wrapper for GetRecord response with this collection's record type. + +#[derive( + serde::Serialize, + serde::Deserialize, + Debug, + Clone, + PartialEq, + Eq, + jacquard_derive::IntoStatic +)] + +#[serde(rename_all = "camelCase")] +pub struct CollectionRecordGetRecordOutput< + S: jacquard_common::BosStr = jacquard_common::DefaultStr, +> { + #[serde(skip_serializing_if = "core::option::Option::is_none")] + pub cid: core::option::Option>, + pub uri: jacquard_common::types::string::AtUri, + pub value: CollectionRecord, +} + +impl CollectionRecord { + pub fn uri( + uri: S, + ) -> Result< + jacquard_common::types::uri::RecordUri, + jacquard_common::types::uri::UriError, + > { + jacquard_common::types::uri::RecordUri::try_from_uri( + jacquard_common::types::string::AtUri::new(uri)?, + ) + } +} + +impl jacquard_lexicon::schema::LexiconSchema +for Collection { + fn nsid() -> &'static str { + "test.collision.collection" + } + fn def_name() -> &'static str { + "collection" + } + fn lexicon_doc() -> jacquard_lexicon::lexicon::LexiconDoc<'static> { + lexicon_doc_test_collision_collection() + } + fn validate(&self) -> Result<(), jacquard_lexicon::validation::ConstraintError> { + if let Some(ref value) = self.count { + if *value < 0i64 { + return Err(jacquard_lexicon::validation::ConstraintError::Minimum { + path: jacquard_lexicon::validation::ValidationPath::from_field( + "count", + ), + min: 0i64, + actual: *value, + }); + } + } + { + let value = &self.label; + #[allow(unused_comparisons)] + if ::len(value.as_ref()) > 100usize { + return Err(jacquard_lexicon::validation::ConstraintError::MaxLength { + path: jacquard_lexicon::validation::ValidationPath::from_field( + "label", + ), + max: 100usize, + actual: ::len(value.as_ref()), + }); + } + } + Ok(()) + } +} + +/// Marker type for deserializing records from this collection. + +#[derive(Debug, serde::Serialize, serde::Deserialize)] +pub struct CollectionRecordRecord; +impl jacquard_common::xrpc::XrpcResp for CollectionRecordRecord { + const NSID: &'static str = "test.collision.collection"; + const ENCODING: &'static str = "application/json"; + type Output = CollectionRecordGetRecordOutput; + type Err = jacquard_common::types::collection::RecordError; +} + +impl From> +for CollectionRecord { + fn from(output: CollectionRecordGetRecordOutput) -> Self { + output.value + } +} + +impl jacquard_common::types::collection::Collection +for CollectionRecord { + const NSID: &'static str = "test.collision.collection"; + type Record = CollectionRecordRecord; +} + +impl jacquard_common::types::collection::Collection for CollectionRecordRecord { + const NSID: &'static str = "test.collision.collection"; + type Record = CollectionRecordRecord; +} + +impl jacquard_lexicon::schema::LexiconSchema +for CollectionRecord { + fn nsid() -> &'static str { + "test.collision.collection" + } + fn def_name() -> &'static str { + "main" + } + fn lexicon_doc() -> jacquard_lexicon::lexicon::LexiconDoc<'static> { + lexicon_doc_test_collision_collection() + } + fn validate(&self) -> Result<(), jacquard_lexicon::validation::ConstraintError> { + { + let value = &self.name; + #[allow(unused_comparisons)] + if ::len(value.as_ref()) > 256usize { + return Err(jacquard_lexicon::validation::ConstraintError::MaxLength { + path: jacquard_lexicon::validation::ValidationPath::from_field( + "name", + ), + max: 256usize, + actual: ::len(value.as_ref()), + }); + } + } + Ok(()) + } +} + +fn lexicon_doc_test_collision_collection() -> jacquard_lexicon::lexicon::LexiconDoc< + 'static, +> { + ::jacquard_lexicon::lexicon::LexiconDoc { + lexicon: ::jacquard_lexicon::lexicon::Lexicon::Lexicon1, + id: ::jacquard_common::CowStr::new_static("test.collision.collection"), + defs: { + let mut map = ::alloc::collections::BTreeMap::new(); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static("collection"), + ::jacquard_lexicon::lexicon::LexUserType::Object(::jacquard_lexicon::lexicon::LexObject { + description: Some( + ::jacquard_common::CowStr::new_static( + "A locally-defined type named Collection that collides with the trait import.", + ), + ), + required: Some( + vec![ + ::jacquard_common::deps::smol_str::SmolStr::new_static("label") + ], + ), + properties: { + #[allow(unused_mut)] + let mut map = ::alloc::collections::BTreeMap::new(); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "count", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::Integer(::jacquard_lexicon::lexicon::LexInteger { + minimum: Some(0i64), + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "label", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { + max_length: Some(100usize), + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static("main"), + ::jacquard_lexicon::lexicon::LexUserType::Record(::jacquard_lexicon::lexicon::LexRecord { + description: Some( + ::jacquard_common::CowStr::new_static( + "A record that itself references the Collection trait via its NSID.", + ), + ), + key: Some(::jacquard_common::CowStr::new_static("tid")), + record: ::jacquard_lexicon::lexicon::LexRecordRecord::Object(::jacquard_lexicon::lexicon::LexObject { + required: Some( + vec![ + ::jacquard_common::deps::smol_str::SmolStr::new_static("name"), + ::jacquard_common::deps::smol_str::SmolStr::new_static("items") + ], + ), + properties: { + #[allow(unused_mut)] + let mut map = ::alloc::collections::BTreeMap::new(); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "createdAt", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { + format: Some( + ::jacquard_lexicon::lexicon::LexStringFormat::Datetime, + ), + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "items", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::Array(::jacquard_lexicon::lexicon::LexArray { + items: ::jacquard_lexicon::lexicon::LexArrayItem::Ref(::jacquard_lexicon::lexicon::LexRef { + r#ref: ::jacquard_common::CowStr::new_static("#collection"), + ..Default::default() + }), + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "name", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { + max_length: Some(256usize), + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ..Default::default() + }), + ); + map + }, + ..Default::default() + } +} + +pub mod collection_record_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 Items; + type Name; + } + /// Empty state - all required fields are unset + pub struct Empty(()); + impl sealed::Sealed for Empty {} + impl State for Empty { + type Items = Unset; + type Name = Unset; + } + ///State transition - sets the `items` field to Set + pub struct SetItems(PhantomData St>); + impl sealed::Sealed for SetItems {} + impl State for SetItems { + type Items = Set; + type Name = St::Name; + } + ///State transition - sets the `name` field to Set + pub struct SetName(PhantomData St>); + impl sealed::Sealed for SetName {} + impl State for SetName { + type Items = St::Items; + type Name = Set; + } + /// Marker types for field names + #[allow(non_camel_case_types)] + pub mod members { + ///Marker type for the `items` field + pub struct items(()); + ///Marker type for the `name` field + pub struct name(()); + } +} + +/// Builder for constructing an instance of this type. +pub struct CollectionRecordBuilder< + S: jacquard_common::BosStr, + St: collection_record_state::State, +> { + _state: ::core::marker::PhantomData St>, + _fields: ( + core::option::Option, + core::option::Option< + Vec>, + >, + core::option::Option, + ), + _type: ::core::marker::PhantomData S>, +} + +impl CollectionRecord { + /// Create a new builder for this type. + pub fn new() -> CollectionRecordBuilder { + CollectionRecordBuilder::new() + } +} + +impl< + S: jacquard_common::BosStr, +> CollectionRecordBuilder { + /// Create a new builder with all fields unset. + pub fn new() -> Self { + CollectionRecordBuilder { + _state: ::core::marker::PhantomData, + _fields: (None, None, None), + _type: ::core::marker::PhantomData, + } + } +} + +impl< + S: jacquard_common::BosStr, + St: collection_record_state::State, +> CollectionRecordBuilder { + /// Set the `createdAt` field (optional) + pub fn created_at( + mut self, + value: impl Into>, + ) -> Self { + self._fields.0 = value.into(); + self + } + /// Set the `createdAt` field to an Option value (optional) + pub fn maybe_created_at( + mut self, + value: Option, + ) -> Self { + self._fields.0 = value; + self + } +} + +impl CollectionRecordBuilder +where + St: collection_record_state::State, + St::Items: collection_record_state::IsUnset, +{ + /// Set the `items` field (required) + pub fn items( + mut self, + value: impl Into< + Vec>, + >, + ) -> CollectionRecordBuilder> { + self._fields.1 = ::core::option::Option::Some(value.into()); + CollectionRecordBuilder { + _state: ::core::marker::PhantomData, + _fields: self._fields, + _type: ::core::marker::PhantomData, + } + } +} + +impl CollectionRecordBuilder +where + St: collection_record_state::State, + St::Name: collection_record_state::IsUnset, +{ + /// Set the `name` field (required) + pub fn name( + mut self, + value: impl Into, + ) -> CollectionRecordBuilder> { + self._fields.2 = ::core::option::Option::Some(value.into()); + CollectionRecordBuilder { + _state: ::core::marker::PhantomData, + _fields: self._fields, + _type: ::core::marker::PhantomData, + } + } +} + +impl CollectionRecordBuilder +where + St: collection_record_state::State, + St::Items: collection_record_state::IsSet, + St::Name: collection_record_state::IsSet, +{ + /// Build the final struct. + pub fn build(self) -> CollectionRecord { + CollectionRecord { + created_at: self._fields.0, + items: self._fields.1.unwrap(), + name: self._fields.2.unwrap(), + extra_data: Default::default(), + } + } + /// Build the final struct with custom extra_data. + pub fn build_with_data( + self, + extra_data: alloc::collections::BTreeMap< + jacquard_common::deps::smol_str::SmolStr, + jacquard_common::types::value::Data, + >, + ) -> CollectionRecord { + CollectionRecord { + created_at: self._fields.0, + items: self._fields.1.unwrap(), + name: self._fields.2.unwrap(), + extra_data: Some(extra_data), + } + } +} \ No newline at end of file diff --git a/crates/jacquard-codegen-tests/src/generated/macro_mode/test_collision/did.rs b/crates/jacquard-codegen-tests/src/generated/macro_mode/test_collision/did.rs new file mode 100644 index 00000000..a4034314 --- /dev/null +++ b/crates/jacquard-codegen-tests/src/generated/macro_mode/test_collision/did.rs @@ -0,0 +1,411 @@ +// @generated by jacquard-lexicon. DO NOT EDIT. +// +// Lexicon: test.collision.did +// +// This file was automatically generated from Lexicon schemas. +// Any manual changes will be overwritten on the next regeneration. + +/// A locally-defined type named Did that collides with the string import. + +#[derive( + serde::Serialize, + serde::Deserialize, + Debug, + Clone, + PartialEq, + Eq, + jacquard_derive::IntoStatic, + Default +)] + +#[serde( + rename_all = "camelCase", + bound(deserialize = "S: serde::Deserialize<'de> + jacquard_common::BosStr") +)] +pub struct Did { + ///The DID method (e.g., plc, web). + pub method: S, + ///The full DID string. + pub value: S, + #[serde(flatten, default, skip_serializing_if = "core::option::Option::is_none")] + pub extra_data: core::option::Option< + alloc::collections::BTreeMap< + jacquard_common::deps::smol_str::SmolStr, + jacquard_common::types::value::Data, + >, + >, +} + +/// An object that also uses a DID-format string field, exercising the collision path. + +#[derive( + serde::Serialize, + serde::Deserialize, + Debug, + Clone, + PartialEq, + Eq, + jacquard_derive::IntoStatic +)] + +#[serde( + rename_all = "camelCase", + bound(deserialize = "S: serde::Deserialize<'de> + jacquard_common::BosStr") +)] +pub struct DidRecord { + pub identifier: crate::macro_mode::test_collision::did::Did, + #[serde(skip_serializing_if = "core::option::Option::is_none")] + pub label: core::option::Option, + ///A field typed as DID format, requiring the Did import but colliding with local Did type. + pub owner: jacquard_common::types::string::Did, + #[serde(flatten, default, skip_serializing_if = "core::option::Option::is_none")] + pub extra_data: core::option::Option< + alloc::collections::BTreeMap< + jacquard_common::deps::smol_str::SmolStr, + jacquard_common::types::value::Data, + >, + >, +} + +impl jacquard_lexicon::schema::LexiconSchema for Did { + fn nsid() -> &'static str { + "test.collision.did" + } + fn def_name() -> &'static str { + "did" + } + fn lexicon_doc() -> jacquard_lexicon::lexicon::LexiconDoc<'static> { + lexicon_doc_test_collision_did() + } + fn validate(&self) -> Result<(), jacquard_lexicon::validation::ConstraintError> { + { + let value = &self.method; + #[allow(unused_comparisons)] + if ::len(value.as_ref()) > 50usize { + return Err(jacquard_lexicon::validation::ConstraintError::MaxLength { + path: jacquard_lexicon::validation::ValidationPath::from_field( + "method", + ), + max: 50usize, + actual: ::len(value.as_ref()), + }); + } + } + { + let value = &self.value; + #[allow(unused_comparisons)] + if ::len(value.as_ref()) > 256usize { + return Err(jacquard_lexicon::validation::ConstraintError::MaxLength { + path: jacquard_lexicon::validation::ValidationPath::from_field( + "value", + ), + max: 256usize, + actual: ::len(value.as_ref()), + }); + } + } + Ok(()) + } +} + +impl jacquard_lexicon::schema::LexiconSchema +for DidRecord { + fn nsid() -> &'static str { + "test.collision.did" + } + fn def_name() -> &'static str { + "main" + } + fn lexicon_doc() -> jacquard_lexicon::lexicon::LexiconDoc<'static> { + lexicon_doc_test_collision_did() + } + fn validate(&self) -> Result<(), jacquard_lexicon::validation::ConstraintError> { + if let Some(ref value) = self.label { + #[allow(unused_comparisons)] + if ::len(value.as_ref()) > 200usize { + return Err(jacquard_lexicon::validation::ConstraintError::MaxLength { + path: jacquard_lexicon::validation::ValidationPath::from_field( + "label", + ), + max: 200usize, + actual: ::len(value.as_ref()), + }); + } + } + Ok(()) + } +} + +fn lexicon_doc_test_collision_did() -> jacquard_lexicon::lexicon::LexiconDoc<'static> { + ::jacquard_lexicon::lexicon::LexiconDoc { + lexicon: ::jacquard_lexicon::lexicon::Lexicon::Lexicon1, + id: ::jacquard_common::CowStr::new_static("test.collision.did"), + defs: { + let mut map = ::alloc::collections::BTreeMap::new(); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static("did"), + ::jacquard_lexicon::lexicon::LexUserType::Object(::jacquard_lexicon::lexicon::LexObject { + description: Some( + ::jacquard_common::CowStr::new_static( + "A locally-defined type named Did that collides with the string import.", + ), + ), + required: Some( + vec![ + ::jacquard_common::deps::smol_str::SmolStr::new_static("method"), + ::jacquard_common::deps::smol_str::SmolStr::new_static("value") + ], + ), + properties: { + #[allow(unused_mut)] + let mut map = ::alloc::collections::BTreeMap::new(); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "method", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { + description: Some( + ::jacquard_common::CowStr::new_static( + "The DID method (e.g., plc, web).", + ), + ), + max_length: Some(50usize), + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "value", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { + description: Some( + ::jacquard_common::CowStr::new_static( + "The full DID string.", + ), + ), + max_length: Some(256usize), + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static("main"), + ::jacquard_lexicon::lexicon::LexUserType::Object(::jacquard_lexicon::lexicon::LexObject { + description: Some( + ::jacquard_common::CowStr::new_static( + "An object that also uses a DID-format string field, exercising the collision path.", + ), + ), + required: Some( + vec![ + ::jacquard_common::deps::smol_str::SmolStr::new_static("owner"), + ::jacquard_common::deps::smol_str::SmolStr::new_static("identifier") + ], + ), + properties: { + #[allow(unused_mut)] + let mut map = ::alloc::collections::BTreeMap::new(); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "identifier", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::Ref(::jacquard_lexicon::lexicon::LexRef { + r#ref: ::jacquard_common::CowStr::new_static("#did"), + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "label", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { + max_length: Some(200usize), + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "owner", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { + description: Some( + ::jacquard_common::CowStr::new_static( + "A field typed as DID format, requiring the Did import but colliding with local Did type.", + ), + ), + format: Some( + ::jacquard_lexicon::lexicon::LexStringFormat::Did, + ), + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map + }, + ..Default::default() + } +} + +pub mod did_record_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 Identifier; + type Owner; + } + /// Empty state - all required fields are unset + pub struct Empty(()); + impl sealed::Sealed for Empty {} + impl State for Empty { + type Identifier = Unset; + type Owner = Unset; + } + ///State transition - sets the `identifier` field to Set + pub struct SetIdentifier(PhantomData St>); + impl sealed::Sealed for SetIdentifier {} + impl State for SetIdentifier { + type Identifier = Set; + type Owner = St::Owner; + } + ///State transition - sets the `owner` field to Set + pub struct SetOwner(PhantomData St>); + impl sealed::Sealed for SetOwner {} + impl State for SetOwner { + type Identifier = St::Identifier; + type Owner = Set; + } + /// Marker types for field names + #[allow(non_camel_case_types)] + pub mod members { + ///Marker type for the `identifier` field + pub struct identifier(()); + ///Marker type for the `owner` field + pub struct owner(()); + } +} + +/// Builder for constructing an instance of this type. +pub struct DidRecordBuilder { + _state: ::core::marker::PhantomData St>, + _fields: ( + core::option::Option>, + core::option::Option, + core::option::Option>, + ), + _type: ::core::marker::PhantomData S>, +} + +impl DidRecord { + /// Create a new builder for this type. + pub fn new() -> DidRecordBuilder { + DidRecordBuilder::new() + } +} + +impl DidRecordBuilder { + /// Create a new builder with all fields unset. + pub fn new() -> Self { + DidRecordBuilder { + _state: ::core::marker::PhantomData, + _fields: (None, None, None), + _type: ::core::marker::PhantomData, + } + } +} + +impl DidRecordBuilder +where + St: did_record_state::State, + St::Identifier: did_record_state::IsUnset, +{ + /// Set the `identifier` field (required) + pub fn identifier( + mut self, + value: impl Into>, + ) -> DidRecordBuilder> { + self._fields.0 = ::core::option::Option::Some(value.into()); + DidRecordBuilder { + _state: ::core::marker::PhantomData, + _fields: self._fields, + _type: ::core::marker::PhantomData, + } + } +} + +impl DidRecordBuilder { + /// Set the `label` field (optional) + pub fn label(mut self, value: impl Into>) -> Self { + self._fields.1 = value.into(); + self + } + /// Set the `label` field to an Option value (optional) + pub fn maybe_label(mut self, value: Option) -> Self { + self._fields.1 = value; + self + } +} + +impl DidRecordBuilder +where + St: did_record_state::State, + St::Owner: did_record_state::IsUnset, +{ + /// Set the `owner` field (required) + pub fn owner( + mut self, + value: impl Into>, + ) -> DidRecordBuilder> { + self._fields.2 = ::core::option::Option::Some(value.into()); + DidRecordBuilder { + _state: ::core::marker::PhantomData, + _fields: self._fields, + _type: ::core::marker::PhantomData, + } + } +} + +impl DidRecordBuilder +where + St: did_record_state::State, + St::Identifier: did_record_state::IsSet, + St::Owner: did_record_state::IsSet, +{ + /// Build the final struct. + pub fn build(self) -> DidRecord { + DidRecord { + identifier: self._fields.0.unwrap(), + label: self._fields.1, + owner: self._fields.2.unwrap(), + extra_data: Default::default(), + } + } + /// Build the final struct with custom extra_data. + pub fn build_with_data( + self, + extra_data: alloc::collections::BTreeMap< + jacquard_common::deps::smol_str::SmolStr, + jacquard_common::types::value::Data, + >, + ) -> DidRecord { + DidRecord { + identifier: self._fields.0.unwrap(), + label: self._fields.1, + owner: self._fields.2.unwrap(), + extra_data: Some(extra_data), + } + } +} \ No newline at end of file diff --git a/crates/jacquard-codegen-tests/src/generated/macro_mode/test_collision/option.rs b/crates/jacquard-codegen-tests/src/generated/macro_mode/test_collision/option.rs new file mode 100644 index 00000000..ab424060 --- /dev/null +++ b/crates/jacquard-codegen-tests/src/generated/macro_mode/test_collision/option.rs @@ -0,0 +1,358 @@ +// @generated by jacquard-lexicon. DO NOT EDIT. +// +// Lexicon: test.collision.option +// +// This file was automatically generated from Lexicon schemas. +// Any manual changes will be overwritten on the next regeneration. + +/// An object with optional fields, exercising the Option::is_none path collision. + +#[derive( + serde::Serialize, + serde::Deserialize, + Debug, + Clone, + PartialEq, + Eq, + jacquard_derive::IntoStatic +)] + +#[serde( + rename_all = "camelCase", + bound(deserialize = "S: serde::Deserialize<'de> + jacquard_common::BosStr") +)] +pub struct OptionRecord { + pub choice: crate::macro_mode::test_collision::option::OptionRecordOption, + #[serde(skip_serializing_if = "core::option::Option::is_none")] + pub description: core::option::Option, + #[serde(flatten, default, skip_serializing_if = "core::option::Option::is_none")] + pub extra_data: core::option::Option< + alloc::collections::BTreeMap< + jacquard_common::deps::smol_str::SmolStr, + jacquard_common::types::value::Data, + >, + >, +} + +/// A locally-defined type named Option, colliding with std::option::Option. + +#[derive( + serde::Serialize, + serde::Deserialize, + Debug, + Clone, + PartialEq, + Eq, + jacquard_derive::IntoStatic, + Default +)] + +#[serde( + rename_all = "camelCase", + bound(deserialize = "S: serde::Deserialize<'de> + jacquard_common::BosStr") +)] +pub struct OptionRecordOption { + pub key: S, + pub value: S, + #[serde(flatten, default, skip_serializing_if = "core::option::Option::is_none")] + pub extra_data: core::option::Option< + alloc::collections::BTreeMap< + jacquard_common::deps::smol_str::SmolStr, + jacquard_common::types::value::Data, + >, + >, +} + +impl jacquard_lexicon::schema::LexiconSchema +for OptionRecord { + fn nsid() -> &'static str { + "test.collision.option" + } + fn def_name() -> &'static str { + "main" + } + fn lexicon_doc() -> jacquard_lexicon::lexicon::LexiconDoc<'static> { + lexicon_doc_test_collision_option() + } + fn validate(&self) -> Result<(), jacquard_lexicon::validation::ConstraintError> { + if let Some(ref value) = self.description { + #[allow(unused_comparisons)] + if ::len(value.as_ref()) > 500usize { + return Err(jacquard_lexicon::validation::ConstraintError::MaxLength { + path: jacquard_lexicon::validation::ValidationPath::from_field( + "description", + ), + max: 500usize, + actual: ::len(value.as_ref()), + }); + } + } + Ok(()) + } +} + +impl jacquard_lexicon::schema::LexiconSchema +for OptionRecordOption { + fn nsid() -> &'static str { + "test.collision.option" + } + fn def_name() -> &'static str { + "option" + } + fn lexicon_doc() -> jacquard_lexicon::lexicon::LexiconDoc<'static> { + lexicon_doc_test_collision_option() + } + fn validate(&self) -> Result<(), jacquard_lexicon::validation::ConstraintError> { + { + let value = &self.key; + #[allow(unused_comparisons)] + if ::len(value.as_ref()) > 100usize { + return Err(jacquard_lexicon::validation::ConstraintError::MaxLength { + path: jacquard_lexicon::validation::ValidationPath::from_field( + "key", + ), + max: 100usize, + actual: ::len(value.as_ref()), + }); + } + } + { + let value = &self.value; + #[allow(unused_comparisons)] + if ::len(value.as_ref()) > 500usize { + return Err(jacquard_lexicon::validation::ConstraintError::MaxLength { + path: jacquard_lexicon::validation::ValidationPath::from_field( + "value", + ), + max: 500usize, + actual: ::len(value.as_ref()), + }); + } + } + Ok(()) + } +} + +pub mod option_record_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 Choice; + } + /// Empty state - all required fields are unset + pub struct Empty(()); + impl sealed::Sealed for Empty {} + impl State for Empty { + type Choice = Unset; + } + ///State transition - sets the `choice` field to Set + pub struct SetChoice(PhantomData St>); + impl sealed::Sealed for SetChoice {} + impl State for SetChoice { + type Choice = Set; + } + /// Marker types for field names + #[allow(non_camel_case_types)] + pub mod members { + ///Marker type for the `choice` field + pub struct choice(()); + } +} + +/// Builder for constructing an instance of this type. +pub struct OptionRecordBuilder< + S: jacquard_common::BosStr, + St: option_record_state::State, +> { + _state: ::core::marker::PhantomData St>, + _fields: ( + core::option::Option< + crate::macro_mode::test_collision::option::OptionRecordOption, + >, + core::option::Option, + ), + _type: ::core::marker::PhantomData S>, +} + +impl OptionRecord { + /// Create a new builder for this type. + pub fn new() -> OptionRecordBuilder { + OptionRecordBuilder::new() + } +} + +impl OptionRecordBuilder { + /// Create a new builder with all fields unset. + pub fn new() -> Self { + OptionRecordBuilder { + _state: ::core::marker::PhantomData, + _fields: (None, None), + _type: ::core::marker::PhantomData, + } + } +} + +impl OptionRecordBuilder +where + St: option_record_state::State, + St::Choice: option_record_state::IsUnset, +{ + /// Set the `choice` field (required) + pub fn choice( + mut self, + value: impl Into< + crate::macro_mode::test_collision::option::OptionRecordOption, + >, + ) -> OptionRecordBuilder> { + self._fields.0 = ::core::option::Option::Some(value.into()); + OptionRecordBuilder { + _state: ::core::marker::PhantomData, + _fields: self._fields, + _type: ::core::marker::PhantomData, + } + } +} + +impl< + S: jacquard_common::BosStr, + St: option_record_state::State, +> OptionRecordBuilder { + /// Set the `description` field (optional) + pub fn description(mut self, value: impl Into>) -> Self { + self._fields.1 = value.into(); + self + } + /// Set the `description` field to an Option value (optional) + pub fn maybe_description(mut self, value: Option) -> Self { + self._fields.1 = value; + self + } +} + +impl OptionRecordBuilder +where + St: option_record_state::State, + St::Choice: option_record_state::IsSet, +{ + /// Build the final struct. + pub fn build(self) -> OptionRecord { + OptionRecord { + choice: self._fields.0.unwrap(), + description: self._fields.1, + extra_data: Default::default(), + } + } + /// Build the final struct with custom extra_data. + pub fn build_with_data( + self, + extra_data: alloc::collections::BTreeMap< + jacquard_common::deps::smol_str::SmolStr, + jacquard_common::types::value::Data, + >, + ) -> OptionRecord { + OptionRecord { + choice: self._fields.0.unwrap(), + description: self._fields.1, + extra_data: Some(extra_data), + } + } +} + +fn lexicon_doc_test_collision_option() -> jacquard_lexicon::lexicon::LexiconDoc< + 'static, +> { + ::jacquard_lexicon::lexicon::LexiconDoc { + lexicon: ::jacquard_lexicon::lexicon::Lexicon::Lexicon1, + id: ::jacquard_common::CowStr::new_static("test.collision.option"), + defs: { + let mut map = ::alloc::collections::BTreeMap::new(); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static("main"), + ::jacquard_lexicon::lexicon::LexUserType::Object(::jacquard_lexicon::lexicon::LexObject { + description: Some( + ::jacquard_common::CowStr::new_static( + "An object with optional fields, exercising the Option::is_none path collision.", + ), + ), + required: Some( + vec![ + ::jacquard_common::deps::smol_str::SmolStr::new_static("choice") + ], + ), + properties: { + #[allow(unused_mut)] + let mut map = ::alloc::collections::BTreeMap::new(); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "choice", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::Ref(::jacquard_lexicon::lexicon::LexRef { + r#ref: ::jacquard_common::CowStr::new_static("#option"), + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "description", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { + max_length: Some(500usize), + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static("option"), + ::jacquard_lexicon::lexicon::LexUserType::Object(::jacquard_lexicon::lexicon::LexObject { + description: Some( + ::jacquard_common::CowStr::new_static( + "A locally-defined type named Option, colliding with std::option::Option.", + ), + ), + required: Some( + vec![ + ::jacquard_common::deps::smol_str::SmolStr::new_static("key"), + ::jacquard_common::deps::smol_str::SmolStr::new_static("value") + ], + ), + properties: { + #[allow(unused_mut)] + let mut map = ::alloc::collections::BTreeMap::new(); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "key", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { + max_length: Some(100usize), + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "value", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { + max_length: Some(500usize), + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map + }, + ..Default::default() + } +} \ No newline at end of file diff --git a/crates/jacquard-codegen-tests/src/generated/macro_mode/test_ns1.rs b/crates/jacquard-codegen-tests/src/generated/macro_mode/test_ns1.rs new file mode 100644 index 00000000..deb2f915 --- /dev/null +++ b/crates/jacquard-codegen-tests/src/generated/macro_mode/test_ns1.rs @@ -0,0 +1,200 @@ +// @generated by jacquard-lexicon. DO NOT EDIT. +// +// Lexicon: test.ns1.defs +// +// This file was automatically generated from Lexicon schemas. +// Any manual changes will be overwritten on the next regeneration. + +/// Another type in ns1 for cross-namespace ref testing. + +#[derive( + serde::Serialize, + serde::Deserialize, + Debug, + Clone, + PartialEq, + Eq, + jacquard_derive::IntoStatic, + Default +)] + +#[serde( + rename_all = "camelCase", + bound(deserialize = "S: serde::Deserialize<'de> + jacquard_common::BosStr") +)] +pub struct Bar { + pub tag: S, + #[serde(flatten, default, skip_serializing_if = "core::option::Option::is_none")] + pub extra_data: core::option::Option< + alloc::collections::BTreeMap< + jacquard_common::deps::smol_str::SmolStr, + jacquard_common::types::value::Data, + >, + >, +} + +/// A type defined in ns1, referenced cross-namespace by ns2. + +#[derive( + serde::Serialize, + serde::Deserialize, + Debug, + Clone, + PartialEq, + Eq, + jacquard_derive::IntoStatic, + Default +)] + +#[serde( + rename_all = "camelCase", + bound(deserialize = "S: serde::Deserialize<'de> + jacquard_common::BosStr") +)] +pub struct Foo { + pub name: S, + #[serde(skip_serializing_if = "core::option::Option::is_none")] + pub value: core::option::Option, + #[serde(flatten, default, skip_serializing_if = "core::option::Option::is_none")] + pub extra_data: core::option::Option< + alloc::collections::BTreeMap< + jacquard_common::deps::smol_str::SmolStr, + jacquard_common::types::value::Data, + >, + >, +} + +impl jacquard_lexicon::schema::LexiconSchema for Bar { + fn nsid() -> &'static str { + "test.ns1.defs" + } + fn def_name() -> &'static str { + "bar" + } + fn lexicon_doc() -> jacquard_lexicon::lexicon::LexiconDoc<'static> { + lexicon_doc_test_ns1_defs() + } + fn validate(&self) -> Result<(), jacquard_lexicon::validation::ConstraintError> { + { + let value = &self.tag; + #[allow(unused_comparisons)] + if ::len(value.as_ref()) > 50usize { + return Err(jacquard_lexicon::validation::ConstraintError::MaxLength { + path: jacquard_lexicon::validation::ValidationPath::from_field( + "tag", + ), + max: 50usize, + actual: ::len(value.as_ref()), + }); + } + } + Ok(()) + } +} + +impl jacquard_lexicon::schema::LexiconSchema for Foo { + fn nsid() -> &'static str { + "test.ns1.defs" + } + fn def_name() -> &'static str { + "foo" + } + fn lexicon_doc() -> jacquard_lexicon::lexicon::LexiconDoc<'static> { + lexicon_doc_test_ns1_defs() + } + fn validate(&self) -> Result<(), jacquard_lexicon::validation::ConstraintError> { + { + let value = &self.name; + #[allow(unused_comparisons)] + if ::len(value.as_ref()) > 100usize { + return Err(jacquard_lexicon::validation::ConstraintError::MaxLength { + path: jacquard_lexicon::validation::ValidationPath::from_field( + "name", + ), + max: 100usize, + actual: ::len(value.as_ref()), + }); + } + } + Ok(()) + } +} + +fn lexicon_doc_test_ns1_defs() -> jacquard_lexicon::lexicon::LexiconDoc<'static> { + ::jacquard_lexicon::lexicon::LexiconDoc { + lexicon: ::jacquard_lexicon::lexicon::Lexicon::Lexicon1, + id: ::jacquard_common::CowStr::new_static("test.ns1.defs"), + defs: { + let mut map = ::alloc::collections::BTreeMap::new(); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static("bar"), + ::jacquard_lexicon::lexicon::LexUserType::Object(::jacquard_lexicon::lexicon::LexObject { + description: Some( + ::jacquard_common::CowStr::new_static( + "Another type in ns1 for cross-namespace ref testing.", + ), + ), + required: Some( + vec![ + ::jacquard_common::deps::smol_str::SmolStr::new_static("tag") + ], + ), + properties: { + #[allow(unused_mut)] + let mut map = ::alloc::collections::BTreeMap::new(); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "tag", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { + max_length: Some(50usize), + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static("foo"), + ::jacquard_lexicon::lexicon::LexUserType::Object(::jacquard_lexicon::lexicon::LexObject { + description: Some( + ::jacquard_common::CowStr::new_static( + "A type defined in ns1, referenced cross-namespace by ns2.", + ), + ), + required: Some( + vec![ + ::jacquard_common::deps::smol_str::SmolStr::new_static("name") + ], + ), + properties: { + #[allow(unused_mut)] + let mut map = ::alloc::collections::BTreeMap::new(); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "name", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { + max_length: Some(100usize), + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "value", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::Integer(::jacquard_lexicon::lexicon::LexInteger { + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map + }, + ..Default::default() + } +} \ No newline at end of file diff --git a/crates/jacquard-codegen-tests/src/generated/macro_mode/test_ns2.rs b/crates/jacquard-codegen-tests/src/generated/macro_mode/test_ns2.rs new file mode 100644 index 00000000..b94c757e --- /dev/null +++ b/crates/jacquard-codegen-tests/src/generated/macro_mode/test_ns2.rs @@ -0,0 +1,6 @@ +// @generated by jacquard-lexicon. DO NOT EDIT. +// +// This file was automatically generated from Lexicon schemas. +// Any manual changes will be overwritten on the next regeneration. + +pub mod consumer; \ No newline at end of file diff --git a/crates/jacquard-codegen-tests/src/generated/macro_mode/test_ns2/consumer.rs b/crates/jacquard-codegen-tests/src/generated/macro_mode/test_ns2/consumer.rs new file mode 100644 index 00000000..dc13b92e --- /dev/null +++ b/crates/jacquard-codegen-tests/src/generated/macro_mode/test_ns2/consumer.rs @@ -0,0 +1,275 @@ +// @generated by jacquard-lexicon. DO NOT EDIT. +// +// Lexicon: test.ns2.consumer +// +// This file was automatically generated from Lexicon schemas. +// Any manual changes will be overwritten on the next regeneration. + +/// An object that references types across namespaces. + +#[derive( + serde::Serialize, + serde::Deserialize, + Debug, + Clone, + PartialEq, + Eq, + jacquard_derive::IntoStatic +)] + +#[serde( + rename_all = "camelCase", + bound(deserialize = "S: serde::Deserialize<'de> + jacquard_common::BosStr") +)] +pub struct Consumer { + #[serde(skip_serializing_if = "core::option::Option::is_none")] + pub description: core::option::Option, + pub item: crate::macro_mode::test_ns1::Foo, + #[serde(skip_serializing_if = "core::option::Option::is_none")] + pub tags: core::option::Option>>, + #[serde(flatten, default, skip_serializing_if = "core::option::Option::is_none")] + pub extra_data: core::option::Option< + alloc::collections::BTreeMap< + jacquard_common::deps::smol_str::SmolStr, + jacquard_common::types::value::Data, + >, + >, +} + +impl jacquard_lexicon::schema::LexiconSchema +for Consumer { + fn nsid() -> &'static str { + "test.ns2.consumer" + } + fn def_name() -> &'static str { + "main" + } + fn lexicon_doc() -> jacquard_lexicon::lexicon::LexiconDoc<'static> { + lexicon_doc_test_ns2_consumer() + } + fn validate(&self) -> Result<(), jacquard_lexicon::validation::ConstraintError> { + if let Some(ref value) = self.description { + #[allow(unused_comparisons)] + if ::len(value.as_ref()) > 500usize { + return Err(jacquard_lexicon::validation::ConstraintError::MaxLength { + path: jacquard_lexicon::validation::ValidationPath::from_field( + "description", + ), + max: 500usize, + actual: ::len(value.as_ref()), + }); + } + } + Ok(()) + } +} + +pub mod consumer_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 Item; + } + /// Empty state - all required fields are unset + pub struct Empty(()); + impl sealed::Sealed for Empty {} + impl State for Empty { + type Item = Unset; + } + ///State transition - sets the `item` field to Set + pub struct SetItem(PhantomData St>); + impl sealed::Sealed for SetItem {} + impl State for SetItem { + type Item = Set; + } + /// Marker types for field names + #[allow(non_camel_case_types)] + pub mod members { + ///Marker type for the `item` field + pub struct item(()); + } +} + +/// Builder for constructing an instance of this type. +pub struct ConsumerBuilder { + _state: ::core::marker::PhantomData St>, + _fields: ( + core::option::Option, + core::option::Option>, + core::option::Option>>, + ), + _type: ::core::marker::PhantomData S>, +} + +impl Consumer { + /// Create a new builder for this type. + pub fn new() -> ConsumerBuilder { + ConsumerBuilder::new() + } +} + +impl ConsumerBuilder { + /// Create a new builder with all fields unset. + pub fn new() -> Self { + ConsumerBuilder { + _state: ::core::marker::PhantomData, + _fields: (None, None, None), + _type: ::core::marker::PhantomData, + } + } +} + +impl ConsumerBuilder { + /// Set the `description` field (optional) + pub fn description(mut self, value: impl Into>) -> Self { + self._fields.0 = value.into(); + self + } + /// Set the `description` field to an Option value (optional) + pub fn maybe_description(mut self, value: Option) -> Self { + self._fields.0 = value; + self + } +} + +impl ConsumerBuilder +where + St: consumer_state::State, + St::Item: consumer_state::IsUnset, +{ + /// Set the `item` field (required) + pub fn item( + mut self, + value: impl Into>, + ) -> ConsumerBuilder> { + self._fields.1 = ::core::option::Option::Some(value.into()); + ConsumerBuilder { + _state: ::core::marker::PhantomData, + _fields: self._fields, + _type: ::core::marker::PhantomData, + } + } +} + +impl ConsumerBuilder { + /// Set the `tags` field (optional) + pub fn tags( + mut self, + value: impl Into>>>, + ) -> Self { + self._fields.2 = value.into(); + self + } + /// Set the `tags` field to an Option value (optional) + pub fn maybe_tags( + mut self, + value: Option>>, + ) -> Self { + self._fields.2 = value; + self + } +} + +impl ConsumerBuilder +where + St: consumer_state::State, + St::Item: consumer_state::IsSet, +{ + /// Build the final struct. + pub fn build(self) -> Consumer { + Consumer { + description: self._fields.0, + item: self._fields.1.unwrap(), + tags: self._fields.2, + extra_data: Default::default(), + } + } + /// Build the final struct with custom extra_data. + pub fn build_with_data( + self, + extra_data: alloc::collections::BTreeMap< + jacquard_common::deps::smol_str::SmolStr, + jacquard_common::types::value::Data, + >, + ) -> Consumer { + Consumer { + description: self._fields.0, + item: self._fields.1.unwrap(), + tags: self._fields.2, + extra_data: Some(extra_data), + } + } +} + +fn lexicon_doc_test_ns2_consumer() -> jacquard_lexicon::lexicon::LexiconDoc<'static> { + ::jacquard_lexicon::lexicon::LexiconDoc { + lexicon: ::jacquard_lexicon::lexicon::Lexicon::Lexicon1, + id: ::jacquard_common::CowStr::new_static("test.ns2.consumer"), + defs: { + let mut map = ::alloc::collections::BTreeMap::new(); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static("main"), + ::jacquard_lexicon::lexicon::LexUserType::Object(::jacquard_lexicon::lexicon::LexObject { + description: Some( + ::jacquard_common::CowStr::new_static( + "An object that references types across namespaces.", + ), + ), + required: Some( + vec![ + ::jacquard_common::deps::smol_str::SmolStr::new_static("item") + ], + ), + properties: { + #[allow(unused_mut)] + let mut map = ::alloc::collections::BTreeMap::new(); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "description", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { + max_length: Some(500usize), + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "item", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::Ref(::jacquard_lexicon::lexicon::LexRef { + r#ref: ::jacquard_common::CowStr::new_static( + "test.ns1.defs#foo", + ), + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "tags", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::Array(::jacquard_lexicon::lexicon::LexArray { + items: ::jacquard_lexicon::lexicon::LexArrayItem::Ref(::jacquard_lexicon::lexicon::LexRef { + r#ref: ::jacquard_common::CowStr::new_static( + "test.ns1.defs#bar", + ), + ..Default::default() + }), + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map + }, + ..Default::default() + } +} \ No newline at end of file diff --git a/crates/jacquard-codegen-tests/src/generated/macro_mode/test_ns3.rs b/crates/jacquard-codegen-tests/src/generated/macro_mode/test_ns3.rs new file mode 100644 index 00000000..523ab25c --- /dev/null +++ b/crates/jacquard-codegen-tests/src/generated/macro_mode/test_ns3.rs @@ -0,0 +1,6 @@ +// @generated by jacquard-lexicon. DO NOT EDIT. +// +// This file was automatically generated from Lexicon schemas. +// Any manual changes will be overwritten on the next regeneration. + +pub mod collision; \ No newline at end of file diff --git a/crates/jacquard-codegen-tests/src/generated/macro_mode/test_ns3/collision.rs b/crates/jacquard-codegen-tests/src/generated/macro_mode/test_ns3/collision.rs new file mode 100644 index 00000000..5e7b29b7 --- /dev/null +++ b/crates/jacquard-codegen-tests/src/generated/macro_mode/test_ns3/collision.rs @@ -0,0 +1,482 @@ +// @generated by jacquard-lexicon. DO NOT EDIT. +// +// Lexicon: test.ns3.collision +// +// This file was automatically generated from Lexicon schemas. +// Any manual changes will be overwritten on the next regeneration. + +/// A locally-defined Foo that shares a name with test.ns1.defs#foo. + +#[derive( + serde::Serialize, + serde::Deserialize, + Debug, + Clone, + PartialEq, + Eq, + jacquard_derive::IntoStatic +)] + +#[serde( + rename_all = "camelCase", + bound(deserialize = "S: serde::Deserialize<'de> + jacquard_common::BosStr") +)] +pub struct Foo { + #[serde(skip_serializing_if = "core::option::Option::is_none")] + pub label: core::option::Option, + pub local_id: i64, + #[serde(flatten, default, skip_serializing_if = "core::option::Option::is_none")] + pub extra_data: core::option::Option< + alloc::collections::BTreeMap< + jacquard_common::deps::smol_str::SmolStr, + jacquard_common::types::value::Data, + >, + >, +} + +/// An object with both a local Foo ref and a cross-namespace Foo ref. + +#[derive( + serde::Serialize, + serde::Deserialize, + Debug, + Clone, + PartialEq, + Eq, + jacquard_derive::IntoStatic +)] + +#[serde( + rename_all = "camelCase", + bound(deserialize = "S: serde::Deserialize<'de> + jacquard_common::BosStr") +)] +pub struct Collision { + pub external_foo: crate::macro_mode::test_ns1::Foo, + pub local_foo: crate::macro_mode::test_ns3::collision::Foo, + #[serde(skip_serializing_if = "core::option::Option::is_none")] + pub note: core::option::Option, + #[serde(flatten, default, skip_serializing_if = "core::option::Option::is_none")] + pub extra_data: core::option::Option< + alloc::collections::BTreeMap< + jacquard_common::deps::smol_str::SmolStr, + jacquard_common::types::value::Data, + >, + >, +} + +impl jacquard_lexicon::schema::LexiconSchema for Foo { + fn nsid() -> &'static str { + "test.ns3.collision" + } + fn def_name() -> &'static str { + "foo" + } + fn lexicon_doc() -> jacquard_lexicon::lexicon::LexiconDoc<'static> { + lexicon_doc_test_ns3_collision() + } + fn validate(&self) -> Result<(), jacquard_lexicon::validation::ConstraintError> { + if let Some(ref value) = self.label { + #[allow(unused_comparisons)] + if ::len(value.as_ref()) > 100usize { + return Err(jacquard_lexicon::validation::ConstraintError::MaxLength { + path: jacquard_lexicon::validation::ValidationPath::from_field( + "label", + ), + max: 100usize, + actual: ::len(value.as_ref()), + }); + } + } + Ok(()) + } +} + +impl jacquard_lexicon::schema::LexiconSchema +for Collision { + fn nsid() -> &'static str { + "test.ns3.collision" + } + fn def_name() -> &'static str { + "main" + } + fn lexicon_doc() -> jacquard_lexicon::lexicon::LexiconDoc<'static> { + lexicon_doc_test_ns3_collision() + } + fn validate(&self) -> Result<(), jacquard_lexicon::validation::ConstraintError> { + Ok(()) + } +} + +pub mod foo_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 LocalId; + } + /// Empty state - all required fields are unset + pub struct Empty(()); + impl sealed::Sealed for Empty {} + impl State for Empty { + type LocalId = Unset; + } + ///State transition - sets the `local_id` field to Set + pub struct SetLocalId(PhantomData St>); + impl sealed::Sealed for SetLocalId {} + impl State for SetLocalId { + type LocalId = Set; + } + /// Marker types for field names + #[allow(non_camel_case_types)] + pub mod members { + ///Marker type for the `local_id` field + pub struct local_id(()); + } +} + +/// Builder for constructing an instance of this type. +pub struct FooBuilder { + _state: ::core::marker::PhantomData St>, + _fields: (core::option::Option, core::option::Option), + _type: ::core::marker::PhantomData S>, +} + +impl Foo { + /// Create a new builder for this type. + pub fn new() -> FooBuilder { + FooBuilder::new() + } +} + +impl FooBuilder { + /// Create a new builder with all fields unset. + pub fn new() -> Self { + FooBuilder { + _state: ::core::marker::PhantomData, + _fields: (None, None), + _type: ::core::marker::PhantomData, + } + } +} + +impl FooBuilder { + /// Set the `label` field (optional) + pub fn label(mut self, value: impl Into>) -> Self { + self._fields.0 = value.into(); + self + } + /// Set the `label` field to an Option value (optional) + pub fn maybe_label(mut self, value: Option) -> Self { + self._fields.0 = value; + self + } +} + +impl FooBuilder +where + St: foo_state::State, + St::LocalId: foo_state::IsUnset, +{ + /// Set the `localId` field (required) + pub fn local_id( + mut self, + value: impl Into, + ) -> FooBuilder> { + self._fields.1 = ::core::option::Option::Some(value.into()); + FooBuilder { + _state: ::core::marker::PhantomData, + _fields: self._fields, + _type: ::core::marker::PhantomData, + } + } +} + +impl FooBuilder +where + St: foo_state::State, + St::LocalId: foo_state::IsSet, +{ + /// Build the final struct. + pub fn build(self) -> Foo { + Foo { + label: self._fields.0, + local_id: self._fields.1.unwrap(), + extra_data: Default::default(), + } + } + /// Build the final struct with custom extra_data. + pub fn build_with_data( + self, + extra_data: alloc::collections::BTreeMap< + jacquard_common::deps::smol_str::SmolStr, + jacquard_common::types::value::Data, + >, + ) -> Foo { + Foo { + label: self._fields.0, + local_id: self._fields.1.unwrap(), + extra_data: Some(extra_data), + } + } +} + +fn lexicon_doc_test_ns3_collision() -> jacquard_lexicon::lexicon::LexiconDoc<'static> { + ::jacquard_lexicon::lexicon::LexiconDoc { + lexicon: ::jacquard_lexicon::lexicon::Lexicon::Lexicon1, + id: ::jacquard_common::CowStr::new_static("test.ns3.collision"), + defs: { + let mut map = ::alloc::collections::BTreeMap::new(); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static("foo"), + ::jacquard_lexicon::lexicon::LexUserType::Object(::jacquard_lexicon::lexicon::LexObject { + description: Some( + ::jacquard_common::CowStr::new_static( + "A locally-defined Foo that shares a name with test.ns1.defs#foo.", + ), + ), + required: Some( + vec![ + ::jacquard_common::deps::smol_str::SmolStr::new_static("localId") + ], + ), + properties: { + #[allow(unused_mut)] + let mut map = ::alloc::collections::BTreeMap::new(); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "label", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { + max_length: Some(100usize), + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "localId", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::Integer(::jacquard_lexicon::lexicon::LexInteger { + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static("main"), + ::jacquard_lexicon::lexicon::LexUserType::Object(::jacquard_lexicon::lexicon::LexObject { + description: Some( + ::jacquard_common::CowStr::new_static( + "An object with both a local Foo ref and a cross-namespace Foo ref.", + ), + ), + required: Some( + vec![ + ::jacquard_common::deps::smol_str::SmolStr::new_static("localFoo"), + ::jacquard_common::deps::smol_str::SmolStr::new_static("externalFoo") + ], + ), + properties: { + #[allow(unused_mut)] + let mut map = ::alloc::collections::BTreeMap::new(); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "externalFoo", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::Ref(::jacquard_lexicon::lexicon::LexRef { + r#ref: ::jacquard_common::CowStr::new_static( + "test.ns1.defs#foo", + ), + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "localFoo", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::Ref(::jacquard_lexicon::lexicon::LexRef { + r#ref: ::jacquard_common::CowStr::new_static("#foo"), + ..Default::default() + }), + ); + map.insert( + ::jacquard_common::deps::smol_str::SmolStr::new_static( + "note", + ), + ::jacquard_lexicon::lexicon::LexObjectProperty::String(::jacquard_lexicon::lexicon::LexString { + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map + }, + ..Default::default() + } +} + +pub mod collision_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 LocalFoo; + type ExternalFoo; + } + /// Empty state - all required fields are unset + pub struct Empty(()); + impl sealed::Sealed for Empty {} + impl State for Empty { + type LocalFoo = Unset; + type ExternalFoo = Unset; + } + ///State transition - sets the `local_foo` field to Set + pub struct SetLocalFoo(PhantomData St>); + impl sealed::Sealed for SetLocalFoo {} + impl State for SetLocalFoo { + type LocalFoo = Set; + type ExternalFoo = St::ExternalFoo; + } + ///State transition - sets the `external_foo` field to Set + pub struct SetExternalFoo(PhantomData St>); + impl sealed::Sealed for SetExternalFoo {} + impl State for SetExternalFoo { + type LocalFoo = St::LocalFoo; + type ExternalFoo = Set; + } + /// Marker types for field names + #[allow(non_camel_case_types)] + pub mod members { + ///Marker type for the `local_foo` field + pub struct local_foo(()); + ///Marker type for the `external_foo` field + pub struct external_foo(()); + } +} + +/// Builder for constructing an instance of this type. +pub struct CollisionBuilder { + _state: ::core::marker::PhantomData St>, + _fields: ( + core::option::Option>, + core::option::Option>, + core::option::Option, + ), + _type: ::core::marker::PhantomData S>, +} + +impl Collision { + /// Create a new builder for this type. + pub fn new() -> CollisionBuilder { + CollisionBuilder::new() + } +} + +impl CollisionBuilder { + /// Create a new builder with all fields unset. + pub fn new() -> Self { + CollisionBuilder { + _state: ::core::marker::PhantomData, + _fields: (None, None, None), + _type: ::core::marker::PhantomData, + } + } +} + +impl CollisionBuilder +where + St: collision_state::State, + St::ExternalFoo: collision_state::IsUnset, +{ + /// Set the `externalFoo` field (required) + pub fn external_foo( + mut self, + value: impl Into>, + ) -> CollisionBuilder> { + self._fields.0 = ::core::option::Option::Some(value.into()); + CollisionBuilder { + _state: ::core::marker::PhantomData, + _fields: self._fields, + _type: ::core::marker::PhantomData, + } + } +} + +impl CollisionBuilder +where + St: collision_state::State, + St::LocalFoo: collision_state::IsUnset, +{ + /// Set the `localFoo` field (required) + pub fn local_foo( + mut self, + value: impl Into>, + ) -> CollisionBuilder> { + self._fields.1 = ::core::option::Option::Some(value.into()); + CollisionBuilder { + _state: ::core::marker::PhantomData, + _fields: self._fields, + _type: ::core::marker::PhantomData, + } + } +} + +impl CollisionBuilder { + /// Set the `note` field (optional) + pub fn note(mut self, value: impl Into>) -> Self { + self._fields.2 = value.into(); + self + } + /// Set the `note` field to an Option value (optional) + pub fn maybe_note(mut self, value: Option) -> Self { + self._fields.2 = value; + self + } +} + +impl CollisionBuilder +where + St: collision_state::State, + St::LocalFoo: collision_state::IsSet, + St::ExternalFoo: collision_state::IsSet, +{ + /// Build the final struct. + pub fn build(self) -> Collision { + Collision { + external_foo: self._fields.0.unwrap(), + local_foo: self._fields.1.unwrap(), + note: self._fields.2, + extra_data: Default::default(), + } + } + /// Build the final struct with custom extra_data. + pub fn build_with_data( + self, + extra_data: alloc::collections::BTreeMap< + jacquard_common::deps::smol_str::SmolStr, + jacquard_common::types::value::Data, + >, + ) -> Collision { + Collision { + external_foo: self._fields.0.unwrap(), + local_foo: self._fields.1.unwrap(), + note: self._fields.2, + extra_data: Some(extra_data), + } + } +} \ No newline at end of file diff --git a/crates/jacquard-codegen-tests/src/generated/pretty/app_bsky.rs b/crates/jacquard-codegen-tests/src/generated/pretty/app_bsky.rs new file mode 100644 index 00000000..0dc7c1b8 --- /dev/null +++ b/crates/jacquard-codegen-tests/src/generated/pretty/app_bsky.rs @@ -0,0 +1,7 @@ +// @generated by jacquard-lexicon. DO NOT EDIT. +// +// This file was automatically generated from Lexicon schemas. +// Any manual changes will be overwritten on the next regeneration. + +pub mod embed; +pub mod richtext; \ No newline at end of file diff --git a/crates/jacquard-codegen-tests/src/generated/pretty/app_bsky/embed.rs b/crates/jacquard-codegen-tests/src/generated/pretty/app_bsky/embed.rs new file mode 100644 index 00000000..0d2e68d6 --- /dev/null +++ b/crates/jacquard-codegen-tests/src/generated/pretty/app_bsky/embed.rs @@ -0,0 +1,6 @@ +// @generated by jacquard-lexicon. DO NOT EDIT. +// +// This file was automatically generated from Lexicon schemas. +// Any manual changes will be overwritten on the next regeneration. + +pub mod external; \ No newline at end of file diff --git a/crates/jacquard-codegen-tests/src/generated/pretty/app_bsky/embed/external.rs b/crates/jacquard-codegen-tests/src/generated/pretty/app_bsky/embed/external.rs new file mode 100644 index 00000000..90f8a18b --- /dev/null +++ b/crates/jacquard-codegen-tests/src/generated/pretty/app_bsky/embed/external.rs @@ -0,0 +1,868 @@ +// @generated by jacquard-lexicon. DO NOT EDIT. +// +// Lexicon: app.bsky.embed.external +// +// 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::blob::BlobRef; +use jacquard_common::types::string::UriValue; +use jacquard_common::types::value::Data; +use jacquard_derive::IntoStatic; +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::pretty::app_bsky::embed::external; + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)] +#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))] +pub struct External { + pub description: S, + #[serde(skip_serializing_if = "Option::is_none")] + pub thumb: Option>, + pub title: S, + pub uri: UriValue, + #[serde(flatten, default, skip_serializing_if = "Option::is_none")] + pub extra_data: Option>>, +} + +/// A representation of some externally linked content (eg, a URL and 'card'), embedded in a Bluesky record (eg, a post). + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)] +#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))] +pub struct ExternalRecord { + pub external: external::External, + #[serde(flatten, default, skip_serializing_if = "Option::is_none")] + pub extra_data: Option>>, +} + + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)] +#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))] +pub struct View { + pub external: external::ViewExternal, + #[serde(flatten, default, skip_serializing_if = "Option::is_none")] + pub extra_data: Option>>, +} + + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)] +#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))] +pub struct ViewExternal { + pub description: S, + #[serde(skip_serializing_if = "Option::is_none")] + pub thumb: Option>, + pub title: S, + pub uri: UriValue, + #[serde(flatten, default, skip_serializing_if = "Option::is_none")] + pub extra_data: Option>>, +} + +impl LexiconSchema for External { + fn nsid() -> &'static str { + "app.bsky.embed.external" + } + fn def_name() -> &'static str { + "external" + } + fn lexicon_doc() -> LexiconDoc<'static> { + lexicon_doc_app_bsky_embed_external() + } + fn validate(&self) -> Result<(), ConstraintError> { + if let Some(ref value) = self.thumb { + { + let size = value.blob().size; + if size > 1000000usize { + return Err(ConstraintError::BlobTooLarge { + path: ValidationPath::from_field("thumb"), + max: 1000000usize, + actual: size, + }); + } + } + } + if let Some(ref value) = self.thumb { + { + let mime = value.blob().mime_type.as_str(); + let accepted: &[&str] = &["image/*"]; + let matched = accepted + .iter() + .any(|pattern| { + if *pattern == "*/*" { + true + } else if pattern.ends_with("/*") { + let prefix = &pattern[..pattern.len() - 2]; + mime.starts_with(prefix) + && mime.as_bytes().get(prefix.len()) == Some(&b'/') + } else { + mime == *pattern + } + }); + if !matched { + return Err(ConstraintError::BlobMimeTypeNotAccepted { + path: ValidationPath::from_field("thumb"), + accepted: vec!["image/*".to_string()], + actual: mime.to_string(), + }); + } + } + } + Ok(()) + } +} + +impl LexiconSchema for ExternalRecord { + fn nsid() -> &'static str { + "app.bsky.embed.external" + } + fn def_name() -> &'static str { + "main" + } + fn lexicon_doc() -> LexiconDoc<'static> { + lexicon_doc_app_bsky_embed_external() + } + fn validate(&self) -> Result<(), ConstraintError> { + Ok(()) + } +} + +impl LexiconSchema for View { + fn nsid() -> &'static str { + "app.bsky.embed.external" + } + fn def_name() -> &'static str { + "view" + } + fn lexicon_doc() -> LexiconDoc<'static> { + lexicon_doc_app_bsky_embed_external() + } + fn validate(&self) -> Result<(), ConstraintError> { + Ok(()) + } +} + +impl LexiconSchema for ViewExternal { + fn nsid() -> &'static str { + "app.bsky.embed.external" + } + fn def_name() -> &'static str { + "viewExternal" + } + fn lexicon_doc() -> LexiconDoc<'static> { + lexicon_doc_app_bsky_embed_external() + } + fn validate(&self) -> Result<(), ConstraintError> { + Ok(()) + } +} + +pub mod external_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 Title; + type Description; + type Uri; + } + /// Empty state - all required fields are unset + pub struct Empty(()); + impl sealed::Sealed for Empty {} + impl State for Empty { + type Title = Unset; + type Description = Unset; + type Uri = Unset; + } + ///State transition - sets the `title` field to Set + pub struct SetTitle(PhantomData St>); + impl sealed::Sealed for SetTitle {} + impl State for SetTitle { + type Title = Set; + type Description = St::Description; + type Uri = St::Uri; + } + ///State transition - sets the `description` field to Set + pub struct SetDescription(PhantomData St>); + impl sealed::Sealed for SetDescription {} + impl State for SetDescription { + type Title = St::Title; + type Description = Set; + type Uri = St::Uri; + } + ///State transition - sets the `uri` field to Set + pub struct SetUri(PhantomData St>); + impl sealed::Sealed for SetUri {} + impl State for SetUri { + type Title = St::Title; + type Description = St::Description; + type Uri = Set; + } + /// Marker types for field names + #[allow(non_camel_case_types)] + pub mod members { + ///Marker type for the `title` field + pub struct title(()); + ///Marker type for the `description` field + pub struct description(()); + ///Marker type for the `uri` field + pub struct uri(()); + } +} + +/// Builder for constructing an instance of this type. +pub struct ExternalBuilder { + _state: PhantomData St>, + _fields: (Option, Option>, Option, Option>), + _type: PhantomData S>, +} + +impl External { + /// Create a new builder for this type. + pub fn new() -> ExternalBuilder { + ExternalBuilder::new() + } +} + +impl ExternalBuilder { + /// Create a new builder with all fields unset. + pub fn new() -> Self { + ExternalBuilder { + _state: PhantomData, + _fields: (None, None, None, None), + _type: PhantomData, + } + } +} + +impl ExternalBuilder +where + St: external_state::State, + St::Description: external_state::IsUnset, +{ + /// Set the `description` field (required) + pub fn description( + mut self, + value: impl Into, + ) -> ExternalBuilder> { + self._fields.0 = Option::Some(value.into()); + ExternalBuilder { + _state: PhantomData, + _fields: self._fields, + _type: PhantomData, + } + } +} + +impl ExternalBuilder { + /// Set the `thumb` field (optional) + pub fn thumb(mut self, value: impl Into>>) -> Self { + self._fields.1 = value.into(); + self + } + /// Set the `thumb` field to an Option value (optional) + pub fn maybe_thumb(mut self, value: Option>) -> Self { + self._fields.1 = value; + self + } +} + +impl ExternalBuilder +where + St: external_state::State, + St::Title: external_state::IsUnset, +{ + /// Set the `title` field (required) + pub fn title( + mut self, + value: impl Into, + ) -> ExternalBuilder> { + self._fields.2 = Option::Some(value.into()); + ExternalBuilder { + _state: PhantomData, + _fields: self._fields, + _type: PhantomData, + } + } +} + +impl ExternalBuilder +where + St: external_state::State, + St::Uri: external_state::IsUnset, +{ + /// Set the `uri` field (required) + pub fn uri( + mut self, + value: impl Into>, + ) -> ExternalBuilder> { + self._fields.3 = Option::Some(value.into()); + ExternalBuilder { + _state: PhantomData, + _fields: self._fields, + _type: PhantomData, + } + } +} + +impl ExternalBuilder +where + St: external_state::State, + St::Title: external_state::IsSet, + St::Description: external_state::IsSet, + St::Uri: external_state::IsSet, +{ + /// Build the final struct. + pub fn build(self) -> External { + External { + description: self._fields.0.unwrap(), + thumb: self._fields.1, + title: self._fields.2.unwrap(), + uri: 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>) -> External { + External { + description: self._fields.0.unwrap(), + thumb: self._fields.1, + title: self._fields.2.unwrap(), + uri: self._fields.3.unwrap(), + extra_data: Some(extra_data), + } + } +} + +fn lexicon_doc_app_bsky_embed_external() -> 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("app.bsky.embed.external"), + defs: { + let mut map = BTreeMap::new(); + map.insert( + SmolStr::new_static("external"), + LexUserType::Object(LexObject { + required: Some( + vec![ + SmolStr::new_static("uri"), SmolStr::new_static("title"), + SmolStr::new_static("description") + ], + ), + properties: { + #[allow(unused_mut)] + let mut map = BTreeMap::new(); + map.insert( + SmolStr::new_static("description"), + LexObjectProperty::String(LexString { ..Default::default() }), + ); + map.insert( + SmolStr::new_static("thumb"), + LexObjectProperty::Blob(LexBlob { ..Default::default() }), + ); + map.insert( + SmolStr::new_static("title"), + LexObjectProperty::String(LexString { ..Default::default() }), + ); + map.insert( + SmolStr::new_static("uri"), + LexObjectProperty::String(LexString { + format: Some(LexStringFormat::Uri), + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("main"), + LexUserType::Object(LexObject { + description: Some( + CowStr::new_static( + "A representation of some externally linked content (eg, a URL and 'card'), embedded in a Bluesky record (eg, a post).", + ), + ), + required: Some(vec![SmolStr::new_static("external")]), + properties: { + #[allow(unused_mut)] + let mut map = BTreeMap::new(); + map.insert( + SmolStr::new_static("external"), + LexObjectProperty::Ref(LexRef { + r#ref: CowStr::new_static("#external"), + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("view"), + LexUserType::Object(LexObject { + required: Some(vec![SmolStr::new_static("external")]), + properties: { + #[allow(unused_mut)] + let mut map = BTreeMap::new(); + map.insert( + SmolStr::new_static("external"), + LexObjectProperty::Ref(LexRef { + r#ref: CowStr::new_static("#viewExternal"), + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("viewExternal"), + LexUserType::Object(LexObject { + required: Some( + vec![ + SmolStr::new_static("uri"), SmolStr::new_static("title"), + SmolStr::new_static("description") + ], + ), + properties: { + #[allow(unused_mut)] + let mut map = BTreeMap::new(); + map.insert( + SmolStr::new_static("description"), + LexObjectProperty::String(LexString { ..Default::default() }), + ); + map.insert( + SmolStr::new_static("thumb"), + LexObjectProperty::String(LexString { + format: Some(LexStringFormat::Uri), + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("title"), + LexObjectProperty::String(LexString { ..Default::default() }), + ); + map.insert( + SmolStr::new_static("uri"), + LexObjectProperty::String(LexString { + format: Some(LexStringFormat::Uri), + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map + }, + ..Default::default() + } +} + +pub mod external_record_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 External; + } + /// Empty state - all required fields are unset + pub struct Empty(()); + impl sealed::Sealed for Empty {} + impl State for Empty { + type External = Unset; + } + ///State transition - sets the `external` field to Set + pub struct SetExternal(PhantomData St>); + impl sealed::Sealed for SetExternal {} + impl State for SetExternal { + type External = Set; + } + /// Marker types for field names + #[allow(non_camel_case_types)] + pub mod members { + ///Marker type for the `external` field + pub struct external(()); + } +} + +/// Builder for constructing an instance of this type. +pub struct ExternalRecordBuilder { + _state: PhantomData St>, + _fields: (Option>,), + _type: PhantomData S>, +} + +impl ExternalRecord { + /// Create a new builder for this type. + pub fn new() -> ExternalRecordBuilder { + ExternalRecordBuilder::new() + } +} + +impl ExternalRecordBuilder { + /// Create a new builder with all fields unset. + pub fn new() -> Self { + ExternalRecordBuilder { + _state: PhantomData, + _fields: (None,), + _type: PhantomData, + } + } +} + +impl ExternalRecordBuilder +where + St: external_record_state::State, + St::External: external_record_state::IsUnset, +{ + /// Set the `external` field (required) + pub fn external( + mut self, + value: impl Into>, + ) -> ExternalRecordBuilder> { + self._fields.0 = Option::Some(value.into()); + ExternalRecordBuilder { + _state: PhantomData, + _fields: self._fields, + _type: PhantomData, + } + } +} + +impl ExternalRecordBuilder +where + St: external_record_state::State, + St::External: external_record_state::IsSet, +{ + /// Build the final struct. + pub fn build(self) -> ExternalRecord { + ExternalRecord { + external: self._fields.0.unwrap(), + extra_data: Default::default(), + } + } + /// Build the final struct with custom extra_data. + pub fn build_with_data( + self, + extra_data: BTreeMap>, + ) -> ExternalRecord { + ExternalRecord { + external: self._fields.0.unwrap(), + extra_data: Some(extra_data), + } + } +} + +pub mod view_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 External; + } + /// Empty state - all required fields are unset + pub struct Empty(()); + impl sealed::Sealed for Empty {} + impl State for Empty { + type External = Unset; + } + ///State transition - sets the `external` field to Set + pub struct SetExternal(PhantomData St>); + impl sealed::Sealed for SetExternal {} + impl State for SetExternal { + type External = Set; + } + /// Marker types for field names + #[allow(non_camel_case_types)] + pub mod members { + ///Marker type for the `external` field + pub struct external(()); + } +} + +/// Builder for constructing an instance of this type. +pub struct ViewBuilder { + _state: PhantomData St>, + _fields: (Option>,), + _type: PhantomData S>, +} + +impl View { + /// Create a new builder for this type. + pub fn new() -> ViewBuilder { + ViewBuilder::new() + } +} + +impl ViewBuilder { + /// Create a new builder with all fields unset. + pub fn new() -> Self { + ViewBuilder { + _state: PhantomData, + _fields: (None,), + _type: PhantomData, + } + } +} + +impl ViewBuilder +where + St: view_state::State, + St::External: view_state::IsUnset, +{ + /// Set the `external` field (required) + pub fn external( + mut self, + value: impl Into>, + ) -> ViewBuilder> { + self._fields.0 = Option::Some(value.into()); + ViewBuilder { + _state: PhantomData, + _fields: self._fields, + _type: PhantomData, + } + } +} + +impl ViewBuilder +where + St: view_state::State, + St::External: view_state::IsSet, +{ + /// Build the final struct. + pub fn build(self) -> View { + View { + external: self._fields.0.unwrap(), + extra_data: Default::default(), + } + } + /// Build the final struct with custom extra_data. + pub fn build_with_data(self, extra_data: BTreeMap>) -> View { + View { + external: self._fields.0.unwrap(), + extra_data: Some(extra_data), + } + } +} + +pub mod view_external_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 Uri; + type Title; + type Description; + } + /// Empty state - all required fields are unset + pub struct Empty(()); + impl sealed::Sealed for Empty {} + impl State for Empty { + type Uri = Unset; + type Title = Unset; + type Description = Unset; + } + ///State transition - sets the `uri` field to Set + pub struct SetUri(PhantomData St>); + impl sealed::Sealed for SetUri {} + impl State for SetUri { + type Uri = Set; + type Title = St::Title; + type Description = St::Description; + } + ///State transition - sets the `title` field to Set + pub struct SetTitle(PhantomData St>); + impl sealed::Sealed for SetTitle {} + impl State for SetTitle { + type Uri = St::Uri; + type Title = Set; + type Description = St::Description; + } + ///State transition - sets the `description` field to Set + pub struct SetDescription(PhantomData St>); + impl sealed::Sealed for SetDescription {} + impl State for SetDescription { + type Uri = St::Uri; + type Title = St::Title; + type Description = Set; + } + /// Marker types for field names + #[allow(non_camel_case_types)] + pub mod members { + ///Marker type for the `uri` field + pub struct uri(()); + ///Marker type for the `title` field + pub struct title(()); + ///Marker type for the `description` field + pub struct description(()); + } +} + +/// Builder for constructing an instance of this type. +pub struct ViewExternalBuilder { + _state: PhantomData St>, + _fields: (Option, Option>, Option, Option>), + _type: PhantomData S>, +} + +impl ViewExternal { + /// Create a new builder for this type. + pub fn new() -> ViewExternalBuilder { + ViewExternalBuilder::new() + } +} + +impl ViewExternalBuilder { + /// Create a new builder with all fields unset. + pub fn new() -> Self { + ViewExternalBuilder { + _state: PhantomData, + _fields: (None, None, None, None), + _type: PhantomData, + } + } +} + +impl ViewExternalBuilder +where + St: view_external_state::State, + St::Description: view_external_state::IsUnset, +{ + /// Set the `description` field (required) + pub fn description( + mut self, + value: impl Into, + ) -> ViewExternalBuilder> { + self._fields.0 = Option::Some(value.into()); + ViewExternalBuilder { + _state: PhantomData, + _fields: self._fields, + _type: PhantomData, + } + } +} + +impl ViewExternalBuilder { + /// Set the `thumb` field (optional) + pub fn thumb(mut self, value: impl Into>>) -> Self { + self._fields.1 = value.into(); + self + } + /// Set the `thumb` field to an Option value (optional) + pub fn maybe_thumb(mut self, value: Option>) -> Self { + self._fields.1 = value; + self + } +} + +impl ViewExternalBuilder +where + St: view_external_state::State, + St::Title: view_external_state::IsUnset, +{ + /// Set the `title` field (required) + pub fn title( + mut self, + value: impl Into, + ) -> ViewExternalBuilder> { + self._fields.2 = Option::Some(value.into()); + ViewExternalBuilder { + _state: PhantomData, + _fields: self._fields, + _type: PhantomData, + } + } +} + +impl ViewExternalBuilder +where + St: view_external_state::State, + St::Uri: view_external_state::IsUnset, +{ + /// Set the `uri` field (required) + pub fn uri( + mut self, + value: impl Into>, + ) -> ViewExternalBuilder> { + self._fields.3 = Option::Some(value.into()); + ViewExternalBuilder { + _state: PhantomData, + _fields: self._fields, + _type: PhantomData, + } + } +} + +impl ViewExternalBuilder +where + St: view_external_state::State, + St::Uri: view_external_state::IsSet, + St::Title: view_external_state::IsSet, + St::Description: view_external_state::IsSet, +{ + /// Build the final struct. + pub fn build(self) -> ViewExternal { + ViewExternal { + description: self._fields.0.unwrap(), + thumb: self._fields.1, + title: self._fields.2.unwrap(), + uri: 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>, + ) -> ViewExternal { + ViewExternal { + description: self._fields.0.unwrap(), + thumb: self._fields.1, + title: self._fields.2.unwrap(), + uri: self._fields.3.unwrap(), + extra_data: Some(extra_data), + } + } +} \ No newline at end of file diff --git a/crates/jacquard-codegen-tests/src/generated/pretty/app_bsky/richtext.rs b/crates/jacquard-codegen-tests/src/generated/pretty/app_bsky/richtext.rs new file mode 100644 index 00000000..b7b3177b --- /dev/null +++ b/crates/jacquard-codegen-tests/src/generated/pretty/app_bsky/richtext.rs @@ -0,0 +1,6 @@ +// @generated by jacquard-lexicon. DO NOT EDIT. +// +// This file was automatically generated from Lexicon schemas. +// Any manual changes will be overwritten on the next regeneration. + +pub mod facet; \ No newline at end of file diff --git a/crates/jacquard-codegen-tests/src/generated/pretty/app_bsky/richtext/facet.rs b/crates/jacquard-codegen-tests/src/generated/pretty/app_bsky/richtext/facet.rs new file mode 100644 index 00000000..ca07f0f4 --- /dev/null +++ b/crates/jacquard-codegen-tests/src/generated/pretty/app_bsky/richtext/facet.rs @@ -0,0 +1,835 @@ +// @generated by jacquard-lexicon. DO NOT EDIT. +// +// Lexicon: app.bsky.richtext.facet +// +// 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::string::{Did, UriValue}; +use jacquard_common::types::value::Data; +use jacquard_derive::{IntoStatic, 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::pretty::app_bsky::richtext::facet; +/// Specifies the sub-string range a facet feature applies to. Start index is inclusive, end index is exclusive. Indices are zero-indexed, counting bytes of the UTF-8 encoded text. NOTE: some languages, like Javascript, use UTF-16 or Unicode codepoints for string slice indexing; in these languages, convert to byte arrays before working with facets. + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)] +#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))] +pub struct ByteSlice { + pub byte_end: i64, + pub byte_start: i64, + #[serde(flatten, default, skip_serializing_if = "Option::is_none")] + pub extra_data: Option>>, +} + +/// Facet feature for a URL. The text URL may have been simplified or truncated, but the facet reference should be a complete URL. + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)] +#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))] +pub struct Link { + pub uri: UriValue, + #[serde(flatten, default, skip_serializing_if = "Option::is_none")] + pub extra_data: Option>>, +} + +/// Annotation of a sub-string within rich text. + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)] +#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))] +pub struct Facet { + pub features: Vec>, + pub index: facet::ByteSlice, + #[serde(flatten, default, skip_serializing_if = "Option::is_none")] + pub extra_data: Option>>, +} + + +#[open_union] +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)] +#[serde(tag = "$type", bound(deserialize = "S: Deserialize<'de> + BosStr"))] +pub enum FacetFeaturesItem { + #[serde(rename = "app.bsky.richtext.facet#mention")] + Mention(Box>), + #[serde(rename = "app.bsky.richtext.facet#link")] + Link(Box>), + #[serde(rename = "app.bsky.richtext.facet#tag")] + Tag(Box>), +} + +/// Facet feature for mention of another account. The text is usually a handle, including a '@' prefix, but the facet reference is a DID. + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)] +#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))] +pub struct Mention { + pub did: Did, + #[serde(flatten, default, skip_serializing_if = "Option::is_none")] + pub extra_data: Option>>, +} + +/// Facet feature for a hashtag. The text usually includes a '#' prefix, but the facet reference should not (except in the case of 'double hash tags'). + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic, Default)] +#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))] +pub struct Tag { + pub tag: S, + #[serde(flatten, default, skip_serializing_if = "Option::is_none")] + pub extra_data: Option>>, +} + +impl LexiconSchema for ByteSlice { + fn nsid() -> &'static str { + "app.bsky.richtext.facet" + } + fn def_name() -> &'static str { + "byteSlice" + } + fn lexicon_doc() -> LexiconDoc<'static> { + lexicon_doc_app_bsky_richtext_facet() + } + fn validate(&self) -> Result<(), ConstraintError> { + { + let value = &self.byte_end; + if *value < 0i64 { + return Err(ConstraintError::Minimum { + path: ValidationPath::from_field("byte_end"), + min: 0i64, + actual: *value, + }); + } + } + { + let value = &self.byte_start; + if *value < 0i64 { + return Err(ConstraintError::Minimum { + path: ValidationPath::from_field("byte_start"), + min: 0i64, + actual: *value, + }); + } + } + Ok(()) + } +} + +impl LexiconSchema for Link { + fn nsid() -> &'static str { + "app.bsky.richtext.facet" + } + fn def_name() -> &'static str { + "link" + } + fn lexicon_doc() -> LexiconDoc<'static> { + lexicon_doc_app_bsky_richtext_facet() + } + fn validate(&self) -> Result<(), ConstraintError> { + Ok(()) + } +} + +impl LexiconSchema for Facet { + fn nsid() -> &'static str { + "app.bsky.richtext.facet" + } + fn def_name() -> &'static str { + "main" + } + fn lexicon_doc() -> LexiconDoc<'static> { + lexicon_doc_app_bsky_richtext_facet() + } + fn validate(&self) -> Result<(), ConstraintError> { + Ok(()) + } +} + +impl LexiconSchema for Mention { + fn nsid() -> &'static str { + "app.bsky.richtext.facet" + } + fn def_name() -> &'static str { + "mention" + } + fn lexicon_doc() -> LexiconDoc<'static> { + lexicon_doc_app_bsky_richtext_facet() + } + fn validate(&self) -> Result<(), ConstraintError> { + Ok(()) + } +} + +impl LexiconSchema for Tag { + fn nsid() -> &'static str { + "app.bsky.richtext.facet" + } + fn def_name() -> &'static str { + "tag" + } + fn lexicon_doc() -> LexiconDoc<'static> { + lexicon_doc_app_bsky_richtext_facet() + } + fn validate(&self) -> Result<(), ConstraintError> { + { + let value = &self.tag; + #[allow(unused_comparisons)] + if ::len(value.as_ref()) > 640usize { + return Err(ConstraintError::MaxLength { + path: ValidationPath::from_field("tag"), + max: 640usize, + actual: ::len(value.as_ref()), + }); + } + } + { + let value = &self.tag; + { + let count = UnicodeSegmentation::graphemes(value.as_ref(), true).count(); + if count > 64usize { + return Err(ConstraintError::MaxGraphemes { + path: ValidationPath::from_field("tag"), + max: 64usize, + actual: count, + }); + } + } + } + Ok(()) + } +} + +pub mod byte_slice_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 ByteEnd; + type ByteStart; + } + /// Empty state - all required fields are unset + pub struct Empty(()); + impl sealed::Sealed for Empty {} + impl State for Empty { + type ByteEnd = Unset; + type ByteStart = Unset; + } + ///State transition - sets the `byte_end` field to Set + pub struct SetByteEnd(PhantomData St>); + impl sealed::Sealed for SetByteEnd {} + impl State for SetByteEnd { + type ByteEnd = Set; + type ByteStart = St::ByteStart; + } + ///State transition - sets the `byte_start` field to Set + pub struct SetByteStart(PhantomData St>); + impl sealed::Sealed for SetByteStart {} + impl State for SetByteStart { + type ByteEnd = St::ByteEnd; + type ByteStart = Set; + } + /// Marker types for field names + #[allow(non_camel_case_types)] + pub mod members { + ///Marker type for the `byte_end` field + pub struct byte_end(()); + ///Marker type for the `byte_start` field + pub struct byte_start(()); + } +} + +/// Builder for constructing an instance of this type. +pub struct ByteSliceBuilder { + _state: PhantomData St>, + _fields: (Option, Option), + _type: PhantomData S>, +} + +impl ByteSlice { + /// Create a new builder for this type. + pub fn new() -> ByteSliceBuilder { + ByteSliceBuilder::new() + } +} + +impl ByteSliceBuilder { + /// Create a new builder with all fields unset. + pub fn new() -> Self { + ByteSliceBuilder { + _state: PhantomData, + _fields: (None, None), + _type: PhantomData, + } + } +} + +impl ByteSliceBuilder +where + St: byte_slice_state::State, + St::ByteEnd: byte_slice_state::IsUnset, +{ + /// Set the `byteEnd` field (required) + pub fn byte_end( + mut self, + value: impl Into, + ) -> ByteSliceBuilder> { + self._fields.0 = Option::Some(value.into()); + ByteSliceBuilder { + _state: PhantomData, + _fields: self._fields, + _type: PhantomData, + } + } +} + +impl ByteSliceBuilder +where + St: byte_slice_state::State, + St::ByteStart: byte_slice_state::IsUnset, +{ + /// Set the `byteStart` field (required) + pub fn byte_start( + mut self, + value: impl Into, + ) -> ByteSliceBuilder> { + self._fields.1 = Option::Some(value.into()); + ByteSliceBuilder { + _state: PhantomData, + _fields: self._fields, + _type: PhantomData, + } + } +} + +impl ByteSliceBuilder +where + St: byte_slice_state::State, + St::ByteEnd: byte_slice_state::IsSet, + St::ByteStart: byte_slice_state::IsSet, +{ + /// Build the final struct. + pub fn build(self) -> ByteSlice { + ByteSlice { + byte_end: self._fields.0.unwrap(), + byte_start: self._fields.1.unwrap(), + extra_data: Default::default(), + } + } + /// Build the final struct with custom extra_data. + pub fn build_with_data( + self, + extra_data: BTreeMap>, + ) -> ByteSlice { + ByteSlice { + byte_end: self._fields.0.unwrap(), + byte_start: self._fields.1.unwrap(), + extra_data: Some(extra_data), + } + } +} + +fn lexicon_doc_app_bsky_richtext_facet() -> 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("app.bsky.richtext.facet"), + defs: { + let mut map = BTreeMap::new(); + map.insert( + SmolStr::new_static("byteSlice"), + LexUserType::Object(LexObject { + description: Some( + CowStr::new_static( + "Specifies the sub-string range a facet feature applies to. Start index is inclusive, end index is exclusive. Indices are zero-indexed, counting bytes of the UTF-8 encoded text. NOTE: some languages, like Javascript, use UTF-16 or Unicode codepoints for string slice indexing; in these languages, convert to byte arrays before working with facets.", + ), + ), + required: Some( + vec![ + SmolStr::new_static("byteStart"), + SmolStr::new_static("byteEnd") + ], + ), + properties: { + #[allow(unused_mut)] + let mut map = BTreeMap::new(); + map.insert( + SmolStr::new_static("byteEnd"), + LexObjectProperty::Integer(LexInteger { + minimum: Some(0i64), + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("byteStart"), + LexObjectProperty::Integer(LexInteger { + minimum: Some(0i64), + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("link"), + LexUserType::Object(LexObject { + description: Some( + CowStr::new_static( + "Facet feature for a URL. The text URL may have been simplified or truncated, but the facet reference should be a complete URL.", + ), + ), + required: Some(vec![SmolStr::new_static("uri")]), + properties: { + #[allow(unused_mut)] + let mut map = BTreeMap::new(); + map.insert( + SmolStr::new_static("uri"), + LexObjectProperty::String(LexString { + format: Some(LexStringFormat::Uri), + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("main"), + LexUserType::Object(LexObject { + description: Some( + CowStr::new_static( + "Annotation of a sub-string within rich text.", + ), + ), + required: Some( + vec![ + SmolStr::new_static("index"), SmolStr::new_static("features") + ], + ), + properties: { + #[allow(unused_mut)] + let mut map = BTreeMap::new(); + map.insert( + SmolStr::new_static("features"), + LexObjectProperty::Array(LexArray { + items: LexArrayItem::Union(LexRefUnion { + refs: vec![ + CowStr::new_static("#mention"), CowStr::new_static("#link"), + CowStr::new_static("#tag") + ], + ..Default::default() + }), + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("index"), + LexObjectProperty::Ref(LexRef { + r#ref: CowStr::new_static("#byteSlice"), + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("mention"), + LexUserType::Object(LexObject { + description: Some( + CowStr::new_static( + "Facet feature for mention of another account. The text is usually a handle, including a '@' prefix, but the facet reference is a DID.", + ), + ), + required: Some(vec![SmolStr::new_static("did")]), + properties: { + #[allow(unused_mut)] + let mut map = BTreeMap::new(); + map.insert( + SmolStr::new_static("did"), + LexObjectProperty::String(LexString { + format: Some(LexStringFormat::Did), + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("tag"), + LexUserType::Object(LexObject { + description: Some( + CowStr::new_static( + "Facet feature for a hashtag. The text usually includes a '#' prefix, but the facet reference should not (except in the case of 'double hash tags').", + ), + ), + required: Some(vec![SmolStr::new_static("tag")]), + properties: { + #[allow(unused_mut)] + let mut map = BTreeMap::new(); + map.insert( + SmolStr::new_static("tag"), + LexObjectProperty::String(LexString { + max_length: Some(640usize), + max_graphemes: Some(64usize), + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map + }, + ..Default::default() + } +} + +pub mod link_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 Uri; + } + /// Empty state - all required fields are unset + pub struct Empty(()); + impl sealed::Sealed for Empty {} + impl State for Empty { + type Uri = Unset; + } + ///State transition - sets the `uri` field to Set + pub struct SetUri(PhantomData St>); + impl sealed::Sealed for SetUri {} + impl State for SetUri { + type Uri = Set; + } + /// Marker types for field names + #[allow(non_camel_case_types)] + pub mod members { + ///Marker type for the `uri` field + pub struct uri(()); + } +} + +/// Builder for constructing an instance of this type. +pub struct LinkBuilder { + _state: PhantomData St>, + _fields: (Option>,), + _type: PhantomData S>, +} + +impl Link { + /// Create a new builder for this type. + pub fn new() -> LinkBuilder { + LinkBuilder::new() + } +} + +impl LinkBuilder { + /// Create a new builder with all fields unset. + pub fn new() -> Self { + LinkBuilder { + _state: PhantomData, + _fields: (None,), + _type: PhantomData, + } + } +} + +impl LinkBuilder +where + St: link_state::State, + St::Uri: link_state::IsUnset, +{ + /// Set the `uri` field (required) + pub fn uri( + mut self, + value: impl Into>, + ) -> LinkBuilder> { + self._fields.0 = Option::Some(value.into()); + LinkBuilder { + _state: PhantomData, + _fields: self._fields, + _type: PhantomData, + } + } +} + +impl LinkBuilder +where + St: link_state::State, + St::Uri: link_state::IsSet, +{ + /// Build the final struct. + pub fn build(self) -> Link { + Link { + uri: self._fields.0.unwrap(), + extra_data: Default::default(), + } + } + /// Build the final struct with custom extra_data. + pub fn build_with_data(self, extra_data: BTreeMap>) -> Link { + Link { + uri: self._fields.0.unwrap(), + extra_data: Some(extra_data), + } + } +} + +pub mod facet_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 Index; + type Features; + } + /// Empty state - all required fields are unset + pub struct Empty(()); + impl sealed::Sealed for Empty {} + impl State for Empty { + type Index = Unset; + type Features = Unset; + } + ///State transition - sets the `index` field to Set + pub struct SetIndex(PhantomData St>); + impl sealed::Sealed for SetIndex {} + impl State for SetIndex { + type Index = Set; + type Features = St::Features; + } + ///State transition - sets the `features` field to Set + pub struct SetFeatures(PhantomData St>); + impl sealed::Sealed for SetFeatures {} + impl State for SetFeatures { + type Index = St::Index; + type Features = Set; + } + /// Marker types for field names + #[allow(non_camel_case_types)] + pub mod members { + ///Marker type for the `index` field + pub struct index(()); + ///Marker type for the `features` field + pub struct features(()); + } +} + +/// Builder for constructing an instance of this type. +pub struct FacetBuilder { + _state: PhantomData St>, + _fields: (Option>>, Option>), + _type: PhantomData S>, +} + +impl Facet { + /// Create a new builder for this type. + pub fn new() -> FacetBuilder { + FacetBuilder::new() + } +} + +impl FacetBuilder { + /// Create a new builder with all fields unset. + pub fn new() -> Self { + FacetBuilder { + _state: PhantomData, + _fields: (None, None), + _type: PhantomData, + } + } +} + +impl FacetBuilder +where + St: facet_state::State, + St::Features: facet_state::IsUnset, +{ + /// Set the `features` field (required) + pub fn features( + mut self, + value: impl Into>>, + ) -> FacetBuilder> { + self._fields.0 = Option::Some(value.into()); + FacetBuilder { + _state: PhantomData, + _fields: self._fields, + _type: PhantomData, + } + } +} + +impl FacetBuilder +where + St: facet_state::State, + St::Index: facet_state::IsUnset, +{ + /// Set the `index` field (required) + pub fn index( + mut self, + value: impl Into>, + ) -> FacetBuilder> { + self._fields.1 = Option::Some(value.into()); + FacetBuilder { + _state: PhantomData, + _fields: self._fields, + _type: PhantomData, + } + } +} + +impl FacetBuilder +where + St: facet_state::State, + St::Index: facet_state::IsSet, + St::Features: facet_state::IsSet, +{ + /// Build the final struct. + pub fn build(self) -> Facet { + Facet { + features: self._fields.0.unwrap(), + index: self._fields.1.unwrap(), + extra_data: Default::default(), + } + } + /// Build the final struct with custom extra_data. + pub fn build_with_data(self, extra_data: BTreeMap>) -> Facet { + Facet { + features: self._fields.0.unwrap(), + index: self._fields.1.unwrap(), + extra_data: Some(extra_data), + } + } +} + +pub mod mention_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 Did; + } + /// Empty state - all required fields are unset + pub struct Empty(()); + impl sealed::Sealed for Empty {} + impl State for Empty { + type Did = Unset; + } + ///State transition - sets the `did` field to Set + pub struct SetDid(PhantomData St>); + impl sealed::Sealed for SetDid {} + impl State for SetDid { + type Did = Set; + } + /// Marker types for field names + #[allow(non_camel_case_types)] + pub mod members { + ///Marker type for the `did` field + pub struct did(()); + } +} + +/// Builder for constructing an instance of this type. +pub struct MentionBuilder { + _state: PhantomData St>, + _fields: (Option>,), + _type: PhantomData S>, +} + +impl Mention { + /// Create a new builder for this type. + pub fn new() -> MentionBuilder { + MentionBuilder::new() + } +} + +impl MentionBuilder { + /// Create a new builder with all fields unset. + pub fn new() -> Self { + MentionBuilder { + _state: PhantomData, + _fields: (None,), + _type: PhantomData, + } + } +} + +impl MentionBuilder +where + St: mention_state::State, + St::Did: mention_state::IsUnset, +{ + /// Set the `did` field (required) + pub fn did( + mut self, + value: impl Into>, + ) -> MentionBuilder> { + self._fields.0 = Option::Some(value.into()); + MentionBuilder { + _state: PhantomData, + _fields: self._fields, + _type: PhantomData, + } + } +} + +impl MentionBuilder +where + St: mention_state::State, + St::Did: mention_state::IsSet, +{ + /// Build the final struct. + pub fn build(self) -> Mention { + Mention { + did: self._fields.0.unwrap(), + extra_data: Default::default(), + } + } + /// Build the final struct with custom extra_data. + pub fn build_with_data(self, extra_data: BTreeMap>) -> Mention { + Mention { + did: self._fields.0.unwrap(), + extra_data: Some(extra_data), + } + } +} \ No newline at end of file diff --git a/crates/jacquard-codegen-tests/src/generated/pretty/builder_types.rs b/crates/jacquard-codegen-tests/src/generated/pretty/builder_types.rs new file mode 100644 index 00000000..cd45c2e4 --- /dev/null +++ b/crates/jacquard-codegen-tests/src/generated/pretty/builder_types.rs @@ -0,0 +1,45 @@ +// @generated by jacquard-lexicon. DO NOT EDIT. +// +// This file was automatically generated from Lexicon schemas. +// Any manual changes will be overwritten on the next regeneration. + +/// Marker type indicating a builder field has been set +pub struct Set(pub T); +impl Set { + /// Extract the inner value + #[inline] + pub fn into_inner(self) -> T { + self.0 + } +} + +/// Marker type indicating a builder field has not been set +pub struct Unset; +/// Trait indicating a builder field is set (has a value) + +#[jacquard_common::deps::codegen::rustversion::attr( + since(1.78.0), + diagnostic::on_unimplemented( + message = "the field `{Self}` was not set, but this method requires it to be set", + label = "the field `{Self}` was not set" + ) +)] +pub trait IsSet: private::Sealed {} +/// Trait indicating a builder field is unset (no value yet) + +#[jacquard_common::deps::codegen::rustversion::attr( + since(1.78.0), + diagnostic::on_unimplemented( + message = "the field `{Self}` was already set, but this method requires it to be unset", + label = "the field `{Self}` was already set" + ) +)] +pub trait IsUnset: private::Sealed {} +impl IsSet for Set {} +impl IsUnset for Unset {} +mod private { + /// Sealed trait to prevent external implementations + pub trait Sealed {} + impl Sealed for super::Set {} + impl Sealed for super::Unset {} +} \ No newline at end of file diff --git a/crates/jacquard-codegen-tests/src/generated/pretty/com_atproto.rs b/crates/jacquard-codegen-tests/src/generated/pretty/com_atproto.rs new file mode 100644 index 00000000..09e30369 --- /dev/null +++ b/crates/jacquard-codegen-tests/src/generated/pretty/com_atproto.rs @@ -0,0 +1,7 @@ +// @generated by jacquard-lexicon. DO NOT EDIT. +// +// This file was automatically generated from Lexicon schemas. +// Any manual changes will be overwritten on the next regeneration. + +pub mod label; +pub mod repo; \ No newline at end of file diff --git a/crates/jacquard-codegen-tests/src/generated/pretty/com_atproto/label.rs b/crates/jacquard-codegen-tests/src/generated/pretty/com_atproto/label.rs new file mode 100644 index 00000000..852614ef --- /dev/null +++ b/crates/jacquard-codegen-tests/src/generated/pretty/com_atproto/label.rs @@ -0,0 +1,1838 @@ +// @generated by jacquard-lexicon. DO NOT EDIT. +// +// Lexicon: com.atproto.label.defs +// +// This file was automatically generated from Lexicon schemas. +// Any manual changes will be overwritten on the next regeneration. + +#[allow(unused_imports)] +use alloc::collections::BTreeMap; + +#[allow(unused_imports)] +use core::marker::PhantomData; +use jacquard_common::{CowStr, BosStr, DefaultStr, FromStaticStr}; +use jacquard_common::deps::bytes::Bytes; + +#[allow(unused_imports)] +use jacquard_common::deps::codegen::unicode_segmentation::UnicodeSegmentation; +use jacquard_common::deps::smol_str::SmolStr; +use jacquard_common::types::string::{Did, Cid, Datetime, Language, UriValue}; +use jacquard_common::types::value::Data; +use jacquard_derive::IntoStatic; +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::pretty::com_atproto::label; +/// Metadata tag on an atproto resource (eg, repo or record). + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)] +#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))] +pub struct Label { + ///Optionally, CID specifying the specific version of 'uri' resource this label applies to. + #[serde(skip_serializing_if = "Option::is_none")] + pub cid: Option>, + ///Timestamp when this label was created. + pub cts: Datetime, + ///Timestamp at which this label expires (no longer applies). + #[serde(skip_serializing_if = "Option::is_none")] + pub exp: Option, + ///If true, this is a negation label, overwriting a previous label. + #[serde(skip_serializing_if = "Option::is_none")] + pub neg: Option, + ///Signature of dag-cbor encoded label. + #[serde(skip_serializing_if = "Option::is_none")] + #[serde(default, with = "jacquard_common::opt_serde_bytes_helper")] + pub sig: Option, + ///DID of the actor who created this label. + pub src: Did, + ///AT URI of the record, repository (account), or other resource that this label applies to. + pub uri: UriValue, + ///The short string name of the value or type of this label. + pub val: S, + ///The AT Protocol version of the label object. + #[serde(skip_serializing_if = "Option::is_none")] + pub ver: Option, + #[serde(flatten, default, skip_serializing_if = "Option::is_none")] + pub extra_data: Option>>, +} + + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum LabelValue { + Hide, + NoPromote, + Warn, + NoUnauthenticated, + DmcaViolation, + Doxxing, + Porn, + Sexual, + Nudity, + Nsfl, + Gore, + Other(S), +} + +impl LabelValue { + pub fn as_str(&self) -> &str { + match self { + Self::Hide => "!hide", + Self::NoPromote => "!no-promote", + Self::Warn => "!warn", + Self::NoUnauthenticated => "!no-unauthenticated", + Self::DmcaViolation => "dmca-violation", + Self::Doxxing => "doxxing", + Self::Porn => "porn", + Self::Sexual => "sexual", + Self::Nudity => "nudity", + Self::Nsfl => "nsfl", + Self::Gore => "gore", + 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() { + "!hide" => Self::Hide, + "!no-promote" => Self::NoPromote, + "!warn" => Self::Warn, + "!no-unauthenticated" => Self::NoUnauthenticated, + "dmca-violation" => Self::DmcaViolation, + "doxxing" => Self::Doxxing, + "porn" => Self::Porn, + "sexual" => Self::Sexual, + "nudity" => Self::Nudity, + "nsfl" => Self::Nsfl, + "gore" => Self::Gore, + _ => Self::Other(s), + } + } +} + +impl AsRef for LabelValue { + fn as_ref(&self) -> &str { + self.as_str() + } +} + +impl core::fmt::Display for LabelValue { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, "{}", self.as_str()) + } +} + +impl Serialize for LabelValue { + fn serialize(&self, serializer: Ser) -> Result + where + Ser: serde::Serializer, + { + serializer.serialize_str(self.as_str()) + } +} + +impl<'de, S: Deserialize<'de> + BosStr> Deserialize<'de> for LabelValue { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let s = S::deserialize(deserializer)?; + Ok(Self::from_value(s)) + } +} + +impl jacquard_common::IntoStatic for LabelValue +where + S: BosStr + jacquard_common::IntoStatic, + S::Output: BosStr, +{ + type Output = LabelValue; + fn into_static(self) -> Self::Output { + match self { + LabelValue::Hide => LabelValue::Hide, + LabelValue::NoPromote => LabelValue::NoPromote, + LabelValue::Warn => LabelValue::Warn, + LabelValue::NoUnauthenticated => LabelValue::NoUnauthenticated, + LabelValue::DmcaViolation => LabelValue::DmcaViolation, + LabelValue::Doxxing => LabelValue::Doxxing, + LabelValue::Porn => LabelValue::Porn, + LabelValue::Sexual => LabelValue::Sexual, + LabelValue::Nudity => LabelValue::Nudity, + LabelValue::Nsfl => LabelValue::Nsfl, + LabelValue::Gore => LabelValue::Gore, + LabelValue::Other(v) => LabelValue::Other(v.into_static()), + } + } +} + +/// Declares a label value and its expected interpretations and behaviors. + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)] +#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))] +pub struct LabelValueDefinition { + ///Does the user need to have adult content enabled in order to configure this label? + #[serde(skip_serializing_if = "Option::is_none")] + pub adult_only: Option, + ///What should this label hide in the UI, if applied? 'content' hides all of the target; 'media' hides the images/video/audio; 'none' hides nothing. + pub blurs: LabelValueDefinitionBlurs, + ///The default setting for this label. + #[serde(skip_serializing_if = "Option::is_none")] + pub default_setting: Option>, + ///The value of the label being defined. Must only include lowercase ascii and the '-' character ([a-z-]+). + pub identifier: S, + pub locales: Vec>, + ///How should a client visually convey this label? 'inform' means neutral and informational; 'alert' means negative and warning; 'none' means show nothing. + pub severity: LabelValueDefinitionSeverity, + #[serde(flatten, default, skip_serializing_if = "Option::is_none")] + pub extra_data: Option>>, +} + +/// What should this label hide in the UI, if applied? 'content' hides all of the target; 'media' hides the images/video/audio; 'none' hides nothing. + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum LabelValueDefinitionBlurs { + Content, + Media, + None, + Other(S), +} + +impl LabelValueDefinitionBlurs { + pub fn as_str(&self) -> &str { + match self { + Self::Content => "content", + Self::Media => "media", + Self::None => "none", + 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() { + "content" => Self::Content, + "media" => Self::Media, + "none" => Self::None, + _ => Self::Other(s), + } + } +} + +impl core::fmt::Display for LabelValueDefinitionBlurs { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, "{}", self.as_str()) + } +} + +impl AsRef for LabelValueDefinitionBlurs { + fn as_ref(&self) -> &str { + self.as_str() + } +} + +impl Serialize for LabelValueDefinitionBlurs { + fn serialize(&self, serializer: Ser) -> Result + where + Ser: serde::Serializer, + { + serializer.serialize_str(self.as_str()) + } +} + +impl<'de, S: Deserialize<'de> + BosStr> Deserialize<'de> +for LabelValueDefinitionBlurs { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let s = S::deserialize(deserializer)?; + Ok(Self::from_value(s)) + } +} + +impl Default for LabelValueDefinitionBlurs { + fn default() -> Self { + Self::Other(Default::default()) + } +} + +impl jacquard_common::IntoStatic for LabelValueDefinitionBlurs +where + S: BosStr + jacquard_common::IntoStatic, + S::Output: BosStr, +{ + type Output = LabelValueDefinitionBlurs; + fn into_static(self) -> Self::Output { + match self { + LabelValueDefinitionBlurs::Content => LabelValueDefinitionBlurs::Content, + LabelValueDefinitionBlurs::Media => LabelValueDefinitionBlurs::Media, + LabelValueDefinitionBlurs::None => LabelValueDefinitionBlurs::None, + LabelValueDefinitionBlurs::Other(v) => { + LabelValueDefinitionBlurs::Other(v.into_static()) + } + } + } +} + +/// The default setting for this label. + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum LabelValueDefinitionDefaultSetting { + Ignore, + Warn, + Hide, + Other(S), +} + +impl LabelValueDefinitionDefaultSetting { + pub fn as_str(&self) -> &str { + match self { + Self::Ignore => "ignore", + Self::Warn => "warn", + Self::Hide => "hide", + 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() { + "ignore" => Self::Ignore, + "warn" => Self::Warn, + "hide" => Self::Hide, + _ => Self::Other(s), + } + } +} + +impl core::fmt::Display for LabelValueDefinitionDefaultSetting { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, "{}", self.as_str()) + } +} + +impl AsRef for LabelValueDefinitionDefaultSetting { + fn as_ref(&self) -> &str { + self.as_str() + } +} + +impl Serialize for LabelValueDefinitionDefaultSetting { + fn serialize(&self, serializer: Ser) -> Result + where + Ser: serde::Serializer, + { + serializer.serialize_str(self.as_str()) + } +} + +impl<'de, S: Deserialize<'de> + BosStr> Deserialize<'de> +for LabelValueDefinitionDefaultSetting { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let s = S::deserialize(deserializer)?; + Ok(Self::from_value(s)) + } +} + +impl Default for LabelValueDefinitionDefaultSetting { + fn default() -> Self { + Self::Other(Default::default()) + } +} + +impl jacquard_common::IntoStatic for LabelValueDefinitionDefaultSetting +where + S: BosStr + jacquard_common::IntoStatic, + S::Output: BosStr, +{ + type Output = LabelValueDefinitionDefaultSetting; + fn into_static(self) -> Self::Output { + match self { + LabelValueDefinitionDefaultSetting::Ignore => { + LabelValueDefinitionDefaultSetting::Ignore + } + LabelValueDefinitionDefaultSetting::Warn => { + LabelValueDefinitionDefaultSetting::Warn + } + LabelValueDefinitionDefaultSetting::Hide => { + LabelValueDefinitionDefaultSetting::Hide + } + LabelValueDefinitionDefaultSetting::Other(v) => { + LabelValueDefinitionDefaultSetting::Other(v.into_static()) + } + } + } +} + +/// How should a client visually convey this label? 'inform' means neutral and informational; 'alert' means negative and warning; 'none' means show nothing. + +#[derive(Debug, Clone, PartialEq, Eq, Hash)] +pub enum LabelValueDefinitionSeverity { + Inform, + Alert, + None, + Other(S), +} + +impl LabelValueDefinitionSeverity { + pub fn as_str(&self) -> &str { + match self { + Self::Inform => "inform", + Self::Alert => "alert", + Self::None => "none", + 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() { + "inform" => Self::Inform, + "alert" => Self::Alert, + "none" => Self::None, + _ => Self::Other(s), + } + } +} + +impl core::fmt::Display for LabelValueDefinitionSeverity { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, "{}", self.as_str()) + } +} + +impl AsRef for LabelValueDefinitionSeverity { + fn as_ref(&self) -> &str { + self.as_str() + } +} + +impl Serialize for LabelValueDefinitionSeverity { + fn serialize(&self, serializer: Ser) -> Result + where + Ser: serde::Serializer, + { + serializer.serialize_str(self.as_str()) + } +} + +impl<'de, S: Deserialize<'de> + BosStr> Deserialize<'de> +for LabelValueDefinitionSeverity { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + let s = S::deserialize(deserializer)?; + Ok(Self::from_value(s)) + } +} + +impl Default for LabelValueDefinitionSeverity { + fn default() -> Self { + Self::Other(Default::default()) + } +} + +impl jacquard_common::IntoStatic for LabelValueDefinitionSeverity +where + S: BosStr + jacquard_common::IntoStatic, + S::Output: BosStr, +{ + type Output = LabelValueDefinitionSeverity; + fn into_static(self) -> Self::Output { + match self { + LabelValueDefinitionSeverity::Inform => LabelValueDefinitionSeverity::Inform, + LabelValueDefinitionSeverity::Alert => LabelValueDefinitionSeverity::Alert, + LabelValueDefinitionSeverity::None => LabelValueDefinitionSeverity::None, + LabelValueDefinitionSeverity::Other(v) => { + LabelValueDefinitionSeverity::Other(v.into_static()) + } + } + } +} + +/// Strings which describe the label in the UI, localized into a specific language. + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)] +#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))] +pub struct LabelValueDefinitionStrings { + ///A longer description of what the label means and why it might be applied. + pub description: S, + ///The code of the language these strings are written in. + pub lang: Language, + ///A short human-readable name for the label. + pub name: S, + #[serde(flatten, default, skip_serializing_if = "Option::is_none")] + pub extra_data: Option>>, +} + +/// Metadata tag on an atproto record, published by the author within the record. Note that schemas should use #selfLabels, not #selfLabel. + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic, Default)] +#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))] +pub struct SelfLabel { + ///The short string name of the value or type of this label. + pub val: S, + #[serde(flatten, default, skip_serializing_if = "Option::is_none")] + pub extra_data: Option>>, +} + +/// Metadata tags on an atproto record, published by the author within the record. + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)] +#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))] +pub struct SelfLabels { + pub values: Vec>, + #[serde(flatten, default, skip_serializing_if = "Option::is_none")] + pub extra_data: Option>>, +} + +impl LexiconSchema for Label { + fn nsid() -> &'static str { + "com.atproto.label.defs" + } + fn def_name() -> &'static str { + "label" + } + fn lexicon_doc() -> LexiconDoc<'static> { + lexicon_doc_com_atproto_label_defs() + } + fn validate(&self) -> Result<(), ConstraintError> { + { + let value = &self.val; + #[allow(unused_comparisons)] + if ::len(value.as_ref()) > 128usize { + return Err(ConstraintError::MaxLength { + path: ValidationPath::from_field("val"), + max: 128usize, + actual: ::len(value.as_ref()), + }); + } + } + Ok(()) + } +} + +impl LexiconSchema for LabelValueDefinition { + fn nsid() -> &'static str { + "com.atproto.label.defs" + } + fn def_name() -> &'static str { + "labelValueDefinition" + } + fn lexicon_doc() -> LexiconDoc<'static> { + lexicon_doc_com_atproto_label_defs() + } + fn validate(&self) -> Result<(), ConstraintError> { + { + let value = &self.identifier; + #[allow(unused_comparisons)] + if ::len(value.as_ref()) > 100usize { + return Err(ConstraintError::MaxLength { + path: ValidationPath::from_field("identifier"), + max: 100usize, + actual: ::len(value.as_ref()), + }); + } + } + { + let value = &self.identifier; + { + let count = UnicodeSegmentation::graphemes(value.as_ref(), true).count(); + if count > 100usize { + return Err(ConstraintError::MaxGraphemes { + path: ValidationPath::from_field("identifier"), + max: 100usize, + actual: count, + }); + } + } + } + Ok(()) + } +} + +impl LexiconSchema for LabelValueDefinitionStrings { + fn nsid() -> &'static str { + "com.atproto.label.defs" + } + fn def_name() -> &'static str { + "labelValueDefinitionStrings" + } + fn lexicon_doc() -> LexiconDoc<'static> { + lexicon_doc_com_atproto_label_defs() + } + fn validate(&self) -> Result<(), ConstraintError> { + { + let value = &self.description; + #[allow(unused_comparisons)] + if ::len(value.as_ref()) > 100000usize { + return Err(ConstraintError::MaxLength { + path: ValidationPath::from_field("description"), + max: 100000usize, + actual: ::len(value.as_ref()), + }); + } + } + { + let value = &self.description; + { + let count = UnicodeSegmentation::graphemes(value.as_ref(), true).count(); + if count > 10000usize { + return Err(ConstraintError::MaxGraphemes { + path: ValidationPath::from_field("description"), + max: 10000usize, + actual: count, + }); + } + } + } + { + let value = &self.name; + #[allow(unused_comparisons)] + if ::len(value.as_ref()) > 640usize { + return Err(ConstraintError::MaxLength { + path: ValidationPath::from_field("name"), + max: 640usize, + actual: ::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(()) + } +} + +impl LexiconSchema for SelfLabel { + fn nsid() -> &'static str { + "com.atproto.label.defs" + } + fn def_name() -> &'static str { + "selfLabel" + } + fn lexicon_doc() -> LexiconDoc<'static> { + lexicon_doc_com_atproto_label_defs() + } + fn validate(&self) -> Result<(), ConstraintError> { + { + let value = &self.val; + #[allow(unused_comparisons)] + if ::len(value.as_ref()) > 128usize { + return Err(ConstraintError::MaxLength { + path: ValidationPath::from_field("val"), + max: 128usize, + actual: ::len(value.as_ref()), + }); + } + } + Ok(()) + } +} + +impl LexiconSchema for SelfLabels { + fn nsid() -> &'static str { + "com.atproto.label.defs" + } + fn def_name() -> &'static str { + "selfLabels" + } + fn lexicon_doc() -> LexiconDoc<'static> { + lexicon_doc_com_atproto_label_defs() + } + fn validate(&self) -> Result<(), ConstraintError> { + { + let value = &self.values; + #[allow(unused_comparisons)] + if value.len() > 10usize { + return Err(ConstraintError::MaxLength { + path: ValidationPath::from_field("values"), + max: 10usize, + actual: value.len(), + }); + } + } + Ok(()) + } +} + +pub mod label_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 Src; + type Cts; + type Uri; + type Val; + } + /// Empty state - all required fields are unset + pub struct Empty(()); + impl sealed::Sealed for Empty {} + impl State for Empty { + type Src = Unset; + type Cts = Unset; + type Uri = Unset; + type Val = Unset; + } + ///State transition - sets the `src` field to Set + pub struct SetSrc(PhantomData St>); + impl sealed::Sealed for SetSrc {} + impl State for SetSrc { + type Src = Set; + type Cts = St::Cts; + type Uri = St::Uri; + type Val = St::Val; + } + ///State transition - sets the `cts` field to Set + pub struct SetCts(PhantomData St>); + impl sealed::Sealed for SetCts {} + impl State for SetCts { + type Src = St::Src; + type Cts = Set; + type Uri = St::Uri; + type Val = St::Val; + } + ///State transition - sets the `uri` field to Set + pub struct SetUri(PhantomData St>); + impl sealed::Sealed for SetUri {} + impl State for SetUri { + type Src = St::Src; + type Cts = St::Cts; + type Uri = Set; + type Val = St::Val; + } + ///State transition - sets the `val` field to Set + pub struct SetVal(PhantomData St>); + impl sealed::Sealed for SetVal {} + impl State for SetVal { + type Src = St::Src; + type Cts = St::Cts; + type Uri = St::Uri; + type Val = Set; + } + /// Marker types for field names + #[allow(non_camel_case_types)] + pub mod members { + ///Marker type for the `src` field + pub struct src(()); + ///Marker type for the `cts` field + pub struct cts(()); + ///Marker type for the `uri` field + pub struct uri(()); + ///Marker type for the `val` field + pub struct val(()); + } +} + +/// Builder for constructing an instance of this type. +pub struct LabelBuilder { + _state: PhantomData St>, + _fields: ( + Option>, + Option, + Option, + Option, + Option, + Option>, + Option>, + Option, + Option, + ), + _type: PhantomData S>, +} + +impl Label { + /// Create a new builder for this type. + pub fn new() -> LabelBuilder { + LabelBuilder::new() + } +} + +impl LabelBuilder { + /// Create a new builder with all fields unset. + pub fn new() -> Self { + LabelBuilder { + _state: PhantomData, + _fields: (None, None, None, None, None, None, None, None, None), + _type: PhantomData, + } + } +} + +impl LabelBuilder { + /// Set the `cid` field (optional) + pub fn cid(mut self, value: impl Into>>) -> Self { + self._fields.0 = value.into(); + self + } + /// Set the `cid` field to an Option value (optional) + pub fn maybe_cid(mut self, value: Option>) -> Self { + self._fields.0 = value; + self + } +} + +impl LabelBuilder +where + St: label_state::State, + St::Cts: label_state::IsUnset, +{ + /// Set the `cts` field (required) + pub fn cts( + mut self, + value: impl Into, + ) -> LabelBuilder> { + self._fields.1 = Option::Some(value.into()); + LabelBuilder { + _state: PhantomData, + _fields: self._fields, + _type: PhantomData, + } + } +} + +impl LabelBuilder { + /// Set the `exp` field (optional) + pub fn exp(mut self, value: impl Into>) -> Self { + self._fields.2 = value.into(); + self + } + /// Set the `exp` field to an Option value (optional) + pub fn maybe_exp(mut self, value: Option) -> Self { + self._fields.2 = value; + self + } +} + +impl LabelBuilder { + /// Set the `neg` field (optional) + pub fn neg(mut self, value: impl Into>) -> Self { + self._fields.3 = value.into(); + self + } + /// Set the `neg` field to an Option value (optional) + pub fn maybe_neg(mut self, value: Option) -> Self { + self._fields.3 = value; + self + } +} + +impl LabelBuilder { + /// Set the `sig` field (optional) + pub fn sig(mut self, value: impl Into>) -> Self { + self._fields.4 = value.into(); + self + } + /// Set the `sig` field to an Option value (optional) + pub fn maybe_sig(mut self, value: Option) -> Self { + self._fields.4 = value; + self + } +} + +impl LabelBuilder +where + St: label_state::State, + St::Src: label_state::IsUnset, +{ + /// Set the `src` field (required) + pub fn src( + mut self, + value: impl Into>, + ) -> LabelBuilder> { + self._fields.5 = Option::Some(value.into()); + LabelBuilder { + _state: PhantomData, + _fields: self._fields, + _type: PhantomData, + } + } +} + +impl LabelBuilder +where + St: label_state::State, + St::Uri: label_state::IsUnset, +{ + /// Set the `uri` field (required) + pub fn uri( + mut self, + value: impl Into>, + ) -> LabelBuilder> { + self._fields.6 = Option::Some(value.into()); + LabelBuilder { + _state: PhantomData, + _fields: self._fields, + _type: PhantomData, + } + } +} + +impl LabelBuilder +where + St: label_state::State, + St::Val: label_state::IsUnset, +{ + /// Set the `val` field (required) + pub fn val( + mut self, + value: impl Into, + ) -> LabelBuilder> { + self._fields.7 = Option::Some(value.into()); + LabelBuilder { + _state: PhantomData, + _fields: self._fields, + _type: PhantomData, + } + } +} + +impl LabelBuilder { + /// Set the `ver` field (optional) + pub fn ver(mut self, value: impl Into>) -> Self { + self._fields.8 = value.into(); + self + } + /// Set the `ver` field to an Option value (optional) + pub fn maybe_ver(mut self, value: Option) -> Self { + self._fields.8 = value; + self + } +} + +impl LabelBuilder +where + St: label_state::State, + St::Src: label_state::IsSet, + St::Cts: label_state::IsSet, + St::Uri: label_state::IsSet, + St::Val: label_state::IsSet, +{ + /// Build the final struct. + pub fn build(self) -> Label { + Label { + cid: self._fields.0, + cts: self._fields.1.unwrap(), + exp: self._fields.2, + neg: self._fields.3, + sig: self._fields.4, + src: self._fields.5.unwrap(), + uri: self._fields.6.unwrap(), + val: self._fields.7.unwrap(), + ver: self._fields.8, + extra_data: Default::default(), + } + } + /// Build the final struct with custom extra_data. + pub fn build_with_data(self, extra_data: BTreeMap>) -> Label { + Label { + cid: self._fields.0, + cts: self._fields.1.unwrap(), + exp: self._fields.2, + neg: self._fields.3, + sig: self._fields.4, + src: self._fields.5.unwrap(), + uri: self._fields.6.unwrap(), + val: self._fields.7.unwrap(), + ver: self._fields.8, + extra_data: Some(extra_data), + } + } +} + +fn lexicon_doc_com_atproto_label_defs() -> LexiconDoc<'static> { + #[allow(unused_imports)] + use jacquard_common::{CowStr, deps::smol_str::SmolStr, types::blob::MimeType}; + use jacquard_lexicon::lexicon::*; + use alloc::collections::BTreeMap; + LexiconDoc { + lexicon: Lexicon::Lexicon1, + id: CowStr::new_static("com.atproto.label.defs"), + defs: { + let mut map = BTreeMap::new(); + map.insert( + SmolStr::new_static("label"), + LexUserType::Object(LexObject { + description: Some( + CowStr::new_static( + "Metadata tag on an atproto resource (eg, repo or record).", + ), + ), + required: Some( + vec![ + SmolStr::new_static("src"), SmolStr::new_static("uri"), + SmolStr::new_static("val"), SmolStr::new_static("cts") + ], + ), + properties: { + #[allow(unused_mut)] + let mut map = BTreeMap::new(); + map.insert( + SmolStr::new_static("cid"), + LexObjectProperty::String(LexString { + description: Some( + CowStr::new_static( + "Optionally, CID specifying the specific version of 'uri' resource this label applies to.", + ), + ), + format: Some(LexStringFormat::Cid), + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("cts"), + LexObjectProperty::String(LexString { + description: Some( + CowStr::new_static("Timestamp when this label was created."), + ), + format: Some(LexStringFormat::Datetime), + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("exp"), + LexObjectProperty::String(LexString { + description: Some( + CowStr::new_static( + "Timestamp at which this label expires (no longer applies).", + ), + ), + format: Some(LexStringFormat::Datetime), + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("neg"), + LexObjectProperty::Boolean(LexBoolean { + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("sig"), + LexObjectProperty::Bytes(LexBytes { ..Default::default() }), + ); + map.insert( + SmolStr::new_static("src"), + LexObjectProperty::String(LexString { + description: Some( + CowStr::new_static( + "DID of the actor who created this label.", + ), + ), + format: Some(LexStringFormat::Did), + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("uri"), + LexObjectProperty::String(LexString { + description: Some( + CowStr::new_static( + "AT URI of the record, repository (account), or other resource that this label applies to.", + ), + ), + format: Some(LexStringFormat::Uri), + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("val"), + LexObjectProperty::String(LexString { + description: Some( + CowStr::new_static( + "The short string name of the value or type of this label.", + ), + ), + max_length: Some(128usize), + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("ver"), + LexObjectProperty::Integer(LexInteger { + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("labelValue"), + LexUserType::String(LexString { ..Default::default() }), + ); + map.insert( + SmolStr::new_static("labelValueDefinition"), + LexUserType::Object(LexObject { + description: Some( + CowStr::new_static( + "Declares a label value and its expected interpretations and behaviors.", + ), + ), + required: Some( + vec![ + SmolStr::new_static("identifier"), + SmolStr::new_static("severity"), + SmolStr::new_static("blurs"), SmolStr::new_static("locales") + ], + ), + properties: { + #[allow(unused_mut)] + let mut map = BTreeMap::new(); + map.insert( + SmolStr::new_static("adultOnly"), + LexObjectProperty::Boolean(LexBoolean { + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("blurs"), + LexObjectProperty::String(LexString { + description: Some( + CowStr::new_static( + "What should this label hide in the UI, if applied? 'content' hides all of the target; 'media' hides the images/video/audio; 'none' hides nothing.", + ), + ), + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("defaultSetting"), + LexObjectProperty::String(LexString { + description: Some( + CowStr::new_static("The default setting for this label."), + ), + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("identifier"), + LexObjectProperty::String(LexString { + description: Some( + CowStr::new_static( + "The value of the label being defined. Must only include lowercase ascii and the '-' character ([a-z-]+).", + ), + ), + max_length: Some(100usize), + max_graphemes: Some(100usize), + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("locales"), + LexObjectProperty::Array(LexArray { + items: LexArrayItem::Ref(LexRef { + r#ref: CowStr::new_static("#labelValueDefinitionStrings"), + ..Default::default() + }), + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("severity"), + LexObjectProperty::String(LexString { + description: Some( + CowStr::new_static( + "How should a client visually convey this label? 'inform' means neutral and informational; 'alert' means negative and warning; 'none' means show nothing.", + ), + ), + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("labelValueDefinitionStrings"), + LexUserType::Object(LexObject { + description: Some( + CowStr::new_static( + "Strings which describe the label in the UI, localized into a specific language.", + ), + ), + required: Some( + vec![ + SmolStr::new_static("lang"), SmolStr::new_static("name"), + SmolStr::new_static("description") + ], + ), + properties: { + #[allow(unused_mut)] + let mut map = BTreeMap::new(); + map.insert( + SmolStr::new_static("description"), + LexObjectProperty::String(LexString { + description: Some( + CowStr::new_static( + "A longer description of what the label means and why it might be applied.", + ), + ), + max_length: Some(100000usize), + max_graphemes: Some(10000usize), + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("lang"), + LexObjectProperty::String(LexString { + description: Some( + CowStr::new_static( + "The code of the language these strings are written in.", + ), + ), + format: Some(LexStringFormat::Language), + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("name"), + LexObjectProperty::String(LexString { + description: Some( + CowStr::new_static( + "A short human-readable name for the label.", + ), + ), + max_length: Some(640usize), + max_graphemes: Some(64usize), + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("selfLabel"), + LexUserType::Object(LexObject { + description: Some( + CowStr::new_static( + "Metadata tag on an atproto record, published by the author within the record. Note that schemas should use #selfLabels, not #selfLabel.", + ), + ), + required: Some(vec![SmolStr::new_static("val")]), + properties: { + #[allow(unused_mut)] + let mut map = BTreeMap::new(); + map.insert( + SmolStr::new_static("val"), + LexObjectProperty::String(LexString { + description: Some( + CowStr::new_static( + "The short string name of the value or type of this label.", + ), + ), + max_length: Some(128usize), + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("selfLabels"), + LexUserType::Object(LexObject { + description: Some( + CowStr::new_static( + "Metadata tags on an atproto record, published by the author within the record.", + ), + ), + required: Some(vec![SmolStr::new_static("values")]), + properties: { + #[allow(unused_mut)] + let mut map = BTreeMap::new(); + map.insert( + SmolStr::new_static("values"), + LexObjectProperty::Array(LexArray { + items: LexArrayItem::Ref(LexRef { + r#ref: CowStr::new_static("#selfLabel"), + ..Default::default() + }), + max_length: Some(10usize), + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map + }, + ..Default::default() + } +} + +pub mod label_value_definition_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 Identifier; + type Locales; + type Severity; + type Blurs; + } + /// Empty state - all required fields are unset + pub struct Empty(()); + impl sealed::Sealed for Empty {} + impl State for Empty { + type Identifier = Unset; + type Locales = Unset; + type Severity = Unset; + type Blurs = Unset; + } + ///State transition - sets the `identifier` field to Set + pub struct SetIdentifier(PhantomData St>); + impl sealed::Sealed for SetIdentifier {} + impl State for SetIdentifier { + type Identifier = Set; + type Locales = St::Locales; + type Severity = St::Severity; + type Blurs = St::Blurs; + } + ///State transition - sets the `locales` field to Set + pub struct SetLocales(PhantomData St>); + impl sealed::Sealed for SetLocales {} + impl State for SetLocales { + type Identifier = St::Identifier; + type Locales = Set; + type Severity = St::Severity; + type Blurs = St::Blurs; + } + ///State transition - sets the `severity` field to Set + pub struct SetSeverity(PhantomData St>); + impl sealed::Sealed for SetSeverity {} + impl State for SetSeverity { + type Identifier = St::Identifier; + type Locales = St::Locales; + type Severity = Set; + type Blurs = St::Blurs; + } + ///State transition - sets the `blurs` field to Set + pub struct SetBlurs(PhantomData St>); + impl sealed::Sealed for SetBlurs {} + impl State for SetBlurs { + type Identifier = St::Identifier; + type Locales = St::Locales; + type Severity = St::Severity; + type Blurs = Set; + } + /// Marker types for field names + #[allow(non_camel_case_types)] + pub mod members { + ///Marker type for the `identifier` field + pub struct identifier(()); + ///Marker type for the `locales` field + pub struct locales(()); + ///Marker type for the `severity` field + pub struct severity(()); + ///Marker type for the `blurs` field + pub struct blurs(()); + } +} + +/// Builder for constructing an instance of this type. +pub struct LabelValueDefinitionBuilder< + S: BosStr, + St: label_value_definition_state::State, +> { + _state: PhantomData St>, + _fields: ( + Option, + Option>, + Option>, + Option, + Option>>, + Option>, + ), + _type: PhantomData S>, +} + +impl LabelValueDefinition { + /// Create a new builder for this type. + pub fn new() -> LabelValueDefinitionBuilder { + LabelValueDefinitionBuilder::new() + } +} + +impl LabelValueDefinitionBuilder { + /// Create a new builder with all fields unset. + pub fn new() -> Self { + LabelValueDefinitionBuilder { + _state: PhantomData, + _fields: (None, None, None, None, None, None), + _type: PhantomData, + } + } +} + +impl< + S: BosStr, + St: label_value_definition_state::State, +> LabelValueDefinitionBuilder { + /// Set the `adultOnly` field (optional) + pub fn adult_only(mut self, value: impl Into>) -> Self { + self._fields.0 = value.into(); + self + } + /// Set the `adultOnly` field to an Option value (optional) + pub fn maybe_adult_only(mut self, value: Option) -> Self { + self._fields.0 = value; + self + } +} + +impl LabelValueDefinitionBuilder +where + St: label_value_definition_state::State, + St::Blurs: label_value_definition_state::IsUnset, +{ + /// Set the `blurs` field (required) + pub fn blurs( + mut self, + value: impl Into>, + ) -> LabelValueDefinitionBuilder> { + self._fields.1 = Option::Some(value.into()); + LabelValueDefinitionBuilder { + _state: PhantomData, + _fields: self._fields, + _type: PhantomData, + } + } +} + +impl< + S: BosStr, + St: label_value_definition_state::State, +> LabelValueDefinitionBuilder { + /// Set the `defaultSetting` field (optional) + pub fn default_setting( + mut self, + value: impl Into>>, + ) -> Self { + self._fields.2 = value.into(); + self + } + /// Set the `defaultSetting` field to an Option value (optional) + pub fn maybe_default_setting( + mut self, + value: Option>, + ) -> Self { + self._fields.2 = value; + self + } +} + +impl LabelValueDefinitionBuilder +where + St: label_value_definition_state::State, + St::Identifier: label_value_definition_state::IsUnset, +{ + /// Set the `identifier` field (required) + pub fn identifier( + mut self, + value: impl Into, + ) -> LabelValueDefinitionBuilder< + S, + label_value_definition_state::SetIdentifier, + > { + self._fields.3 = Option::Some(value.into()); + LabelValueDefinitionBuilder { + _state: PhantomData, + _fields: self._fields, + _type: PhantomData, + } + } +} + +impl LabelValueDefinitionBuilder +where + St: label_value_definition_state::State, + St::Locales: label_value_definition_state::IsUnset, +{ + /// Set the `locales` field (required) + pub fn locales( + mut self, + value: impl Into>>, + ) -> LabelValueDefinitionBuilder> { + self._fields.4 = Option::Some(value.into()); + LabelValueDefinitionBuilder { + _state: PhantomData, + _fields: self._fields, + _type: PhantomData, + } + } +} + +impl LabelValueDefinitionBuilder +where + St: label_value_definition_state::State, + St::Severity: label_value_definition_state::IsUnset, +{ + /// Set the `severity` field (required) + pub fn severity( + mut self, + value: impl Into>, + ) -> LabelValueDefinitionBuilder> { + self._fields.5 = Option::Some(value.into()); + LabelValueDefinitionBuilder { + _state: PhantomData, + _fields: self._fields, + _type: PhantomData, + } + } +} + +impl LabelValueDefinitionBuilder +where + St: label_value_definition_state::State, + St::Identifier: label_value_definition_state::IsSet, + St::Locales: label_value_definition_state::IsSet, + St::Severity: label_value_definition_state::IsSet, + St::Blurs: label_value_definition_state::IsSet, +{ + /// Build the final struct. + pub fn build(self) -> LabelValueDefinition { + LabelValueDefinition { + adult_only: self._fields.0, + blurs: self._fields.1.unwrap(), + default_setting: self._fields.2, + identifier: self._fields.3.unwrap(), + locales: self._fields.4.unwrap(), + severity: self._fields.5.unwrap(), + extra_data: Default::default(), + } + } + /// Build the final struct with custom extra_data. + pub fn build_with_data( + self, + extra_data: BTreeMap>, + ) -> LabelValueDefinition { + LabelValueDefinition { + adult_only: self._fields.0, + blurs: self._fields.1.unwrap(), + default_setting: self._fields.2, + identifier: self._fields.3.unwrap(), + locales: self._fields.4.unwrap(), + severity: self._fields.5.unwrap(), + extra_data: Some(extra_data), + } + } +} + +pub mod label_value_definition_strings_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 Description; + type Lang; + type Name; + } + /// Empty state - all required fields are unset + pub struct Empty(()); + impl sealed::Sealed for Empty {} + impl State for Empty { + type Description = Unset; + type Lang = Unset; + type Name = Unset; + } + ///State transition - sets the `description` field to Set + pub struct SetDescription(PhantomData St>); + impl sealed::Sealed for SetDescription {} + impl State for SetDescription { + type Description = Set; + type Lang = St::Lang; + type Name = St::Name; + } + ///State transition - sets the `lang` field to Set + pub struct SetLang(PhantomData St>); + impl sealed::Sealed for SetLang {} + impl State for SetLang { + type Description = St::Description; + type Lang = Set; + type Name = St::Name; + } + ///State transition - sets the `name` field to Set + pub struct SetName(PhantomData St>); + impl sealed::Sealed for SetName {} + impl State for SetName { + type Description = St::Description; + type Lang = St::Lang; + type Name = Set; + } + /// Marker types for field names + #[allow(non_camel_case_types)] + pub mod members { + ///Marker type for the `description` field + pub struct description(()); + ///Marker type for the `lang` field + pub struct lang(()); + ///Marker type for the `name` field + pub struct name(()); + } +} + +/// Builder for constructing an instance of this type. +pub struct LabelValueDefinitionStringsBuilder< + S: BosStr, + St: label_value_definition_strings_state::State, +> { + _state: PhantomData St>, + _fields: (Option, Option, Option), + _type: PhantomData S>, +} + +impl LabelValueDefinitionStrings { + /// Create a new builder for this type. + pub fn new() -> LabelValueDefinitionStringsBuilder< + S, + label_value_definition_strings_state::Empty, + > { + LabelValueDefinitionStringsBuilder::new() + } +} + +impl< + S: BosStr, +> LabelValueDefinitionStringsBuilder { + /// Create a new builder with all fields unset. + pub fn new() -> Self { + LabelValueDefinitionStringsBuilder { + _state: PhantomData, + _fields: (None, None, None), + _type: PhantomData, + } + } +} + +impl LabelValueDefinitionStringsBuilder +where + St: label_value_definition_strings_state::State, + St::Description: label_value_definition_strings_state::IsUnset, +{ + /// Set the `description` field (required) + pub fn description( + mut self, + value: impl Into, + ) -> LabelValueDefinitionStringsBuilder< + S, + label_value_definition_strings_state::SetDescription, + > { + self._fields.0 = Option::Some(value.into()); + LabelValueDefinitionStringsBuilder { + _state: PhantomData, + _fields: self._fields, + _type: PhantomData, + } + } +} + +impl LabelValueDefinitionStringsBuilder +where + St: label_value_definition_strings_state::State, + St::Lang: label_value_definition_strings_state::IsUnset, +{ + /// Set the `lang` field (required) + pub fn lang( + mut self, + value: impl Into, + ) -> LabelValueDefinitionStringsBuilder< + S, + label_value_definition_strings_state::SetLang, + > { + self._fields.1 = Option::Some(value.into()); + LabelValueDefinitionStringsBuilder { + _state: PhantomData, + _fields: self._fields, + _type: PhantomData, + } + } +} + +impl LabelValueDefinitionStringsBuilder +where + St: label_value_definition_strings_state::State, + St::Name: label_value_definition_strings_state::IsUnset, +{ + /// Set the `name` field (required) + pub fn name( + mut self, + value: impl Into, + ) -> LabelValueDefinitionStringsBuilder< + S, + label_value_definition_strings_state::SetName, + > { + self._fields.2 = Option::Some(value.into()); + LabelValueDefinitionStringsBuilder { + _state: PhantomData, + _fields: self._fields, + _type: PhantomData, + } + } +} + +impl LabelValueDefinitionStringsBuilder +where + St: label_value_definition_strings_state::State, + St::Description: label_value_definition_strings_state::IsSet, + St::Lang: label_value_definition_strings_state::IsSet, + St::Name: label_value_definition_strings_state::IsSet, +{ + /// Build the final struct. + pub fn build(self) -> LabelValueDefinitionStrings { + LabelValueDefinitionStrings { + description: self._fields.0.unwrap(), + lang: self._fields.1.unwrap(), + name: self._fields.2.unwrap(), + extra_data: Default::default(), + } + } + /// Build the final struct with custom extra_data. + pub fn build_with_data( + self, + extra_data: BTreeMap>, + ) -> LabelValueDefinitionStrings { + LabelValueDefinitionStrings { + description: self._fields.0.unwrap(), + lang: self._fields.1.unwrap(), + name: self._fields.2.unwrap(), + extra_data: Some(extra_data), + } + } +} + +pub mod self_labels_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 Values; + } + /// Empty state - all required fields are unset + pub struct Empty(()); + impl sealed::Sealed for Empty {} + impl State for Empty { + type Values = Unset; + } + ///State transition - sets the `values` field to Set + pub struct SetValues(PhantomData St>); + impl sealed::Sealed for SetValues {} + impl State for SetValues { + type Values = Set; + } + /// Marker types for field names + #[allow(non_camel_case_types)] + pub mod members { + ///Marker type for the `values` field + pub struct values(()); + } +} + +/// Builder for constructing an instance of this type. +pub struct SelfLabelsBuilder { + _state: PhantomData St>, + _fields: (Option>>,), + _type: PhantomData S>, +} + +impl SelfLabels { + /// Create a new builder for this type. + pub fn new() -> SelfLabelsBuilder { + SelfLabelsBuilder::new() + } +} + +impl SelfLabelsBuilder { + /// Create a new builder with all fields unset. + pub fn new() -> Self { + SelfLabelsBuilder { + _state: PhantomData, + _fields: (None,), + _type: PhantomData, + } + } +} + +impl SelfLabelsBuilder +where + St: self_labels_state::State, + St::Values: self_labels_state::IsUnset, +{ + /// Set the `values` field (required) + pub fn values( + mut self, + value: impl Into>>, + ) -> SelfLabelsBuilder> { + self._fields.0 = Option::Some(value.into()); + SelfLabelsBuilder { + _state: PhantomData, + _fields: self._fields, + _type: PhantomData, + } + } +} + +impl SelfLabelsBuilder +where + St: self_labels_state::State, + St::Values: self_labels_state::IsSet, +{ + /// Build the final struct. + pub fn build(self) -> SelfLabels { + SelfLabels { + values: self._fields.0.unwrap(), + extra_data: Default::default(), + } + } + /// Build the final struct with custom extra_data. + pub fn build_with_data( + self, + extra_data: BTreeMap>, + ) -> SelfLabels { + SelfLabels { + values: self._fields.0.unwrap(), + extra_data: Some(extra_data), + } + } +} \ No newline at end of file diff --git a/crates/jacquard-codegen-tests/src/generated/pretty/com_atproto/repo.rs b/crates/jacquard-codegen-tests/src/generated/pretty/com_atproto/repo.rs new file mode 100644 index 00000000..3c65f8fd --- /dev/null +++ b/crates/jacquard-codegen-tests/src/generated/pretty/com_atproto/repo.rs @@ -0,0 +1,6 @@ +// @generated by jacquard-lexicon. DO NOT EDIT. +// +// This file was automatically generated from Lexicon schemas. +// Any manual changes will be overwritten on the next regeneration. + +pub mod strong_ref; \ No newline at end of file diff --git a/crates/jacquard-codegen-tests/src/generated/pretty/com_atproto/repo/strong_ref.rs b/crates/jacquard-codegen-tests/src/generated/pretty/com_atproto/repo/strong_ref.rs new file mode 100644 index 00000000..8b7c0d75 --- /dev/null +++ b/crates/jacquard-codegen-tests/src/generated/pretty/com_atproto/repo/strong_ref.rs @@ -0,0 +1,228 @@ +// @generated by jacquard-lexicon. DO NOT EDIT. +// +// Lexicon: com.atproto.repo.strongRef +// +// 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::{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::string::{AtUri, Cid}; +use jacquard_common::types::value::Data; +use jacquard_derive::IntoStatic; +use jacquard_lexicon::lexicon::LexiconDoc; +use jacquard_lexicon::schema::LexiconSchema; + +#[allow(unused_imports)] +use jacquard_lexicon::validation::{ConstraintError, ValidationPath}; +use serde::{Serialize, Deserialize}; + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)] +#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))] +pub struct StrongRef { + pub cid: Cid, + pub uri: AtUri, + #[serde(flatten, default, skip_serializing_if = "Option::is_none")] + pub extra_data: Option>>, +} + +impl LexiconSchema for StrongRef { + fn nsid() -> &'static str { + "com.atproto.repo.strongRef" + } + fn def_name() -> &'static str { + "main" + } + fn lexicon_doc() -> LexiconDoc<'static> { + lexicon_doc_com_atproto_repo_strongRef() + } + fn validate(&self) -> Result<(), ConstraintError> { + Ok(()) + } +} + +pub mod strong_ref_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 Uri; + type Cid; + } + /// Empty state - all required fields are unset + pub struct Empty(()); + impl sealed::Sealed for Empty {} + impl State for Empty { + type Uri = Unset; + type Cid = Unset; + } + ///State transition - sets the `uri` field to Set + pub struct SetUri(PhantomData St>); + impl sealed::Sealed for SetUri {} + impl State for SetUri { + type Uri = Set; + type Cid = St::Cid; + } + ///State transition - sets the `cid` field to Set + pub struct SetCid(PhantomData St>); + impl sealed::Sealed for SetCid {} + impl State for SetCid { + type Uri = St::Uri; + type Cid = Set; + } + /// Marker types for field names + #[allow(non_camel_case_types)] + pub mod members { + ///Marker type for the `uri` field + pub struct uri(()); + ///Marker type for the `cid` field + pub struct cid(()); + } +} + +/// Builder for constructing an instance of this type. +pub struct StrongRefBuilder { + _state: PhantomData St>, + _fields: (Option>, Option>), + _type: PhantomData S>, +} + +impl StrongRef { + /// Create a new builder for this type. + pub fn new() -> StrongRefBuilder { + StrongRefBuilder::new() + } +} + +impl StrongRefBuilder { + /// Create a new builder with all fields unset. + pub fn new() -> Self { + StrongRefBuilder { + _state: PhantomData, + _fields: (None, None), + _type: PhantomData, + } + } +} + +impl StrongRefBuilder +where + St: strong_ref_state::State, + St::Cid: strong_ref_state::IsUnset, +{ + /// Set the `cid` field (required) + pub fn cid( + mut self, + value: impl Into>, + ) -> StrongRefBuilder> { + self._fields.0 = Option::Some(value.into()); + StrongRefBuilder { + _state: PhantomData, + _fields: self._fields, + _type: PhantomData, + } + } +} + +impl StrongRefBuilder +where + St: strong_ref_state::State, + St::Uri: strong_ref_state::IsUnset, +{ + /// Set the `uri` field (required) + pub fn uri( + mut self, + value: impl Into>, + ) -> StrongRefBuilder> { + self._fields.1 = Option::Some(value.into()); + StrongRefBuilder { + _state: PhantomData, + _fields: self._fields, + _type: PhantomData, + } + } +} + +impl StrongRefBuilder +where + St: strong_ref_state::State, + St::Uri: strong_ref_state::IsSet, + St::Cid: strong_ref_state::IsSet, +{ + /// Build the final struct. + pub fn build(self) -> StrongRef { + StrongRef { + cid: self._fields.0.unwrap(), + uri: self._fields.1.unwrap(), + extra_data: Default::default(), + } + } + /// Build the final struct with custom extra_data. + pub fn build_with_data( + self, + extra_data: BTreeMap>, + ) -> StrongRef { + StrongRef { + cid: self._fields.0.unwrap(), + uri: self._fields.1.unwrap(), + extra_data: Some(extra_data), + } + } +} + +fn lexicon_doc_com_atproto_repo_strongRef() -> LexiconDoc<'static> { + #[allow(unused_imports)] + use jacquard_common::{CowStr, deps::smol_str::SmolStr, types::blob::MimeType}; + use jacquard_lexicon::lexicon::*; + use alloc::collections::BTreeMap; + LexiconDoc { + lexicon: Lexicon::Lexicon1, + id: CowStr::new_static("com.atproto.repo.strongRef"), + defs: { + let mut map = BTreeMap::new(); + map.insert( + SmolStr::new_static("main"), + LexUserType::Object(LexObject { + required: Some( + vec![SmolStr::new_static("uri"), SmolStr::new_static("cid")], + ), + properties: { + #[allow(unused_mut)] + let mut map = BTreeMap::new(); + map.insert( + SmolStr::new_static("cid"), + LexObjectProperty::String(LexString { + format: Some(LexStringFormat::Cid), + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("uri"), + LexObjectProperty::String(LexString { + format: Some(LexStringFormat::AtUri), + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map + }, + ..Default::default() + } +} \ No newline at end of file diff --git a/crates/jacquard-codegen-tests/src/generated/pretty/lib.rs b/crates/jacquard-codegen-tests/src/generated/pretty/lib.rs new file mode 100644 index 00000000..90f780c8 --- /dev/null +++ b/crates/jacquard-codegen-tests/src/generated/pretty/lib.rs @@ -0,0 +1,30 @@ +// @generated by jacquard-lexicon. DO NOT EDIT. +// +// This file was automatically generated from Lexicon schemas. +// Any manual changes will be overwritten on the next regeneration. + +extern crate alloc; + +#[cfg(feature = "app_bsky")] +pub mod app_bsky; +pub mod builder_types; + + +#[cfg(feature = "com_atproto")] +pub mod com_atproto; + + +#[cfg(feature = "test_collision")] +pub mod test_collision; + + +#[cfg(feature = "test_ns1")] +pub mod test_ns1; + + +#[cfg(feature = "test_ns2")] +pub mod test_ns2; + + +#[cfg(feature = "test_ns3")] +pub mod test_ns3; \ No newline at end of file diff --git a/crates/jacquard-codegen-tests/src/generated/pretty/test_collision.rs b/crates/jacquard-codegen-tests/src/generated/pretty/test_collision.rs new file mode 100644 index 00000000..89a1e91c --- /dev/null +++ b/crates/jacquard-codegen-tests/src/generated/pretty/test_collision.rs @@ -0,0 +1,8 @@ +// @generated by jacquard-lexicon. DO NOT EDIT. +// +// This file was automatically generated from Lexicon schemas. +// Any manual changes will be overwritten on the next regeneration. + +pub mod collection; +pub mod did; +pub mod option; \ No newline at end of file diff --git a/crates/jacquard-codegen-tests/src/generated/pretty/test_collision/collection.rs b/crates/jacquard-codegen-tests/src/generated/pretty/test_collision/collection.rs new file mode 100644 index 00000000..298e0bf9 --- /dev/null +++ b/crates/jacquard-codegen-tests/src/generated/pretty/test_collision/collection.rs @@ -0,0 +1,409 @@ +// @generated by jacquard-lexicon. DO NOT EDIT. +// +// Lexicon: test.collision.collection +// +// 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::RecordError; +use jacquard_common::types::string::{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::pretty::test_collision::collection; +/// A locally-defined type named Collection that collides with the trait import. + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic, Default)] +#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))] +pub struct Collection { + #[serde(skip_serializing_if = "Option::is_none")] + pub count: Option, + pub label: S, + #[serde(flatten, default, skip_serializing_if = "Option::is_none")] + pub extra_data: Option>>, +} + +/// A record that itself references the Collection trait via its NSID. + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)] +#[serde( + rename_all = "camelCase", + rename = "test.collision.collection", + tag = "$type", + bound(deserialize = "S: Deserialize<'de> + BosStr") +)] +pub struct CollectionRecord { + #[serde(skip_serializing_if = "Option::is_none")] + pub created_at: Option, + pub items: Vec>, + pub name: S, + #[serde(flatten, default, skip_serializing_if = "Option::is_none")] + pub extra_data: Option>>, +} + +/// 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 CollectionRecordGetRecordOutput { + #[serde(skip_serializing_if = "Option::is_none")] + pub cid: Option>, + pub uri: AtUri, + pub value: CollectionRecord, +} + +impl CollectionRecord { + pub fn uri(uri: S) -> Result, UriError> { + RecordUri::try_from_uri(AtUri::new(uri)?) + } +} + +impl LexiconSchema for Collection { + fn nsid() -> &'static str { + "test.collision.collection" + } + fn def_name() -> &'static str { + "collection" + } + fn lexicon_doc() -> LexiconDoc<'static> { + lexicon_doc_test_collision_collection() + } + fn validate(&self) -> Result<(), ConstraintError> { + if let Some(ref value) = self.count { + if *value < 0i64 { + return Err(ConstraintError::Minimum { + path: ValidationPath::from_field("count"), + min: 0i64, + actual: *value, + }); + } + } + { + let value = &self.label; + #[allow(unused_comparisons)] + if ::len(value.as_ref()) > 100usize { + return Err(ConstraintError::MaxLength { + path: ValidationPath::from_field("label"), + max: 100usize, + actual: ::len(value.as_ref()), + }); + } + } + Ok(()) + } +} + +/// Marker type for deserializing records from this collection. + +#[derive(Debug, Serialize, Deserialize)] +pub struct CollectionRecordRecord; +impl XrpcResp for CollectionRecordRecord { + const NSID: &'static str = "test.collision.collection"; + const ENCODING: &'static str = "application/json"; + type Output = CollectionRecordGetRecordOutput; + type Err = RecordError; +} + +impl From> for CollectionRecord { + fn from(output: CollectionRecordGetRecordOutput) -> Self { + output.value + } +} + +impl jacquard_common::types::collection::Collection for CollectionRecord { + const NSID: &'static str = "test.collision.collection"; + type Record = CollectionRecordRecord; +} + +impl jacquard_common::types::collection::Collection for CollectionRecordRecord { + const NSID: &'static str = "test.collision.collection"; + type Record = CollectionRecordRecord; +} + +impl LexiconSchema for CollectionRecord { + fn nsid() -> &'static str { + "test.collision.collection" + } + fn def_name() -> &'static str { + "main" + } + fn lexicon_doc() -> LexiconDoc<'static> { + lexicon_doc_test_collision_collection() + } + fn validate(&self) -> Result<(), ConstraintError> { + { + let value = &self.name; + #[allow(unused_comparisons)] + if ::len(value.as_ref()) > 256usize { + return Err(ConstraintError::MaxLength { + path: ValidationPath::from_field("name"), + max: 256usize, + actual: ::len(value.as_ref()), + }); + } + } + Ok(()) + } +} + +fn lexicon_doc_test_collision_collection() -> 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("test.collision.collection"), + defs: { + let mut map = BTreeMap::new(); + map.insert( + SmolStr::new_static("collection"), + LexUserType::Object(LexObject { + description: Some( + CowStr::new_static( + "A locally-defined type named Collection that collides with the trait import.", + ), + ), + required: Some(vec![SmolStr::new_static("label")]), + properties: { + #[allow(unused_mut)] + let mut map = BTreeMap::new(); + map.insert( + SmolStr::new_static("count"), + LexObjectProperty::Integer(LexInteger { + minimum: Some(0i64), + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("label"), + LexObjectProperty::String(LexString { + max_length: Some(100usize), + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("main"), + LexUserType::Record(LexRecord { + description: Some( + CowStr::new_static( + "A record that itself references the Collection trait via its NSID.", + ), + ), + key: Some(CowStr::new_static("tid")), + record: LexRecordRecord::Object(LexObject { + required: Some( + vec![ + SmolStr::new_static("name"), SmolStr::new_static("items") + ], + ), + properties: { + #[allow(unused_mut)] + let mut map = BTreeMap::new(); + map.insert( + SmolStr::new_static("createdAt"), + LexObjectProperty::String(LexString { + format: Some(LexStringFormat::Datetime), + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("items"), + LexObjectProperty::Array(LexArray { + items: LexArrayItem::Ref(LexRef { + r#ref: CowStr::new_static("#collection"), + ..Default::default() + }), + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("name"), + LexObjectProperty::String(LexString { + max_length: Some(256usize), + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ..Default::default() + }), + ); + map + }, + ..Default::default() + } +} + +pub mod collection_record_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 Items; + type Name; + } + /// Empty state - all required fields are unset + pub struct Empty(()); + impl sealed::Sealed for Empty {} + impl State for Empty { + type Items = Unset; + type Name = Unset; + } + ///State transition - sets the `items` field to Set + pub struct SetItems(PhantomData St>); + impl sealed::Sealed for SetItems {} + impl State for SetItems { + type Items = Set; + type Name = St::Name; + } + ///State transition - sets the `name` field to Set + pub struct SetName(PhantomData St>); + impl sealed::Sealed for SetName {} + impl State for SetName { + type Items = St::Items; + type Name = Set; + } + /// Marker types for field names + #[allow(non_camel_case_types)] + pub mod members { + ///Marker type for the `items` field + pub struct items(()); + ///Marker type for the `name` field + pub struct name(()); + } +} + +/// Builder for constructing an instance of this type. +pub struct CollectionRecordBuilder { + _state: PhantomData St>, + _fields: (Option, Option>>, Option), + _type: PhantomData S>, +} + +impl CollectionRecord { + /// Create a new builder for this type. + pub fn new() -> CollectionRecordBuilder { + CollectionRecordBuilder::new() + } +} + +impl CollectionRecordBuilder { + /// Create a new builder with all fields unset. + pub fn new() -> Self { + CollectionRecordBuilder { + _state: PhantomData, + _fields: (None, None, None), + _type: PhantomData, + } + } +} + +impl CollectionRecordBuilder { + /// Set the `createdAt` field (optional) + pub fn created_at(mut self, value: impl Into>) -> Self { + self._fields.0 = value.into(); + self + } + /// Set the `createdAt` field to an Option value (optional) + pub fn maybe_created_at(mut self, value: Option) -> Self { + self._fields.0 = value; + self + } +} + +impl CollectionRecordBuilder +where + St: collection_record_state::State, + St::Items: collection_record_state::IsUnset, +{ + /// Set the `items` field (required) + pub fn items( + mut self, + value: impl Into>>, + ) -> CollectionRecordBuilder> { + self._fields.1 = Option::Some(value.into()); + CollectionRecordBuilder { + _state: PhantomData, + _fields: self._fields, + _type: PhantomData, + } + } +} + +impl CollectionRecordBuilder +where + St: collection_record_state::State, + St::Name: collection_record_state::IsUnset, +{ + /// Set the `name` field (required) + pub fn name( + mut self, + value: impl Into, + ) -> CollectionRecordBuilder> { + self._fields.2 = Option::Some(value.into()); + CollectionRecordBuilder { + _state: PhantomData, + _fields: self._fields, + _type: PhantomData, + } + } +} + +impl CollectionRecordBuilder +where + St: collection_record_state::State, + St::Items: collection_record_state::IsSet, + St::Name: collection_record_state::IsSet, +{ + /// Build the final struct. + pub fn build(self) -> CollectionRecord { + CollectionRecord { + created_at: self._fields.0, + items: self._fields.1.unwrap(), + name: self._fields.2.unwrap(), + extra_data: Default::default(), + } + } + /// Build the final struct with custom extra_data. + pub fn build_with_data( + self, + extra_data: BTreeMap>, + ) -> CollectionRecord { + CollectionRecord { + created_at: self._fields.0, + items: self._fields.1.unwrap(), + name: self._fields.2.unwrap(), + extra_data: Some(extra_data), + } + } +} \ No newline at end of file diff --git a/crates/jacquard-codegen-tests/src/generated/pretty/test_collision/did.rs b/crates/jacquard-codegen-tests/src/generated/pretty/test_collision/did.rs new file mode 100644 index 00000000..0bf603ae --- /dev/null +++ b/crates/jacquard-codegen-tests/src/generated/pretty/test_collision/did.rs @@ -0,0 +1,370 @@ +// @generated by jacquard-lexicon. DO NOT EDIT. +// +// Lexicon: test.collision.did +// +// 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::value::Data; +use jacquard_derive::IntoStatic; +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::pretty::test_collision::did; +/// A locally-defined type named Did that collides with the string import. + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic, Default)] +#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))] +pub struct Did { + ///The DID method (e.g., plc, web). + pub method: S, + ///The full DID string. + pub value: S, + #[serde(flatten, default, skip_serializing_if = "Option::is_none")] + pub extra_data: Option>>, +} + +/// An object that also uses a DID-format string field, exercising the collision path. + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)] +#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))] +pub struct DidRecord { + pub identifier: did::Did, + #[serde(skip_serializing_if = "Option::is_none")] + pub label: Option, + ///A field typed as DID format, requiring the Did import but colliding with local Did type. + pub owner: jacquard_common::types::string::Did, + #[serde(flatten, default, skip_serializing_if = "Option::is_none")] + pub extra_data: Option>>, +} + +impl LexiconSchema for Did { + fn nsid() -> &'static str { + "test.collision.did" + } + fn def_name() -> &'static str { + "did" + } + fn lexicon_doc() -> LexiconDoc<'static> { + lexicon_doc_test_collision_did() + } + fn validate(&self) -> Result<(), ConstraintError> { + { + let value = &self.method; + #[allow(unused_comparisons)] + if ::len(value.as_ref()) > 50usize { + return Err(ConstraintError::MaxLength { + path: ValidationPath::from_field("method"), + max: 50usize, + actual: ::len(value.as_ref()), + }); + } + } + { + let value = &self.value; + #[allow(unused_comparisons)] + if ::len(value.as_ref()) > 256usize { + return Err(ConstraintError::MaxLength { + path: ValidationPath::from_field("value"), + max: 256usize, + actual: ::len(value.as_ref()), + }); + } + } + Ok(()) + } +} + +impl LexiconSchema for DidRecord { + fn nsid() -> &'static str { + "test.collision.did" + } + fn def_name() -> &'static str { + "main" + } + fn lexicon_doc() -> LexiconDoc<'static> { + lexicon_doc_test_collision_did() + } + fn validate(&self) -> Result<(), ConstraintError> { + if let Some(ref value) = self.label { + #[allow(unused_comparisons)] + if ::len(value.as_ref()) > 200usize { + return Err(ConstraintError::MaxLength { + path: ValidationPath::from_field("label"), + max: 200usize, + actual: ::len(value.as_ref()), + }); + } + } + Ok(()) + } +} + +fn lexicon_doc_test_collision_did() -> 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("test.collision.did"), + defs: { + let mut map = BTreeMap::new(); + map.insert( + SmolStr::new_static("did"), + LexUserType::Object(LexObject { + description: Some( + CowStr::new_static( + "A locally-defined type named Did that collides with the string import.", + ), + ), + required: Some( + vec![SmolStr::new_static("method"), SmolStr::new_static("value")], + ), + properties: { + #[allow(unused_mut)] + let mut map = BTreeMap::new(); + map.insert( + SmolStr::new_static("method"), + LexObjectProperty::String(LexString { + description: Some( + CowStr::new_static("The DID method (e.g., plc, web)."), + ), + max_length: Some(50usize), + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("value"), + LexObjectProperty::String(LexString { + description: Some( + CowStr::new_static("The full DID string."), + ), + max_length: Some(256usize), + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("main"), + LexUserType::Object(LexObject { + description: Some( + CowStr::new_static( + "An object that also uses a DID-format string field, exercising the collision path.", + ), + ), + required: Some( + vec![ + SmolStr::new_static("owner"), + SmolStr::new_static("identifier") + ], + ), + properties: { + #[allow(unused_mut)] + let mut map = BTreeMap::new(); + map.insert( + SmolStr::new_static("identifier"), + LexObjectProperty::Ref(LexRef { + r#ref: CowStr::new_static("#did"), + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("label"), + LexObjectProperty::String(LexString { + max_length: Some(200usize), + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("owner"), + LexObjectProperty::String(LexString { + description: Some( + CowStr::new_static( + "A field typed as DID format, requiring the Did import but colliding with local Did type.", + ), + ), + format: Some(LexStringFormat::Did), + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map + }, + ..Default::default() + } +} + +pub mod did_record_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 Owner; + type Identifier; + } + /// Empty state - all required fields are unset + pub struct Empty(()); + impl sealed::Sealed for Empty {} + impl State for Empty { + type Owner = Unset; + type Identifier = Unset; + } + ///State transition - sets the `owner` field to Set + pub struct SetOwner(PhantomData St>); + impl sealed::Sealed for SetOwner {} + impl State for SetOwner { + type Owner = Set; + type Identifier = St::Identifier; + } + ///State transition - sets the `identifier` field to Set + pub struct SetIdentifier(PhantomData St>); + impl sealed::Sealed for SetIdentifier {} + impl State for SetIdentifier { + type Owner = St::Owner; + type Identifier = Set; + } + /// Marker types for field names + #[allow(non_camel_case_types)] + pub mod members { + ///Marker type for the `owner` field + pub struct owner(()); + ///Marker type for the `identifier` field + pub struct identifier(()); + } +} + +/// Builder for constructing an instance of this type. +pub struct DidRecordBuilder { + _state: PhantomData St>, + _fields: ( + Option>, + Option, + Option>, + ), + _type: PhantomData S>, +} + +impl DidRecord { + /// Create a new builder for this type. + pub fn new() -> DidRecordBuilder { + DidRecordBuilder::new() + } +} + +impl DidRecordBuilder { + /// Create a new builder with all fields unset. + pub fn new() -> Self { + DidRecordBuilder { + _state: PhantomData, + _fields: (None, None, None), + _type: PhantomData, + } + } +} + +impl DidRecordBuilder +where + St: did_record_state::State, + St::Identifier: did_record_state::IsUnset, +{ + /// Set the `identifier` field (required) + pub fn identifier( + mut self, + value: impl Into>, + ) -> DidRecordBuilder> { + self._fields.0 = Option::Some(value.into()); + DidRecordBuilder { + _state: PhantomData, + _fields: self._fields, + _type: PhantomData, + } + } +} + +impl DidRecordBuilder { + /// Set the `label` field (optional) + pub fn label(mut self, value: impl Into>) -> Self { + self._fields.1 = value.into(); + self + } + /// Set the `label` field to an Option value (optional) + pub fn maybe_label(mut self, value: Option) -> Self { + self._fields.1 = value; + self + } +} + +impl DidRecordBuilder +where + St: did_record_state::State, + St::Owner: did_record_state::IsUnset, +{ + /// Set the `owner` field (required) + pub fn owner( + mut self, + value: impl Into>, + ) -> DidRecordBuilder> { + self._fields.2 = Option::Some(value.into()); + DidRecordBuilder { + _state: PhantomData, + _fields: self._fields, + _type: PhantomData, + } + } +} + +impl DidRecordBuilder +where + St: did_record_state::State, + St::Owner: did_record_state::IsSet, + St::Identifier: did_record_state::IsSet, +{ + /// Build the final struct. + pub fn build(self) -> DidRecord { + DidRecord { + identifier: self._fields.0.unwrap(), + label: self._fields.1, + owner: self._fields.2.unwrap(), + extra_data: Default::default(), + } + } + /// Build the final struct with custom extra_data. + pub fn build_with_data( + self, + extra_data: BTreeMap>, + ) -> DidRecord { + DidRecord { + identifier: self._fields.0.unwrap(), + label: self._fields.1, + owner: self._fields.2.unwrap(), + extra_data: Some(extra_data), + } + } +} \ No newline at end of file diff --git a/crates/jacquard-codegen-tests/src/generated/pretty/test_collision/option.rs b/crates/jacquard-codegen-tests/src/generated/pretty/test_collision/option.rs new file mode 100644 index 00000000..513b8183 --- /dev/null +++ b/crates/jacquard-codegen-tests/src/generated/pretty/test_collision/option.rs @@ -0,0 +1,305 @@ +// @generated by jacquard-lexicon. DO NOT EDIT. +// +// Lexicon: test.collision.option +// +// 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::value::Data; +use jacquard_derive::IntoStatic; +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::pretty::test_collision::option; +/// An object with optional fields, exercising the Option::is_none path collision. + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)] +#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))] +pub struct OptionRecord { + pub choice: option::OptionRecordOption, + #[serde(skip_serializing_if = "Option::is_none")] + pub description: Option, + #[serde(flatten, default, skip_serializing_if = "Option::is_none")] + pub extra_data: Option>>, +} + +/// A locally-defined type named Option, colliding with std::option::Option. + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic, Default)] +#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))] +pub struct OptionRecordOption { + pub key: S, + pub value: S, + #[serde(flatten, default, skip_serializing_if = "Option::is_none")] + pub extra_data: Option>>, +} + +impl LexiconSchema for OptionRecord { + fn nsid() -> &'static str { + "test.collision.option" + } + fn def_name() -> &'static str { + "main" + } + fn lexicon_doc() -> LexiconDoc<'static> { + lexicon_doc_test_collision_option() + } + fn validate(&self) -> Result<(), ConstraintError> { + if let Some(ref value) = self.description { + #[allow(unused_comparisons)] + if ::len(value.as_ref()) > 500usize { + return Err(ConstraintError::MaxLength { + path: ValidationPath::from_field("description"), + max: 500usize, + actual: ::len(value.as_ref()), + }); + } + } + Ok(()) + } +} + +impl LexiconSchema for OptionRecordOption { + fn nsid() -> &'static str { + "test.collision.option" + } + fn def_name() -> &'static str { + "option" + } + fn lexicon_doc() -> LexiconDoc<'static> { + lexicon_doc_test_collision_option() + } + fn validate(&self) -> Result<(), ConstraintError> { + { + let value = &self.key; + #[allow(unused_comparisons)] + if ::len(value.as_ref()) > 100usize { + return Err(ConstraintError::MaxLength { + path: ValidationPath::from_field("key"), + max: 100usize, + actual: ::len(value.as_ref()), + }); + } + } + { + let value = &self.value; + #[allow(unused_comparisons)] + if ::len(value.as_ref()) > 500usize { + return Err(ConstraintError::MaxLength { + path: ValidationPath::from_field("value"), + max: 500usize, + actual: ::len(value.as_ref()), + }); + } + } + Ok(()) + } +} + +pub mod option_record_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 Choice; + } + /// Empty state - all required fields are unset + pub struct Empty(()); + impl sealed::Sealed for Empty {} + impl State for Empty { + type Choice = Unset; + } + ///State transition - sets the `choice` field to Set + pub struct SetChoice(PhantomData St>); + impl sealed::Sealed for SetChoice {} + impl State for SetChoice { + type Choice = Set; + } + /// Marker types for field names + #[allow(non_camel_case_types)] + pub mod members { + ///Marker type for the `choice` field + pub struct choice(()); + } +} + +/// Builder for constructing an instance of this type. +pub struct OptionRecordBuilder { + _state: PhantomData St>, + _fields: (Option>, Option), + _type: PhantomData S>, +} + +impl OptionRecord { + /// Create a new builder for this type. + pub fn new() -> OptionRecordBuilder { + OptionRecordBuilder::new() + } +} + +impl OptionRecordBuilder { + /// Create a new builder with all fields unset. + pub fn new() -> Self { + OptionRecordBuilder { + _state: PhantomData, + _fields: (None, None), + _type: PhantomData, + } + } +} + +impl OptionRecordBuilder +where + St: option_record_state::State, + St::Choice: option_record_state::IsUnset, +{ + /// Set the `choice` field (required) + pub fn choice( + mut self, + value: impl Into>, + ) -> OptionRecordBuilder> { + self._fields.0 = Option::Some(value.into()); + OptionRecordBuilder { + _state: PhantomData, + _fields: self._fields, + _type: PhantomData, + } + } +} + +impl OptionRecordBuilder { + /// Set the `description` field (optional) + pub fn description(mut self, value: impl Into>) -> Self { + self._fields.1 = value.into(); + self + } + /// Set the `description` field to an Option value (optional) + pub fn maybe_description(mut self, value: Option) -> Self { + self._fields.1 = value; + self + } +} + +impl OptionRecordBuilder +where + St: option_record_state::State, + St::Choice: option_record_state::IsSet, +{ + /// Build the final struct. + pub fn build(self) -> OptionRecord { + OptionRecord { + choice: self._fields.0.unwrap(), + description: self._fields.1, + extra_data: Default::default(), + } + } + /// Build the final struct with custom extra_data. + pub fn build_with_data( + self, + extra_data: BTreeMap>, + ) -> OptionRecord { + OptionRecord { + choice: self._fields.0.unwrap(), + description: self._fields.1, + extra_data: Some(extra_data), + } + } +} + +fn lexicon_doc_test_collision_option() -> 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("test.collision.option"), + defs: { + let mut map = BTreeMap::new(); + map.insert( + SmolStr::new_static("main"), + LexUserType::Object(LexObject { + description: Some( + CowStr::new_static( + "An object with optional fields, exercising the Option::is_none path collision.", + ), + ), + required: Some(vec![SmolStr::new_static("choice")]), + properties: { + #[allow(unused_mut)] + let mut map = BTreeMap::new(); + map.insert( + SmolStr::new_static("choice"), + LexObjectProperty::Ref(LexRef { + r#ref: CowStr::new_static("#option"), + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("description"), + LexObjectProperty::String(LexString { + max_length: Some(500usize), + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("option"), + LexUserType::Object(LexObject { + description: Some( + CowStr::new_static( + "A locally-defined type named Option, colliding with std::option::Option.", + ), + ), + required: Some( + vec![SmolStr::new_static("key"), SmolStr::new_static("value")], + ), + properties: { + #[allow(unused_mut)] + let mut map = BTreeMap::new(); + map.insert( + SmolStr::new_static("key"), + LexObjectProperty::String(LexString { + max_length: Some(100usize), + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("value"), + LexObjectProperty::String(LexString { + max_length: Some(500usize), + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map + }, + ..Default::default() + } +} \ No newline at end of file diff --git a/crates/jacquard-codegen-tests/src/generated/pretty/test_ns1.rs b/crates/jacquard-codegen-tests/src/generated/pretty/test_ns1.rs new file mode 100644 index 00000000..8ae0ef12 --- /dev/null +++ b/crates/jacquard-codegen-tests/src/generated/pretty/test_ns1.rs @@ -0,0 +1,165 @@ +// @generated by jacquard-lexicon. DO NOT EDIT. +// +// Lexicon: test.ns1.defs +// +// 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; +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::value::Data; +use jacquard_derive::IntoStatic; +use jacquard_lexicon::lexicon::LexiconDoc; +use jacquard_lexicon::schema::LexiconSchema; + +#[allow(unused_imports)] +use jacquard_lexicon::validation::{ConstraintError, ValidationPath}; +use serde::{Serialize, Deserialize}; +/// Another type in ns1 for cross-namespace ref testing. + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic, Default)] +#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))] +pub struct Bar { + pub tag: S, + #[serde(flatten, default, skip_serializing_if = "Option::is_none")] + pub extra_data: Option>>, +} + +/// A type defined in ns1, referenced cross-namespace by ns2. + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic, Default)] +#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))] +pub struct Foo { + pub name: S, + #[serde(skip_serializing_if = "Option::is_none")] + pub value: Option, + #[serde(flatten, default, skip_serializing_if = "Option::is_none")] + pub extra_data: Option>>, +} + +impl LexiconSchema for Bar { + fn nsid() -> &'static str { + "test.ns1.defs" + } + fn def_name() -> &'static str { + "bar" + } + fn lexicon_doc() -> LexiconDoc<'static> { + lexicon_doc_test_ns1_defs() + } + fn validate(&self) -> Result<(), ConstraintError> { + { + let value = &self.tag; + #[allow(unused_comparisons)] + if ::len(value.as_ref()) > 50usize { + return Err(ConstraintError::MaxLength { + path: ValidationPath::from_field("tag"), + max: 50usize, + actual: ::len(value.as_ref()), + }); + } + } + Ok(()) + } +} + +impl LexiconSchema for Foo { + fn nsid() -> &'static str { + "test.ns1.defs" + } + fn def_name() -> &'static str { + "foo" + } + fn lexicon_doc() -> LexiconDoc<'static> { + lexicon_doc_test_ns1_defs() + } + fn validate(&self) -> Result<(), ConstraintError> { + { + let value = &self.name; + #[allow(unused_comparisons)] + if ::len(value.as_ref()) > 100usize { + return Err(ConstraintError::MaxLength { + path: ValidationPath::from_field("name"), + max: 100usize, + actual: ::len(value.as_ref()), + }); + } + } + Ok(()) + } +} + +fn lexicon_doc_test_ns1_defs() -> 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("test.ns1.defs"), + defs: { + let mut map = BTreeMap::new(); + map.insert( + SmolStr::new_static("bar"), + LexUserType::Object(LexObject { + description: Some( + CowStr::new_static( + "Another type in ns1 for cross-namespace ref testing.", + ), + ), + required: Some(vec![SmolStr::new_static("tag")]), + properties: { + #[allow(unused_mut)] + let mut map = BTreeMap::new(); + map.insert( + SmolStr::new_static("tag"), + LexObjectProperty::String(LexString { + max_length: Some(50usize), + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("foo"), + LexUserType::Object(LexObject { + description: Some( + CowStr::new_static( + "A type defined in ns1, referenced cross-namespace by ns2.", + ), + ), + required: Some(vec![SmolStr::new_static("name")]), + properties: { + #[allow(unused_mut)] + let mut map = BTreeMap::new(); + map.insert( + SmolStr::new_static("name"), + LexObjectProperty::String(LexString { + max_length: Some(100usize), + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("value"), + LexObjectProperty::Integer(LexInteger { + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map + }, + ..Default::default() + } +} \ No newline at end of file diff --git a/crates/jacquard-codegen-tests/src/generated/pretty/test_ns2.rs b/crates/jacquard-codegen-tests/src/generated/pretty/test_ns2.rs new file mode 100644 index 00000000..b94c757e --- /dev/null +++ b/crates/jacquard-codegen-tests/src/generated/pretty/test_ns2.rs @@ -0,0 +1,6 @@ +// @generated by jacquard-lexicon. DO NOT EDIT. +// +// This file was automatically generated from Lexicon schemas. +// Any manual changes will be overwritten on the next regeneration. + +pub mod consumer; \ No newline at end of file diff --git a/crates/jacquard-codegen-tests/src/generated/pretty/test_ns2/consumer.rs b/crates/jacquard-codegen-tests/src/generated/pretty/test_ns2/consumer.rs new file mode 100644 index 00000000..c3c56a02 --- /dev/null +++ b/crates/jacquard-codegen-tests/src/generated/pretty/test_ns2/consumer.rs @@ -0,0 +1,249 @@ +// @generated by jacquard-lexicon. DO NOT EDIT. +// +// Lexicon: test.ns2.consumer +// +// 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::value::Data; +use jacquard_derive::IntoStatic; +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::pretty::test_ns1::Bar; +use crate::pretty::test_ns1::Foo; +/// An object that references types across namespaces. + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)] +#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))] +pub struct Consumer { + #[serde(skip_serializing_if = "Option::is_none")] + pub description: Option, + pub item: Foo, + #[serde(skip_serializing_if = "Option::is_none")] + pub tags: Option>>, + #[serde(flatten, default, skip_serializing_if = "Option::is_none")] + pub extra_data: Option>>, +} + +impl LexiconSchema for Consumer { + fn nsid() -> &'static str { + "test.ns2.consumer" + } + fn def_name() -> &'static str { + "main" + } + fn lexicon_doc() -> LexiconDoc<'static> { + lexicon_doc_test_ns2_consumer() + } + fn validate(&self) -> Result<(), ConstraintError> { + if let Some(ref value) = self.description { + #[allow(unused_comparisons)] + if ::len(value.as_ref()) > 500usize { + return Err(ConstraintError::MaxLength { + path: ValidationPath::from_field("description"), + max: 500usize, + actual: ::len(value.as_ref()), + }); + } + } + Ok(()) + } +} + +pub mod consumer_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 Item; + } + /// Empty state - all required fields are unset + pub struct Empty(()); + impl sealed::Sealed for Empty {} + impl State for Empty { + type Item = Unset; + } + ///State transition - sets the `item` field to Set + pub struct SetItem(PhantomData St>); + impl sealed::Sealed for SetItem {} + impl State for SetItem { + type Item = Set; + } + /// Marker types for field names + #[allow(non_camel_case_types)] + pub mod members { + ///Marker type for the `item` field + pub struct item(()); + } +} + +/// Builder for constructing an instance of this type. +pub struct ConsumerBuilder { + _state: PhantomData St>, + _fields: (Option, Option>, Option>>), + _type: PhantomData S>, +} + +impl Consumer { + /// Create a new builder for this type. + pub fn new() -> ConsumerBuilder { + ConsumerBuilder::new() + } +} + +impl ConsumerBuilder { + /// Create a new builder with all fields unset. + pub fn new() -> Self { + ConsumerBuilder { + _state: PhantomData, + _fields: (None, None, None), + _type: PhantomData, + } + } +} + +impl ConsumerBuilder { + /// Set the `description` field (optional) + pub fn description(mut self, value: impl Into>) -> Self { + self._fields.0 = value.into(); + self + } + /// Set the `description` field to an Option value (optional) + pub fn maybe_description(mut self, value: Option) -> Self { + self._fields.0 = value; + self + } +} + +impl ConsumerBuilder +where + St: consumer_state::State, + St::Item: consumer_state::IsUnset, +{ + /// Set the `item` field (required) + pub fn item( + mut self, + value: impl Into>, + ) -> ConsumerBuilder> { + self._fields.1 = Option::Some(value.into()); + ConsumerBuilder { + _state: PhantomData, + _fields: self._fields, + _type: PhantomData, + } + } +} + +impl ConsumerBuilder { + /// Set the `tags` field (optional) + pub fn tags(mut self, value: impl Into>>>) -> Self { + self._fields.2 = value.into(); + self + } + /// Set the `tags` field to an Option value (optional) + pub fn maybe_tags(mut self, value: Option>>) -> Self { + self._fields.2 = value; + self + } +} + +impl ConsumerBuilder +where + St: consumer_state::State, + St::Item: consumer_state::IsSet, +{ + /// Build the final struct. + pub fn build(self) -> Consumer { + Consumer { + description: self._fields.0, + item: self._fields.1.unwrap(), + tags: self._fields.2, + extra_data: Default::default(), + } + } + /// Build the final struct with custom extra_data. + pub fn build_with_data(self, extra_data: BTreeMap>) -> Consumer { + Consumer { + description: self._fields.0, + item: self._fields.1.unwrap(), + tags: self._fields.2, + extra_data: Some(extra_data), + } + } +} + +fn lexicon_doc_test_ns2_consumer() -> 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("test.ns2.consumer"), + defs: { + let mut map = BTreeMap::new(); + map.insert( + SmolStr::new_static("main"), + LexUserType::Object(LexObject { + description: Some( + CowStr::new_static( + "An object that references types across namespaces.", + ), + ), + required: Some(vec![SmolStr::new_static("item")]), + properties: { + #[allow(unused_mut)] + let mut map = BTreeMap::new(); + map.insert( + SmolStr::new_static("description"), + LexObjectProperty::String(LexString { + max_length: Some(500usize), + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("item"), + LexObjectProperty::Ref(LexRef { + r#ref: CowStr::new_static("test.ns1.defs#foo"), + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("tags"), + LexObjectProperty::Array(LexArray { + items: LexArrayItem::Ref(LexRef { + r#ref: CowStr::new_static("test.ns1.defs#bar"), + ..Default::default() + }), + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map + }, + ..Default::default() + } +} \ No newline at end of file diff --git a/crates/jacquard-codegen-tests/src/generated/pretty/test_ns3.rs b/crates/jacquard-codegen-tests/src/generated/pretty/test_ns3.rs new file mode 100644 index 00000000..523ab25c --- /dev/null +++ b/crates/jacquard-codegen-tests/src/generated/pretty/test_ns3.rs @@ -0,0 +1,6 @@ +// @generated by jacquard-lexicon. DO NOT EDIT. +// +// This file was automatically generated from Lexicon schemas. +// Any manual changes will be overwritten on the next regeneration. + +pub mod collision; \ No newline at end of file diff --git a/crates/jacquard-codegen-tests/src/generated/pretty/test_ns3/collision.rs b/crates/jacquard-codegen-tests/src/generated/pretty/test_ns3/collision.rs new file mode 100644 index 00000000..2ca16dec --- /dev/null +++ b/crates/jacquard-codegen-tests/src/generated/pretty/test_ns3/collision.rs @@ -0,0 +1,438 @@ +// @generated by jacquard-lexicon. DO NOT EDIT. +// +// Lexicon: test.ns3.collision +// +// 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::value::Data; +use jacquard_derive::IntoStatic; +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::pretty::test_ns1; +use crate::pretty::test_ns3::collision; +/// A locally-defined Foo that shares a name with test.ns1.defs#foo. + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)] +#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))] +pub struct Foo { + #[serde(skip_serializing_if = "Option::is_none")] + pub label: Option, + pub local_id: i64, + #[serde(flatten, default, skip_serializing_if = "Option::is_none")] + pub extra_data: Option>>, +} + +/// An object with both a local Foo ref and a cross-namespace Foo ref. + +#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)] +#[serde(rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))] +pub struct Collision { + pub external_foo: test_ns1::Foo, + pub local_foo: collision::Foo, + #[serde(skip_serializing_if = "Option::is_none")] + pub note: Option, + #[serde(flatten, default, skip_serializing_if = "Option::is_none")] + pub extra_data: Option>>, +} + +impl LexiconSchema for Foo { + fn nsid() -> &'static str { + "test.ns3.collision" + } + fn def_name() -> &'static str { + "foo" + } + fn lexicon_doc() -> LexiconDoc<'static> { + lexicon_doc_test_ns3_collision() + } + fn validate(&self) -> Result<(), ConstraintError> { + if let Some(ref value) = self.label { + #[allow(unused_comparisons)] + if ::len(value.as_ref()) > 100usize { + return Err(ConstraintError::MaxLength { + path: ValidationPath::from_field("label"), + max: 100usize, + actual: ::len(value.as_ref()), + }); + } + } + Ok(()) + } +} + +impl LexiconSchema for Collision { + fn nsid() -> &'static str { + "test.ns3.collision" + } + fn def_name() -> &'static str { + "main" + } + fn lexicon_doc() -> LexiconDoc<'static> { + lexicon_doc_test_ns3_collision() + } + fn validate(&self) -> Result<(), ConstraintError> { + Ok(()) + } +} + +pub mod foo_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 LocalId; + } + /// Empty state - all required fields are unset + pub struct Empty(()); + impl sealed::Sealed for Empty {} + impl State for Empty { + type LocalId = Unset; + } + ///State transition - sets the `local_id` field to Set + pub struct SetLocalId(PhantomData St>); + impl sealed::Sealed for SetLocalId {} + impl State for SetLocalId { + type LocalId = Set; + } + /// Marker types for field names + #[allow(non_camel_case_types)] + pub mod members { + ///Marker type for the `local_id` field + pub struct local_id(()); + } +} + +/// Builder for constructing an instance of this type. +pub struct FooBuilder { + _state: PhantomData St>, + _fields: (Option, Option), + _type: PhantomData S>, +} + +impl Foo { + /// Create a new builder for this type. + pub fn new() -> FooBuilder { + FooBuilder::new() + } +} + +impl FooBuilder { + /// Create a new builder with all fields unset. + pub fn new() -> Self { + FooBuilder { + _state: PhantomData, + _fields: (None, None), + _type: PhantomData, + } + } +} + +impl FooBuilder { + /// Set the `label` field (optional) + pub fn label(mut self, value: impl Into>) -> Self { + self._fields.0 = value.into(); + self + } + /// Set the `label` field to an Option value (optional) + pub fn maybe_label(mut self, value: Option) -> Self { + self._fields.0 = value; + self + } +} + +impl FooBuilder +where + St: foo_state::State, + St::LocalId: foo_state::IsUnset, +{ + /// Set the `localId` field (required) + pub fn local_id( + mut self, + value: impl Into, + ) -> FooBuilder> { + self._fields.1 = Option::Some(value.into()); + FooBuilder { + _state: PhantomData, + _fields: self._fields, + _type: PhantomData, + } + } +} + +impl FooBuilder +where + St: foo_state::State, + St::LocalId: foo_state::IsSet, +{ + /// Build the final struct. + pub fn build(self) -> Foo { + Foo { + label: self._fields.0, + local_id: self._fields.1.unwrap(), + extra_data: Default::default(), + } + } + /// Build the final struct with custom extra_data. + pub fn build_with_data(self, extra_data: BTreeMap>) -> Foo { + Foo { + label: self._fields.0, + local_id: self._fields.1.unwrap(), + extra_data: Some(extra_data), + } + } +} + +fn lexicon_doc_test_ns3_collision() -> 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("test.ns3.collision"), + defs: { + let mut map = BTreeMap::new(); + map.insert( + SmolStr::new_static("foo"), + LexUserType::Object(LexObject { + description: Some( + CowStr::new_static( + "A locally-defined Foo that shares a name with test.ns1.defs#foo.", + ), + ), + required: Some(vec![SmolStr::new_static("localId")]), + properties: { + #[allow(unused_mut)] + let mut map = BTreeMap::new(); + map.insert( + SmolStr::new_static("label"), + LexObjectProperty::String(LexString { + max_length: Some(100usize), + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("localId"), + LexObjectProperty::Integer(LexInteger { + ..Default::default() + }), + ); + map + }, + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("main"), + LexUserType::Object(LexObject { + description: Some( + CowStr::new_static( + "An object with both a local Foo ref and a cross-namespace Foo ref.", + ), + ), + required: Some( + vec![ + SmolStr::new_static("localFoo"), + SmolStr::new_static("externalFoo") + ], + ), + properties: { + #[allow(unused_mut)] + let mut map = BTreeMap::new(); + map.insert( + SmolStr::new_static("externalFoo"), + LexObjectProperty::Ref(LexRef { + r#ref: CowStr::new_static("test.ns1.defs#foo"), + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("localFoo"), + LexObjectProperty::Ref(LexRef { + r#ref: CowStr::new_static("#foo"), + ..Default::default() + }), + ); + map.insert( + SmolStr::new_static("note"), + LexObjectProperty::String(LexString { ..Default::default() }), + ); + map + }, + ..Default::default() + }), + ); + map + }, + ..Default::default() + } +} + +pub mod collision_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 ExternalFoo; + type LocalFoo; + } + /// Empty state - all required fields are unset + pub struct Empty(()); + impl sealed::Sealed for Empty {} + impl State for Empty { + type ExternalFoo = Unset; + type LocalFoo = Unset; + } + ///State transition - sets the `external_foo` field to Set + pub struct SetExternalFoo(PhantomData St>); + impl sealed::Sealed for SetExternalFoo {} + impl State for SetExternalFoo { + type ExternalFoo = Set; + type LocalFoo = St::LocalFoo; + } + ///State transition - sets the `local_foo` field to Set + pub struct SetLocalFoo(PhantomData St>); + impl sealed::Sealed for SetLocalFoo {} + impl State for SetLocalFoo { + type ExternalFoo = St::ExternalFoo; + type LocalFoo = Set; + } + /// Marker types for field names + #[allow(non_camel_case_types)] + pub mod members { + ///Marker type for the `external_foo` field + pub struct external_foo(()); + ///Marker type for the `local_foo` field + pub struct local_foo(()); + } +} + +/// Builder for constructing an instance of this type. +pub struct CollisionBuilder { + _state: PhantomData St>, + _fields: (Option>, Option>, Option), + _type: PhantomData S>, +} + +impl Collision { + /// Create a new builder for this type. + pub fn new() -> CollisionBuilder { + CollisionBuilder::new() + } +} + +impl CollisionBuilder { + /// Create a new builder with all fields unset. + pub fn new() -> Self { + CollisionBuilder { + _state: PhantomData, + _fields: (None, None, None), + _type: PhantomData, + } + } +} + +impl CollisionBuilder +where + St: collision_state::State, + St::ExternalFoo: collision_state::IsUnset, +{ + /// Set the `externalFoo` field (required) + pub fn external_foo( + mut self, + value: impl Into>, + ) -> CollisionBuilder> { + self._fields.0 = Option::Some(value.into()); + CollisionBuilder { + _state: PhantomData, + _fields: self._fields, + _type: PhantomData, + } + } +} + +impl CollisionBuilder +where + St: collision_state::State, + St::LocalFoo: collision_state::IsUnset, +{ + /// Set the `localFoo` field (required) + pub fn local_foo( + mut self, + value: impl Into>, + ) -> CollisionBuilder> { + self._fields.1 = Option::Some(value.into()); + CollisionBuilder { + _state: PhantomData, + _fields: self._fields, + _type: PhantomData, + } + } +} + +impl CollisionBuilder { + /// Set the `note` field (optional) + pub fn note(mut self, value: impl Into>) -> Self { + self._fields.2 = value.into(); + self + } + /// Set the `note` field to an Option value (optional) + pub fn maybe_note(mut self, value: Option) -> Self { + self._fields.2 = value; + self + } +} + +impl CollisionBuilder +where + St: collision_state::State, + St::ExternalFoo: collision_state::IsSet, + St::LocalFoo: collision_state::IsSet, +{ + /// Build the final struct. + pub fn build(self) -> Collision { + Collision { + external_foo: self._fields.0.unwrap(), + local_foo: self._fields.1.unwrap(), + note: self._fields.2, + extra_data: Default::default(), + } + } + /// Build the final struct with custom extra_data. + pub fn build_with_data( + self, + extra_data: BTreeMap>, + ) -> Collision { + Collision { + external_foo: self._fields.0.unwrap(), + local_foo: self._fields.1.unwrap(), + note: self._fields.2, + extra_data: Some(extra_data), + } + } +} \ No newline at end of file diff --git a/crates/jacquard-codegen-tests/tests/fixtures/app_bsky_feed_post.json b/crates/jacquard-codegen-tests/tests/fixtures/app_bsky_feed_post.json new file mode 100644 index 00000000..56de9ed2 --- /dev/null +++ b/crates/jacquard-codegen-tests/tests/fixtures/app_bsky_feed_post.json @@ -0,0 +1,144 @@ +{ + "lexicon": 1, + "id": "app.bsky.feed.post", + "defs": { + "entity": { + "type": "object", + "description": "Deprecated: use facets instead.", + "required": [ + "index", + "type", + "value" + ], + "properties": { + "index": { + "type": "ref", + "ref": "#textSlice" + }, + "type": { + "type": "string", + "description": "Expected values are 'mention' and 'link'." + }, + "value": { + "type": "string" + } + } + }, + "main": { + "type": "record", + "description": "Record containing a Bluesky post.", + "key": "tid", + "record": { + "type": "object", + "required": [ + "text", + "createdAt" + ], + "properties": { + "createdAt": { + "type": "string", + "description": "Client-declared timestamp when this post was originally created.", + "format": "datetime" + }, + "embed": { + "type": "union", + "refs": [ + "app.bsky.embed.images", + "app.bsky.embed.video", + "app.bsky.embed.external", + "app.bsky.embed.record", + "app.bsky.embed.recordWithMedia" + ] + }, + "entities": { + "type": "array", + "description": "DEPRECATED: replaced by app.bsky.richtext.facet.", + "items": { + "type": "ref", + "ref": "#entity" + } + }, + "facets": { + "type": "array", + "description": "Annotations of text (mentions, URLs, hashtags, etc)", + "items": { + "type": "ref", + "ref": "app.bsky.richtext.facet" + } + }, + "labels": { + "type": "union", + "description": "Self-label values for this post. Effectively content warnings.", + "refs": [ + "com.atproto.label.defs#selfLabels" + ] + }, + "langs": { + "type": "array", + "description": "Indicates human language of post primary text content.", + "items": { + "type": "string", + "format": "language" + }, + "maxLength": 3 + }, + "reply": { + "type": "ref", + "ref": "#replyRef" + }, + "tags": { + "type": "array", + "description": "Additional hashtags, in addition to any included in post text and facets.", + "items": { + "type": "string", + "maxLength": 640, + "maxGraphemes": 64 + }, + "maxLength": 8 + }, + "text": { + "type": "string", + "description": "The primary post content. May be an empty string, if there are embeds.", + "maxLength": 3000, + "maxGraphemes": 300 + } + } + } + }, + "replyRef": { + "type": "object", + "required": [ + "root", + "parent" + ], + "properties": { + "parent": { + "type": "ref", + "ref": "com.atproto.repo.strongRef" + }, + "root": { + "type": "ref", + "ref": "com.atproto.repo.strongRef" + } + } + }, + "textSlice": { + "type": "object", + "description": "Deprecated. Use app.bsky.richtext instead -- A text segment. Start is inclusive, end is exclusive. Indices are for utf16-encoded strings.", + "required": [ + "start", + "end" + ], + "properties": { + "end": { + "type": "integer", + "minimum": 0 + }, + "start": { + "type": "integer", + "minimum": 0 + } + } + } + } +} \ No newline at end of file diff --git a/crates/jacquard-lexicon/tests/fixtures/app_bsky_feed_post.rs b/crates/jacquard-codegen-tests/tests/fixtures/app_bsky_feed_post.rs similarity index 100% rename from crates/jacquard-lexicon/tests/fixtures/app_bsky_feed_post.rs rename to crates/jacquard-codegen-tests/tests/fixtures/app_bsky_feed_post.rs diff --git a/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/arrayTypes.json b/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/arrayTypes.json new file mode 100644 index 00000000..3c5ff481 --- /dev/null +++ b/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/arrayTypes.json @@ -0,0 +1,74 @@ +{ + "lexicon": 1, + "id": "test.array.types", + "defs": { + "main": { + "type": "object", + "properties": { + "simpleStrings": { + "type": "array", + "items": { + "type": "string" + } + }, + "unionItems": { + "type": "array", + "items": { + "type": "union", + "refs": ["#textItem", "#imageItem"] + } + }, + "refItems": { + "type": "array", + "items": { + "type": "ref", + "ref": "#nestedObject" + } + }, + "objectItems": { + "type": "array", + "items": { + "type": "object", + "properties": { + "inline": { + "type": "string" + } + } + } + }, + "cidLinks": { + "type": "array", + "items": { + "type": "cid-link" + } + } + } + }, + "textItem": { + "type": "object", + "required": ["text"], + "properties": { + "text": { + "type": "string" + } + } + }, + "imageItem": { + "type": "object", + "required": ["blob"], + "properties": { + "blob": { + "type": "blob" + } + } + }, + "nestedObject": { + "type": "object", + "properties": { + "value": { + "type": "integer" + } + } + } + } +} diff --git a/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/binaryTypes.json b/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/binaryTypes.json new file mode 100644 index 00000000..673c2249 --- /dev/null +++ b/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/binaryTypes.json @@ -0,0 +1,30 @@ +{ + "lexicon": 1, + "id": "test.binary.types", + "defs": { + "main": { + "type": "object", + "required": ["cid", "data"], + "properties": { + "cid": { + "type": "cid-link", + "description": "Content identifier" + }, + "data": { + "type": "bytes", + "description": "Raw bytes", + "maxLength": 5000 + }, + "avatar": { + "type": "blob", + "accept": ["image/*"], + "maxSize": 1000000, + "description": "Profile avatar" + }, + "optionalCid": { + "type": "cid-link" + } + } + } + } +} diff --git a/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/constraints.json b/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/constraints.json new file mode 100644 index 00000000..9a31b871 --- /dev/null +++ b/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/constraints.json @@ -0,0 +1,45 @@ +{ + "lexicon": 1, + "id": "test.constraints.validation", + "defs": { + "main": { + "type": "object", + "properties": { + "username": { + "type": "string", + "minLength": 3, + "maxLength": 20, + "description": "User handle" + }, + "bio": { + "type": "string", + "maxGraphemes": 256, + "minGraphemes": 1 + }, + "age": { + "type": "integer", + "minimum": 13, + "maximum": 120, + "default": 18 + }, + "enabled": { + "type": "boolean", + "default": false + }, + "tags": { + "type": "array", + "items": { + "type": "string" + }, + "minLength": 0, + "maxLength": 10 + }, + "role": { + "type": "string", + "default": "user", + "knownValues": ["user", "admin", "moderator"] + } + } + } + } +} diff --git a/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/createRecord.json b/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/createRecord.json new file mode 100644 index 00000000..cb89f52c --- /dev/null +++ b/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/createRecord.json @@ -0,0 +1,65 @@ +{ + "lexicon": 1, + "id": "com.atproto.repo.createRecord", + "defs": { + "main": { + "type": "procedure", + "description": "Create a new record in a repository.", + "input": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["repo", "collection", "record"], + "properties": { + "repo": { + "type": "string", + "format": "at-identifier", + "description": "The handle or DID of the repo" + }, + "collection": { + "type": "string", + "format": "nsid" + }, + "rkey": { + "type": "string", + "format": "record-key" + }, + "validate": { + "type": "boolean", + "default": true + }, + "record": { + "type": "unknown", + "description": "The record to create" + }, + "swapCommit": { + "type": "string", + "format": "cid" + } + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["uri", "cid"], + "properties": { + "uri": { + "type": "string", + "format": "at-uri" + }, + "cid": { + "type": "string", + "format": "cid" + } + } + } + }, + "errors": [ + {"name": "InvalidSwap"}, + {"name": "InvalidRecord"} + ] + } + } +} diff --git a/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/defs.json b/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/defs.json new file mode 100644 index 00000000..6f4c1ab9 --- /dev/null +++ b/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/defs.json @@ -0,0 +1,156 @@ +{ + "lexicon": 1, + "id": "com.atproto.label.defs", + "defs": { + "label": { + "type": "object", + "description": "Metadata tag on an atproto resource (eg, repo or record).", + "required": ["src", "uri", "val", "cts"], + "properties": { + "ver": { + "type": "integer", + "description": "The AT Protocol version of the label object." + }, + "src": { + "type": "string", + "format": "did", + "description": "DID of the actor who created this label." + }, + "uri": { + "type": "string", + "format": "uri", + "description": "AT URI of the record, repository (account), or other resource that this label applies to." + }, + "cid": { + "type": "string", + "format": "cid", + "description": "Optionally, CID specifying the specific version of 'uri' resource this label applies to." + }, + "val": { + "type": "string", + "maxLength": 128, + "description": "The short string name of the value or type of this label." + }, + "neg": { + "type": "boolean", + "description": "If true, this is a negation label, overwriting a previous label." + }, + "cts": { + "type": "string", + "format": "datetime", + "description": "Timestamp when this label was created." + }, + "exp": { + "type": "string", + "format": "datetime", + "description": "Timestamp at which this label expires (no longer applies)." + }, + "sig": { + "type": "bytes", + "description": "Signature of dag-cbor encoded label." + } + } + }, + "selfLabels": { + "type": "object", + "description": "Metadata tags on an atproto record, published by the author within the record.", + "required": ["values"], + "properties": { + "values": { + "type": "array", + "items": { "type": "ref", "ref": "#selfLabel" }, + "maxLength": 10 + } + } + }, + "selfLabel": { + "type": "object", + "description": "Metadata tag on an atproto record, published by the author within the record. Note that schemas should use #selfLabels, not #selfLabel.", + "required": ["val"], + "properties": { + "val": { + "type": "string", + "maxLength": 128, + "description": "The short string name of the value or type of this label." + } + } + }, + "labelValueDefinition": { + "type": "object", + "description": "Declares a label value and its expected interpretations and behaviors.", + "required": ["identifier", "severity", "blurs", "locales"], + "properties": { + "identifier": { + "type": "string", + "description": "The value of the label being defined. Must only include lowercase ascii and the '-' character ([a-z-]+).", + "maxLength": 100, + "maxGraphemes": 100 + }, + "severity": { + "type": "string", + "description": "How should a client visually convey this label? 'inform' means neutral and informational; 'alert' means negative and warning; 'none' means show nothing.", + "knownValues": ["inform", "alert", "none"] + }, + "blurs": { + "type": "string", + "description": "What should this label hide in the UI, if applied? 'content' hides all of the target; 'media' hides the images/video/audio; 'none' hides nothing.", + "knownValues": ["content", "media", "none"] + }, + "defaultSetting": { + "type": "string", + "description": "The default setting for this label.", + "knownValues": ["ignore", "warn", "hide"], + "default": "warn" + }, + "adultOnly": { + "type": "boolean", + "description": "Does the user need to have adult content enabled in order to configure this label?" + }, + "locales": { + "type": "array", + "items": { "type": "ref", "ref": "#labelValueDefinitionStrings" } + } + } + }, + "labelValueDefinitionStrings": { + "type": "object", + "description": "Strings which describe the label in the UI, localized into a specific language.", + "required": ["lang", "name", "description"], + "properties": { + "lang": { + "type": "string", + "description": "The code of the language these strings are written in.", + "format": "language" + }, + "name": { + "type": "string", + "description": "A short human-readable name for the label.", + "maxGraphemes": 64, + "maxLength": 640 + }, + "description": { + "type": "string", + "description": "A longer description of what the label means and why it might be applied.", + "maxGraphemes": 10000, + "maxLength": 100000 + } + } + }, + "labelValue": { + "type": "string", + "knownValues": [ + "!hide", + "!no-promote", + "!warn", + "!no-unauthenticated", + "dmca-violation", + "doxxing", + "porn", + "sexual", + "nudity", + "nsfl", + "gore" + ] + } + } +} diff --git a/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/emptyObject.json b/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/emptyObject.json new file mode 100644 index 00000000..ec78dd31 --- /dev/null +++ b/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/emptyObject.json @@ -0,0 +1,23 @@ +{ + "lexicon": 1, + "id": "test.empty.object", + "defs": { + "main": { + "type": "object", + "properties": { + "withEmpty": { + "type": "ref", + "ref": "#emptyDef" + }, + "normal": { + "type": "string" + } + } + }, + "emptyDef": { + "type": "object", + "description": "Object with no properties - should generate Data<'a>", + "properties": {} + } + } +} diff --git a/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/external.json b/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/external.json new file mode 100644 index 00000000..b9930dff --- /dev/null +++ b/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/external.json @@ -0,0 +1,51 @@ +{ + "lexicon": 1, + "id": "app.bsky.embed.external", + "defs": { + "main": { + "type": "object", + "description": "A representation of some externally linked content (eg, a URL and 'card'), embedded in a Bluesky record (eg, a post).", + "required": ["external"], + "properties": { + "external": { + "type": "ref", + "ref": "#external" + } + } + }, + "external": { + "type": "object", + "required": ["uri", "title", "description"], + "properties": { + "uri": { "type": "string", "format": "uri" }, + "title": { "type": "string" }, + "description": { "type": "string" }, + "thumb": { + "type": "blob", + "accept": ["image/*"], + "maxSize": 1000000 + } + } + }, + "view": { + "type": "object", + "required": ["external"], + "properties": { + "external": { + "type": "ref", + "ref": "#viewExternal" + } + } + }, + "viewExternal": { + "type": "object", + "required": ["uri", "title", "description"], + "properties": { + "uri": { "type": "string", "format": "uri" }, + "title": { "type": "string" }, + "description": { "type": "string" }, + "thumb": { "type": "string", "format": "uri" } + } + } + } +} diff --git a/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/facet.json b/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/facet.json new file mode 100644 index 00000000..388a3a5e --- /dev/null +++ b/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/facet.json @@ -0,0 +1,51 @@ +{ + "lexicon": 1, + "id": "app.bsky.richtext.facet", + "defs": { + "main": { + "type": "object", + "description": "Annotation of a sub-string within rich text.", + "required": ["index", "features"], + "properties": { + "index": { "type": "ref", "ref": "#byteSlice" }, + "features": { + "type": "array", + "items": { "type": "union", "refs": ["#mention", "#link", "#tag"] } + } + } + }, + "mention": { + "type": "object", + "description": "Facet feature for mention of another account. The text is usually a handle, including a '@' prefix, but the facet reference is a DID.", + "required": ["did"], + "properties": { + "did": { "type": "string", "format": "did" } + } + }, + "link": { + "type": "object", + "description": "Facet feature for a URL. The text URL may have been simplified or truncated, but the facet reference should be a complete URL.", + "required": ["uri"], + "properties": { + "uri": { "type": "string", "format": "uri" } + } + }, + "tag": { + "type": "object", + "description": "Facet feature for a hashtag. The text usually includes a '#' prefix, but the facet reference should not (except in the case of 'double hash tags').", + "required": ["tag"], + "properties": { + "tag": { "type": "string", "maxLength": 640, "maxGraphemes": 64 } + } + }, + "byteSlice": { + "type": "object", + "description": "Specifies the sub-string range a facet feature applies to. Start index is inclusive, end index is exclusive. Indices are zero-indexed, counting bytes of the UTF-8 encoded text. NOTE: some languages, like Javascript, use UTF-16 or Unicode codepoints for string slice indexing; in these languages, convert to byte arrays before working with facets.", + "required": ["byteStart", "byteEnd"], + "properties": { + "byteStart": { "type": "integer", "minimum": 0 }, + "byteEnd": { "type": "integer", "minimum": 0 } + } + } + } +} diff --git a/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/getAuthorFeed.json b/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/getAuthorFeed.json new file mode 100644 index 00000000..c9ef8c50 --- /dev/null +++ b/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/getAuthorFeed.json @@ -0,0 +1,58 @@ +{ + "lexicon": 1, + "id": "app.bsky.feed.getAuthorFeed", + "defs": { + "main": { + "type": "query", + "description": "Get a view of an actor's 'author feed' (post and reposts by the author). Does not require auth.", + "parameters": { + "type": "params", + "required": ["actor"], + "properties": { + "actor": { "type": "string", "format": "at-identifier" }, + "limit": { + "type": "integer", + "minimum": 1, + "maximum": 100, + "default": 50 + }, + "cursor": { "type": "string" }, + "filter": { + "type": "string", + "description": "Combinations of post/repost types to include in response.", + "knownValues": [ + "posts_with_replies", + "posts_no_replies", + "posts_with_media", + "posts_and_author_threads", + "posts_with_video" + ], + "default": "posts_with_replies" + }, + "includePins": { + "type": "boolean", + "default": false + } + } + }, + "output": { + "encoding": "application/json", + "schema": { + "type": "object", + "required": ["feed"], + "properties": { + "cursor": { "type": "string" }, + "feed": { + "type": "array", + "items": { + "type": "ref", + "ref": "app.bsky.feed.defs#feedViewPost" + } + } + } + } + }, + "errors": [{ "name": "BlockedActor" }, { "name": "BlockedByActor" }] + } + } +} diff --git a/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/images.json b/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/images.json new file mode 100644 index 00000000..c6b6fa20 --- /dev/null +++ b/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/images.json @@ -0,0 +1,72 @@ +{ + "lexicon": 1, + "id": "app.bsky.embed.images", + "description": "A set of images embedded in a Bluesky record (eg, a post).", + "defs": { + "main": { + "type": "object", + "required": ["images"], + "properties": { + "images": { + "type": "array", + "items": { "type": "ref", "ref": "#image" }, + "maxLength": 4 + } + } + }, + "image": { + "type": "object", + "required": ["image", "alt"], + "properties": { + "image": { + "type": "blob", + "accept": ["image/*"], + "maxSize": 1000000 + }, + "alt": { + "type": "string", + "description": "Alt text description of the image, for accessibility." + }, + "aspectRatio": { + "type": "ref", + "ref": "app.bsky.embed.defs#aspectRatio" + } + } + }, + "view": { + "type": "object", + "required": ["images"], + "properties": { + "images": { + "type": "array", + "items": { "type": "ref", "ref": "#viewImage" }, + "maxLength": 4 + } + } + }, + "viewImage": { + "type": "object", + "required": ["thumb", "fullsize", "alt"], + "properties": { + "thumb": { + "type": "string", + "format": "uri", + "description": "Fully-qualified URL where a thumbnail of the image can be fetched. For example, CDN location provided by the App View." + }, + "fullsize": { + "type": "string", + "format": "uri", + "description": "Fully-qualified URL where a large version of the image can be fetched. May or may not be the exact original blob. For example, CDN location provided by the App View." + }, + "alt": { + "type": "string", + "description": "Alt text description of the image, for accessibility." + }, + "aspectRatio": { + "type": "ref", + "ref": "app.bsky.embed.defs#aspectRatio" + } + } + } + } +} diff --git a/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/multiDef.json b/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/multiDef.json new file mode 100644 index 00000000..46d4a822 --- /dev/null +++ b/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/multiDef.json @@ -0,0 +1,58 @@ +{ + "lexicon": 1, + "id": "pub.leaflet.poll.definition", + "defs": { + "main": { + "type": "record", + "description": "Poll definition record", + "key": "tid", + "record": { + "type": "object", + "required": ["question", "options"], + "properties": { + "question": { + "type": "string", + "maxLength": 300 + }, + "options": { + "type": "array", + "items": { + "type": "ref", + "ref": "#option" + }, + "minLength": 2, + "maxLength": 4 + }, + "endsAt": { + "type": "string", + "format": "datetime" + } + } + } + }, + "option": { + "type": "object", + "required": ["text"], + "properties": { + "text": { + "type": "string", + "maxLength": 100 + } + } + }, + "vote": { + "type": "object", + "required": ["pollRef", "optionIndex"], + "properties": { + "pollRef": { + "type": "ref", + "ref": "com.atproto.repo.strongRef" + }, + "optionIndex": { + "type": "integer", + "minimum": 0 + } + } + } + } +} diff --git a/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/not_a_lexicon.json b/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/not_a_lexicon.json new file mode 100644 index 00000000..88443e86 --- /dev/null +++ b/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/not_a_lexicon.json @@ -0,0 +1,7 @@ +{ + "name": "some random config", + "version": "1.0.0", + "settings": { + "enabled": true + } +} diff --git a/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/post.json b/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/post.json new file mode 100644 index 00000000..9893a355 --- /dev/null +++ b/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/post.json @@ -0,0 +1,96 @@ +{ + "lexicon": 1, + "id": "app.bsky.feed.post", + "defs": { + "main": { + "type": "record", + "description": "Record containing a Bluesky post.", + "key": "tid", + "record": { + "type": "object", + "required": ["text", "createdAt"], + "properties": { + "text": { + "type": "string", + "maxLength": 3000, + "maxGraphemes": 300, + "description": "The primary post content. May be an empty string, if there are embeds." + }, + "entities": { + "type": "array", + "description": "DEPRECATED: replaced by app.bsky.richtext.facet.", + "items": { "type": "ref", "ref": "#entity" } + }, + "facets": { + "type": "array", + "description": "Annotations of text (mentions, URLs, hashtags, etc)", + "items": { "type": "ref", "ref": "app.bsky.richtext.facet" } + }, + "reply": { "type": "ref", "ref": "#replyRef" }, + "embed": { + "type": "union", + "refs": [ + "app.bsky.embed.images", + "app.bsky.embed.video", + "app.bsky.embed.external", + "app.bsky.embed.record", + "app.bsky.embed.recordWithMedia" + ] + }, + "langs": { + "type": "array", + "description": "Indicates human language of post primary text content.", + "maxLength": 3, + "items": { "type": "string", "format": "language" } + }, + "labels": { + "type": "union", + "description": "Self-label values for this post. Effectively content warnings.", + "refs": ["com.atproto.label.defs#selfLabels"] + }, + "tags": { + "type": "array", + "description": "Additional hashtags, in addition to any included in post text and facets.", + "maxLength": 8, + "items": { "type": "string", "maxLength": 640, "maxGraphemes": 64 } + }, + "createdAt": { + "type": "string", + "format": "datetime", + "description": "Client-declared timestamp when this post was originally created." + } + } + } + }, + "replyRef": { + "type": "object", + "required": ["root", "parent"], + "properties": { + "root": { "type": "ref", "ref": "com.atproto.repo.strongRef" }, + "parent": { "type": "ref", "ref": "com.atproto.repo.strongRef" } + } + }, + "entity": { + "type": "object", + "description": "Deprecated: use facets instead.", + "required": ["index", "type", "value"], + "properties": { + "index": { "type": "ref", "ref": "#textSlice" }, + "type": { + "type": "string", + "description": "Expected values are 'mention' and 'link'." + }, + "value": { "type": "string" } + } + }, + "textSlice": { + "type": "object", + "description": "Deprecated. Use app.bsky.richtext instead -- A text segment. Start is inclusive, end is exclusive. Indices are for utf16-encoded strings.", + "required": ["start", "end"], + "properties": { + "start": { "type": "integer", "minimum": 0 }, + "end": { "type": "integer", "minimum": 0 } + } + } + } +} diff --git a/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/record.json b/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/record.json new file mode 100644 index 00000000..a73200a3 --- /dev/null +++ b/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/record.json @@ -0,0 +1,96 @@ +{ + "lexicon": 1, + "id": "app.bsky.embed.record", + "description": "A representation of a record embedded in a Bluesky record (eg, a post). For example, a quote-post, or sharing a feed generator record.", + "defs": { + "main": { + "type": "object", + "required": ["record"], + "properties": { + "record": { "type": "ref", "ref": "com.atproto.repo.strongRef" } + } + }, + "view": { + "type": "object", + "required": ["record"], + "properties": { + "record": { + "type": "union", + "refs": [ + "#viewRecord", + "#viewNotFound", + "#viewBlocked", + "#viewDetached", + "app.bsky.feed.defs#generatorView", + "app.bsky.graph.defs#listView", + "app.bsky.labeler.defs#labelerView", + "app.bsky.graph.defs#starterPackViewBasic" + ] + } + } + }, + "viewRecord": { + "type": "object", + "required": ["uri", "cid", "author", "value", "indexedAt"], + "properties": { + "uri": { "type": "string", "format": "at-uri" }, + "cid": { "type": "string", "format": "cid" }, + "author": { + "type": "ref", + "ref": "app.bsky.actor.defs#profileViewBasic" + }, + "value": { + "type": "unknown", + "description": "The record data itself." + }, + "labels": { + "type": "array", + "items": { "type": "ref", "ref": "com.atproto.label.defs#label" } + }, + "replyCount": { "type": "integer" }, + "repostCount": { "type": "integer" }, + "likeCount": { "type": "integer" }, + "quoteCount": { "type": "integer" }, + "embeds": { + "type": "array", + "items": { + "type": "union", + "refs": [ + "app.bsky.embed.images#view", + "app.bsky.embed.video#view", + "app.bsky.embed.external#view", + "app.bsky.embed.record#view", + "app.bsky.embed.recordWithMedia#view" + ] + } + }, + "indexedAt": { "type": "string", "format": "datetime" } + } + }, + "viewNotFound": { + "type": "object", + "required": ["uri", "notFound"], + "properties": { + "uri": { "type": "string", "format": "at-uri" }, + "notFound": { "type": "boolean", "const": true } + } + }, + "viewBlocked": { + "type": "object", + "required": ["uri", "blocked", "author"], + "properties": { + "uri": { "type": "string", "format": "at-uri" }, + "blocked": { "type": "boolean", "const": true }, + "author": { "type": "ref", "ref": "app.bsky.feed.defs#blockedAuthor" } + } + }, + "viewDetached": { + "type": "object", + "required": ["uri", "detached"], + "properties": { + "uri": { "type": "string", "format": "at-uri" }, + "detached": { "type": "boolean", "const": true } + } + } + } +} diff --git a/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/recordWithMedia.json b/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/recordWithMedia.json new file mode 100644 index 00000000..5baf6850 --- /dev/null +++ b/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/recordWithMedia.json @@ -0,0 +1,43 @@ +{ + "lexicon": 1, + "id": "app.bsky.embed.recordWithMedia", + "description": "A representation of a record embedded in a Bluesky record (eg, a post), alongside other compatible embeds. For example, a quote post and image, or a quote post and external URL card.", + "defs": { + "main": { + "type": "object", + "required": ["record", "media"], + "properties": { + "record": { + "type": "ref", + "ref": "app.bsky.embed.record" + }, + "media": { + "type": "union", + "refs": [ + "app.bsky.embed.images", + "app.bsky.embed.video", + "app.bsky.embed.external" + ] + } + } + }, + "view": { + "type": "object", + "required": ["record", "media"], + "properties": { + "record": { + "type": "ref", + "ref": "app.bsky.embed.record#view" + }, + "media": { + "type": "union", + "refs": [ + "app.bsky.embed.images#view", + "app.bsky.embed.video#view", + "app.bsky.embed.external#view" + ] + } + } + } + } +} diff --git a/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/strongRef.json b/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/strongRef.json new file mode 100644 index 00000000..cb796251 --- /dev/null +++ b/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/strongRef.json @@ -0,0 +1,15 @@ +{ + "lexicon": 1, + "id": "com.atproto.repo.strongRef", + "description": "A URI with a content-hash fingerprint.", + "defs": { + "main": { + "type": "object", + "required": ["uri", "cid"], + "properties": { + "uri": { "type": "string", "format": "at-uri" }, + "cid": { "type": "string", "format": "cid" } + } + } + } +} diff --git a/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/subscribeRepos.json b/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/subscribeRepos.json new file mode 100644 index 00000000..23a95d83 --- /dev/null +++ b/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/subscribeRepos.json @@ -0,0 +1,126 @@ +{ + "lexicon": 1, + "id": "com.atproto.sync.subscribeRepos", + "defs": { + "main": { + "type": "subscription", + "description": "Subscribe to repository update stream", + "parameters": { + "type": "params", + "properties": { + "cursor": { + "type": "integer", + "description": "The last known event seq number" + } + } + }, + "message": { + "schema": { + "type": "union", + "refs": ["#commit", "#identity", "#account"] + } + } + }, + "commit": { + "type": "object", + "required": ["seq", "rebase", "tooBig", "repo", "commit", "rev", "since", "blocks", "ops", "blobs", "time"], + "properties": { + "seq": { + "type": "integer" + }, + "rebase": { + "type": "boolean" + }, + "tooBig": { + "type": "boolean" + }, + "repo": { + "type": "string", + "format": "did" + }, + "commit": { + "type": "cid-link" + }, + "rev": { + "type": "string" + }, + "since": { + "type": "string" + }, + "blocks": { + "type": "bytes" + }, + "ops": { + "type": "array", + "items": { + "type": "ref", + "ref": "#repoOp" + } + }, + "blobs": { + "type": "array", + "items": { + "type": "cid-link" + } + }, + "time": { + "type": "string", + "format": "datetime" + } + } + }, + "identity": { + "type": "object", + "required": ["seq", "did", "time"], + "properties": { + "seq": { + "type": "integer" + }, + "did": { + "type": "string", + "format": "did" + }, + "time": { + "type": "string", + "format": "datetime" + } + } + }, + "account": { + "type": "object", + "required": ["seq", "did", "time", "active"], + "properties": { + "seq": { + "type": "integer" + }, + "did": { + "type": "string", + "format": "did" + }, + "time": { + "type": "string", + "format": "datetime" + }, + "active": { + "type": "boolean" + } + } + }, + "repoOp": { + "type": "object", + "required": ["action", "path", "cid"], + "properties": { + "action": { + "type": "string", + "knownValues": ["create", "update", "delete"] + }, + "path": { + "type": "string" + }, + "cid": { + "type": "cid-link" + } + } + } + } +} diff --git a/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/token.json b/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/token.json new file mode 100644 index 00000000..f5ec248d --- /dev/null +++ b/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/token.json @@ -0,0 +1,56 @@ +{ + "lexicon": 1, + "id": "app.bsky.embed.images", + "defs": { + "main": { + "type": "object", + "required": ["images"], + "properties": { + "images": { + "type": "array", + "items": { + "type": "ref", + "ref": "#image" + }, + "maxLength": 4 + } + } + }, + "image": { + "type": "object", + "required": ["image", "alt"], + "properties": { + "image": { + "type": "blob", + "accept": ["image/png", "image/jpeg"], + "maxSize": 1000000 + }, + "alt": { + "type": "string", + "maxGraphemes": 10000 + }, + "aspectRatio": { + "type": "ref", + "ref": "#aspectRatio" + } + } + }, + "aspectRatio": { + "type": "object", + "required": ["width", "height"], + "properties": { + "width": { + "type": "integer", + "minimum": 1 + }, + "height": { + "type": "integer", + "minimum": 1 + } + } + }, + "viewImage": { + "type": "token" + } + } +} diff --git a/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/video.json b/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/video.json new file mode 100644 index 00000000..92511af1 --- /dev/null +++ b/crates/jacquard-codegen-tests/tests/fixtures/test_lexicons/video.json @@ -0,0 +1,67 @@ +{ + "lexicon": 1, + "id": "app.bsky.embed.video", + "description": "A video embedded in a Bluesky record (eg, a post).", + "defs": { + "main": { + "type": "object", + "required": ["video"], + "properties": { + "video": { + "type": "blob", + "description": "The mp4 video file. May be up to 100mb, formerly limited to 50mb.", + "accept": ["video/mp4"], + "maxSize": 100000000 + }, + "captions": { + "type": "array", + "items": { "type": "ref", "ref": "#caption" }, + "maxLength": 20 + }, + "alt": { + "type": "string", + "description": "Alt text description of the video, for accessibility.", + "maxGraphemes": 1000, + "maxLength": 10000 + }, + "aspectRatio": { + "type": "ref", + "ref": "app.bsky.embed.defs#aspectRatio" + } + } + }, + "caption": { + "type": "object", + "required": ["lang", "file"], + "properties": { + "lang": { + "type": "string", + "format": "language" + }, + "file": { + "type": "blob", + "accept": ["text/vtt"], + "maxSize": 20000 + } + } + }, + "view": { + "type": "object", + "required": ["cid", "playlist"], + "properties": { + "cid": { "type": "string", "format": "cid" }, + "playlist": { "type": "string", "format": "uri" }, + "thumbnail": { "type": "string", "format": "uri" }, + "alt": { + "type": "string", + "maxGraphemes": 1000, + "maxLength": 10000 + }, + "aspectRatio": { + "type": "ref", + "ref": "app.bsky.embed.defs#aspectRatio" + } + } + } + } +} diff --git a/crates/jacquard-lexicon/tests/roundtrip_post.rs b/crates/jacquard-codegen-tests/tests/roundtrip_post.rs similarity index 100% rename from crates/jacquard-lexicon/tests/roundtrip_post.rs rename to crates/jacquard-codegen-tests/tests/roundtrip_post.rs diff --git a/crates/jacquard-lexicon/tests/union_test.rs b/crates/jacquard-codegen-tests/tests/union_test.rs similarity index 100% rename from crates/jacquard-lexicon/tests/union_test.rs rename to crates/jacquard-codegen-tests/tests/union_test.rs diff --git a/crates/jacquard-common/Cargo.toml b/crates/jacquard-common/Cargo.toml index fdfe36e9..d0a5abe5 100644 --- a/crates/jacquard-common/Cargo.toml +++ b/crates/jacquard-common/Cargo.toml @@ -2,7 +2,7 @@ name = "jacquard-common" description = "Core AT Protocol types and utilities for Jacquard" edition.workspace = true -version = "0.12.0-beta.1" +version = "0.12.0-beta.2" authors.workspace = true repository.workspace = true keywords.workspace = true diff --git a/crates/jacquard-derive/Cargo.toml b/crates/jacquard-derive/Cargo.toml index 2c7812c4..47dba23b 100644 --- a/crates/jacquard-derive/Cargo.toml +++ b/crates/jacquard-derive/Cargo.toml @@ -16,15 +16,15 @@ proc-macro = true [dependencies] heck.workspace = true -jacquard-lexicon = { version = "0.12.0-beta.1", path = "../jacquard-lexicon", features = ["codegen"] } +jacquard-lexicon = { version = "0.12.0-beta.2", path = "../jacquard-lexicon", features = ["codegen"] } proc-macro2.workspace = true quote.workspace = true syn.workspace = true [dev-dependencies] inventory = "0.3" -jacquard-common = { version = "0.12.0-beta.1", path = "../jacquard-common" } -jacquard-lexicon = { version = "0.12.0-beta.1", path = "../jacquard-lexicon" } +jacquard-common = { version = "0.12.0-beta.2", path = "../jacquard-common" } +jacquard-lexicon = { version = "0.12.0-beta.2", path = "../jacquard-lexicon" } serde.workspace = true serde_json.workspace = true unicode-segmentation = "1.12" diff --git a/crates/jacquard-identity/Cargo.toml b/crates/jacquard-identity/Cargo.toml index 14a4d50f..27eafbe7 100644 --- a/crates/jacquard-identity/Cargo.toml +++ b/crates/jacquard-identity/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "jacquard-identity" edition.workspace = true -version = "0.12.0-beta.1" +version = "0.12.0-beta.2" authors.workspace = true repository.workspace = true keywords.workspace = true diff --git a/crates/jacquard-lexgen/Cargo.toml b/crates/jacquard-lexgen/Cargo.toml index d9754bf0..af9234be 100644 --- a/crates/jacquard-lexgen/Cargo.toml +++ b/crates/jacquard-lexgen/Cargo.toml @@ -2,7 +2,7 @@ name = "jacquard-lexgen" description = "Lexicon fetching and code generation binaries for Jacquard" edition.workspace = true -version = "0.12.0-beta.1" +version = "0.12.0-beta.2" authors.workspace = true repository.workspace = true keywords.workspace = true @@ -32,10 +32,10 @@ path = "../../examples/extract_inventory.rs" clap.workspace = true glob = "0.3" inventory = "0.3" -jacquard-common = { version = "0.12.0-beta.1", features = [ "reqwest-client" ], path = "../jacquard-common" } -jacquard-derive = { version = "0.12.0-beta.1", path = "../jacquard-derive" } -jacquard-identity = { version = "0.12.0-beta.1", path = "../jacquard-identity", features = ["dns"] } -jacquard-lexicon = { version = "0.12.0-beta.1", path = "../jacquard-lexicon" } +jacquard-common = { version = "0.12.0-beta.2", features = [ "reqwest-client" ], path = "../jacquard-common" } +jacquard-derive = { version = "0.12.0-beta.2", path = "../jacquard-derive" } +jacquard-identity = { version = "0.12.0-beta.2", path = "../jacquard-identity", features = ["dns"] } +jacquard-lexicon = { version = "0.12.0-beta.2", path = "../jacquard-lexicon" } kdl = "6" miette = { workspace = true, features = ["fancy"] } reqwest = { workspace = true, features = ["json", "http2", "system-proxy", "rustls-tls"] } diff --git a/crates/jacquard-lexicon/Cargo.toml b/crates/jacquard-lexicon/Cargo.toml index f2178810..ec4aa572 100644 --- a/crates/jacquard-lexicon/Cargo.toml +++ b/crates/jacquard-lexicon/Cargo.toml @@ -2,7 +2,7 @@ name = "jacquard-lexicon" description = "Lexicon schema parsing and code generation for Jacquard" edition.workspace = true -version = "0.12.0-beta.1" +version = "0.12.0-beta.2" authors.workspace = true repository.workspace = true keywords.workspace = true @@ -20,7 +20,7 @@ cid.workspace = true dashmap.workspace = true heck = { workspace = true, optional = true } inventory = "0.3" -jacquard-common = { version = "0.12.0-beta.1", path = "../jacquard-common" } +jacquard-common = { version = "0.12.0-beta.2", path = "../jacquard-common" } miette = { workspace = true } multihash.workspace = true prettyplease = { workspace = true, optional = true } @@ -39,5 +39,4 @@ unicode-segmentation = "1.12" [dev-dependencies] bytes = { workspace = true } -jacquard-derive = { version = "0.12.0-beta.1", path = "../jacquard-derive"} tempfile = { version = "3.23.0" } diff --git a/crates/jacquard-oauth/Cargo.toml b/crates/jacquard-oauth/Cargo.toml index b912793e..1fcbf657 100644 --- a/crates/jacquard-oauth/Cargo.toml +++ b/crates/jacquard-oauth/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "jacquard-oauth" -version = "0.12.0-beta.1" +version = "0.12.0-beta.2" edition.workspace = true description = "AT Protocol OAuth 2.1 core types and helpers for Jacquard" authors.workspace = true @@ -22,9 +22,9 @@ streaming = ["jacquard-common/streaming", "dep:n0-future"] scope-check = ["dep:jacquard-lexicon"] [dependencies] -jacquard-common = { version = "0.12.0-beta.1", path = "../jacquard-common", features = ["reqwest-client"] } -jacquard-identity = { version = "0.12.0-beta.1", path = "../jacquard-identity" } -jacquard-lexicon = { version = "0.12.0-beta.1", path = "../jacquard-lexicon", optional = true } +jacquard-common = { version = "0.12.0-beta.2", path = "../jacquard-common", features = ["reqwest-client"] } +jacquard-identity = { version = "0.12.0-beta.2", path = "../jacquard-identity" } +jacquard-lexicon = { version = "0.12.0-beta.2", path = "../jacquard-lexicon", optional = true } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } smol_str = { workspace = true } diff --git a/crates/jacquard-oauth/src/scopes.rs b/crates/jacquard-oauth/src/scopes.rs index ee77ad4c..738185ad 100644 --- a/crates/jacquard-oauth/src/scopes.rs +++ b/crates/jacquard-oauth/src/scopes.rs @@ -1,6 +1,6 @@ //! AT Protocol OAuth scopes //! -//! Derived from +//! Originally derived from , since substantially modified. //! //! This module provides comprehensive support for AT Protocol OAuth scopes, //! including parsing, serialization, normalization, and permission checking. @@ -36,7 +36,7 @@ use jacquard_common::{BorrowOrShare, Bos, FromStaticStr, IntoStatic}; use serde::de::{Error as DeError, Visitor}; use serde::{Deserialize, Serialize}; use smallvec::SmallVec; -use smol_str::{SmolStr, ToSmolStr, format_smolstr}; +use smol_str::{SmolStr, SmolStrBuilder, ToSmolStr, format_smolstr}; /// Represents an AT Protocol OAuth scope #[derive(Debug, Clone, PartialEq, Eq, Hash)] @@ -165,7 +165,7 @@ pub enum TransitionScope { /// Include scope referencing a permission set NSID with optional audience. /// /// Represents `include:[?aud=]` scopes. The audience is a plain -/// validated string — a DID optionally followed by `#fragment`. Stored in +/// validated string - a DID optionally followed by `#fragment`. Stored in /// decoded form; `#` is percent-encoded as `%23` on serialisation. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct IncludeScope { @@ -241,9 +241,9 @@ pub(crate) enum MimePatternKind { /// Validate a MIME pattern string without allocating. /// /// Returns the pattern kind. Valid patterns: -/// - `*/*` → `MimePatternKind::All` -/// - `/*` (e.g., `image/*`) → `MimePatternKind::TypeWildcard` -/// - `/` (e.g., `image/png`) → `MimePatternKind::Exact` +/// - `*/*` -> `MimePatternKind::All` +/// - `/*` (e.g., `image/*`) -> `MimePatternKind::TypeWildcard` +/// - `/` (e.g., `image/png`) -> `MimePatternKind::Exact` pub(crate) fn validate_mime_pattern(s: &str) -> Result { if s == "*/*" { Ok(MimePatternKind::All) @@ -251,7 +251,7 @@ pub(crate) fn validate_mime_pattern(s: &str) -> Result Result MimePattern { /// /// The caller must ensure `s` is a valid MIME pattern string /// and `kind` matches the pattern. `MimePattern`'s API assumes - /// the invariant holds — violating it will produce incorrect + /// the invariant holds. Violating it will produce incorrect /// results from downstream operations. pub(crate) unsafe fn unchecked(s: S, kind: MimePatternKind) -> Self { match kind { @@ -483,11 +483,6 @@ where } } -// ============================================================================ -// Scope index types — internal infrastructure for Phase 2's Scopes container. -// All types are pub(crate), consumed by the Scopes container. -// ============================================================================ - /// Byte-range indices for a single scope within a `Scopes` buffer. #[derive(Debug, Clone, PartialEq, Eq)] pub(crate) struct ScopeIndices { @@ -570,21 +565,14 @@ impl RepoActionFlags { #[derive(Debug, Clone, PartialEq, Eq)] pub(crate) enum IncludeAudience { /// Audience in buffer is already decoded (no percent-encoding). - /// `grants()` can compare directly. Serialisation must encode `#` → `%23`. + /// `grants()` can compare directly. Serialisation must encode `#` -> `%23`. Plain(u16, u16), /// Audience in buffer contains percent-encoding (e.g., `%23`). /// `grants()` must decode before comparing. Serialisation can pass through. Encoded(u16, u16), } -// ============================================================================ -// Scopes container — validated, zero-copy scope string with indices. -// ============================================================================ - /// Iterator over scopes in a `Scopes` container. -/// -/// Yields `Scope<&'o str>` views that borrow from the shared buffer. -/// This type is returned by `Scopes::iter()`. pub struct ScopesIter<'i, 'o> { buffer: &'o str, indices: std::slice::Iter<'i, ScopeIndices>, @@ -647,7 +635,7 @@ impl + AsRef> Scopes { // Check u16 limit on buffer length. if s.len() > u16::MAX as usize { return Err(ParseError::InvalidResource( - "scope string exceeds u16 byte limit".to_string(), + "scope string exceeds u16 byte limit".to_smolstr(), )); } @@ -686,10 +674,6 @@ impl + AsRef> Scopes { } /// Iterate over scopes as `Scope<&'o str>` views borrowing from the buffer. - /// - /// The iterator borrows from the buffer via the `BorrowOrShare` split lifetimes. - /// For example, when `S = &'a str`, the iterator yields `Scope<&'a str>` and - /// can outlive the borrow of `self`. pub fn iter<'i, 'o>(&'i self) -> ScopesIter<'i, 'o> where S: BorrowOrShare<'i, 'o, str>, @@ -732,9 +716,6 @@ impl + AsRef> Scopes { } /// Borrow as `Scopes<&str>`. - /// - /// Indices are cloned (they're small, no heap strings). The buffer - /// is borrowed via `AsRef`. pub fn borrow(&self) -> Scopes<&str> { Scopes { buffer: self.buffer.as_ref(), @@ -743,9 +724,6 @@ impl + AsRef> Scopes { } /// Convert to `Scopes` with a different backing type. - /// - /// Indices are moved (no clone). The buffer is converted via `From`. - /// Byte offsets remain valid because the buffer content is identical. pub fn convert + AsRef + From>(self) -> Scopes { Scopes { buffer: B::from(self.buffer), @@ -754,9 +732,6 @@ impl + AsRef> Scopes { } /// Produce the sorted, normalized space-separated scope string. - /// - /// Same output as `Serialize`, but returns `SmolStr` directly - /// without going through a serializer. pub fn to_normalized_string(&self) -> SmolStr { if self.indices.is_empty() { return SmolStr::default(); @@ -772,22 +747,14 @@ impl + AsRef> Scopes { .collect(); normalized.sort(); - // Compute total length for pre-allocation. - let total_len = normalized.iter().map(|s| s.len()).sum::() - + if normalized.len() > 1 { - normalized.len() - 1 - } else { - 0 - }; // Add length for space separators. - - let mut result = String::with_capacity(total_len); + let mut result = SmolStrBuilder::new(); for (i, s) in normalized.iter().enumerate() { if i > 0 { result.push(' '); } result.push_str(s); } - result.to_smolstr() + result.finish() } /// Check if the container has a scope that grants the given scope. @@ -837,11 +804,17 @@ impl Scopes { } } -impl + AsRef + Default> Default for Scopes { +impl + AsRef + Default + FromStaticStr> Default for Scopes { fn default() -> Self { + let buffer = S::from_static("atproto"); + let end = (buffer.as_ref().len() - 1) as u16; Scopes { - buffer: S::default(), - indices: Vec::new(), + buffer, + indices: vec![ScopeIndices { + start: 0, + end, + inner: ScopeInnerIndices::Unit(ScopeKind::Atproto), + }], } } } @@ -901,7 +874,7 @@ fn parse_scope_indices(token: &str, base: u16) -> Result Result parse_openid_indices(suffix), "profile" => parse_profile_indices(suffix), "email" => parse_email_indices(suffix), - _ => Err(ParseError::UnknownPrefix(prefix.to_string())), + _ => Err(ParseError::UnknownPrefix(prefix.to_smolstr())), } } @@ -937,7 +910,7 @@ fn parse_account_indices(suffix: Option<&str>) -> Result AccountResource::Email, "repo" => AccountResource::Repo, "status" => AccountResource::Status, - _ => return Err(ParseError::InvalidResource(resource_str.to_string())), + _ => return Err(ParseError::InvalidResource(resource_str.to_smolstr())), }; let action = if let Some(params) = params { @@ -949,7 +922,7 @@ fn parse_account_indices(suffix: Option<&str>) -> Result AccountAction::Read, Some("manage") => AccountAction::Manage, - Some(other) => return Err(ParseError::InvalidAction(other.to_string())), + Some(other) => return Err(ParseError::InvalidAction(other.to_smolstr())), None => AccountAction::Read, } } else { @@ -964,7 +937,7 @@ fn parse_identity_indices(suffix: Option<&str>) -> Result IdentityScope::Handle, Some("*") => IdentityScope::All, - Some(other) => return Err(ParseError::InvalidResource(other.to_string())), + Some(other) => return Err(ParseError::InvalidResource(other.to_smolstr())), None => return Err(ParseError::MissingResource), }; @@ -977,7 +950,7 @@ fn parse_transition_indices(suffix: Option<&str>) -> Result TransitionScope::Generic, Some("email") => TransitionScope::Email, Some("chat.bsky") => TransitionScope::ChatBsky, - Some(other) => return Err(ParseError::InvalidResource(other.to_string())), + Some(other) => return Err(ParseError::InvalidResource(other.to_smolstr())), None => return Err(ParseError::MissingResource), }; @@ -988,7 +961,7 @@ fn parse_transition_indices(suffix: Option<&str>) -> Result) -> Result { if suffix.is_some() { return Err(ParseError::InvalidResource( - "atproto scope does not accept suffixes".to_string(), + "atproto scope does not accept suffixes".to_smolstr(), )); } Ok(ScopeInnerIndices::Unit(ScopeKind::Atproto)) @@ -998,7 +971,7 @@ fn parse_atproto_indices(suffix: Option<&str>) -> Result) -> Result { if suffix.is_some() { return Err(ParseError::InvalidResource( - "openid scope does not accept suffixes".to_string(), + "openid scope does not accept suffixes".to_smolstr(), )); } Ok(ScopeInnerIndices::Unit(ScopeKind::OpenId)) @@ -1008,7 +981,7 @@ fn parse_openid_indices(suffix: Option<&str>) -> Result) -> Result { if suffix.is_some() { return Err(ParseError::InvalidResource( - "profile scope does not accept suffixes".to_string(), + "profile scope does not accept suffixes".to_smolstr(), )); } Ok(ScopeInnerIndices::Unit(ScopeKind::Profile)) @@ -1018,7 +991,7 @@ fn parse_profile_indices(suffix: Option<&str>) -> Result) -> Result { if suffix.is_some() { return Err(ParseError::InvalidResource( - "email scope does not accept suffixes".to_string(), + "email scope does not accept suffixes".to_smolstr(), )); } Ok(ScopeInnerIndices::Unit(ScopeKind::Email)) @@ -1091,7 +1064,7 @@ fn parse_repo_indices( let end = start + nsid_str.len() as u16; Some((start, end)) } else { - return Err(ParseError::InvalidResource(nsid_str.to_string())); + return Err(ParseError::InvalidResource(nsid_str.to_smolstr())); } } }; @@ -1108,7 +1081,7 @@ fn parse_repo_indices( "update" => flags |= RepoActionFlags::UPDATE, "delete" => flags |= RepoActionFlags::DELETE, "*" => flags = RepoActionFlags::ALL, - other => return Err(ParseError::InvalidAction(other.to_string())), + other => return Err(ParseError::InvalidAction(other.to_smolstr())), } } actions = RepoActionFlags(flags); @@ -1252,7 +1225,7 @@ fn parse_include_indices( // Find the NSID's byte position in the token. let nsid_pos = token .find(nsid_str) - .ok_or_else(|| ParseError::InvalidResource(nsid_str.to_string()))?; + .ok_or_else(|| ParseError::InvalidResource(nsid_str.to_smolstr()))?; let nsid_start = base + nsid_pos as u16; let nsid_end = nsid_start + nsid_str.len() as u16; @@ -1267,13 +1240,13 @@ fn parse_include_indices( // Validate and decode the percent-encoded value using fluent-uri. let estr = EStr::::new(aud_value).ok_or_else(|| { ParseError::InvalidResource( - "include audience has invalid percent-encoding".to_string(), + "include audience has invalid percent-encoding".to_smolstr(), ) })?; let decoded = estr.decode().to_string().map_err(|_| { ParseError::InvalidResource( - "include audience contains invalid UTF-8 sequence".to_string(), + "include audience contains invalid UTF-8 sequence".to_smolstr(), ) })?; @@ -1284,7 +1257,7 @@ fn parse_include_indices( let frag = decoded.split('#').nth(1).unwrap_or(""); if frag.is_empty() { return Err(ParseError::InvalidResource( - "include audience fragment cannot be empty".to_string(), + "include audience fragment cannot be empty".to_smolstr(), )); } } @@ -1296,7 +1269,7 @@ fn parse_include_indices( let frag = aud_value.split('#').nth(1).unwrap_or(""); if frag.is_empty() { return Err(ParseError::InvalidResource( - "include audience fragment cannot be empty".to_string(), + "include audience fragment cannot be empty".to_smolstr(), )); } } @@ -1305,7 +1278,7 @@ fn parse_include_indices( // Find the audience's byte position in the token. let aud_pos = token .find(aud_value) - .ok_or_else(|| ParseError::InvalidResource(aud_value.to_string()))?; + .ok_or_else(|| ParseError::InvalidResource(aud_value.to_smolstr()))?; let aud_start = base + aud_pos as u16; let aud_end = aud_start + aud_value.len() as u16; @@ -1612,7 +1585,7 @@ impl Scope { let prefix = found_prefix.ok_or_else(|| { // If no known prefix found, extract what looks like a prefix for error reporting let end = s.find(':').or_else(|| s.find('?')).unwrap_or(s.len()); - ParseError::UnknownPrefix(s[..end].to_string()) + ParseError::UnknownPrefix(s[..end].to_smolstr()) })?; match prefix { @@ -1626,7 +1599,7 @@ impl Scope { "openid" => Self::parse_openid(suffix), "profile" => Self::parse_profile(suffix), "email" => Self::parse_email(suffix), - _ => Err(ParseError::UnknownPrefix(prefix.to_string())), + _ => Err(ParseError::UnknownPrefix(prefix.to_smolstr())), } } @@ -1646,7 +1619,7 @@ impl Scope { "email" => AccountResource::Email, "repo" => AccountResource::Repo, "status" => AccountResource::Status, - _ => return Err(ParseError::InvalidResource(resource_str.to_string())), + _ => return Err(ParseError::InvalidResource(resource_str.to_smolstr())), }; let action = if let Some(params) = params { @@ -1658,7 +1631,7 @@ impl Scope { { Some("read") => AccountAction::Read, Some("manage") => AccountAction::Manage, - Some(other) => return Err(ParseError::InvalidAction(other.to_string())), + Some(other) => return Err(ParseError::InvalidAction(other.to_smolstr())), None => AccountAction::Read, } } else { @@ -1672,7 +1645,7 @@ impl Scope { let scope = match suffix { Some("handle") => IdentityScope::Handle, Some("*") => IdentityScope::All, - Some(other) => return Err(ParseError::InvalidResource(other.to_string())), + Some(other) => return Err(ParseError::InvalidResource(other.to_smolstr())), None => return Err(ParseError::MissingResource), }; @@ -1750,7 +1723,7 @@ impl Scope { actions.insert(RepoAction::Update); actions.insert(RepoAction::Delete); } - other => return Err(ParseError::InvalidAction(other.to_string())), + other => return Err(ParseError::InvalidAction(other.to_smolstr())), } } } @@ -1840,7 +1813,7 @@ impl Scope { fn parse_atproto(suffix: Option<&str>) -> Result { if suffix.is_some() { return Err(ParseError::InvalidResource( - "atproto scope does not accept suffixes".to_string(), + "atproto scope does not accept suffixes".to_smolstr(), )); } Ok(Scope::Atproto) @@ -1851,7 +1824,7 @@ impl Scope { Some("generic") => TransitionScope::Generic, Some("email") => TransitionScope::Email, Some("chat.bsky") => TransitionScope::ChatBsky, - Some(other) => return Err(ParseError::InvalidResource(other.to_string())), + Some(other) => return Err(ParseError::InvalidResource(other.to_smolstr())), None => return Err(ParseError::MissingResource), }; @@ -1861,7 +1834,7 @@ impl Scope { fn parse_openid(suffix: Option<&str>) -> Result { if suffix.is_some() { return Err(ParseError::InvalidResource( - "openid scope does not accept suffixes".to_string(), + "openid scope does not accept suffixes".to_smolstr(), )); } Ok(Scope::OpenId) @@ -1870,7 +1843,7 @@ impl Scope { fn parse_profile(suffix: Option<&str>) -> Result { if suffix.is_some() { return Err(ParseError::InvalidResource( - "profile scope does not accept suffixes".to_string(), + "profile scope does not accept suffixes".to_smolstr(), )); } Ok(Scope::Profile) @@ -1879,7 +1852,7 @@ impl Scope { fn parse_email(suffix: Option<&str>) -> Result { if suffix.is_some() { return Err(ParseError::InvalidResource( - "email scope does not accept suffixes".to_string(), + "email scope does not accept suffixes".to_smolstr(), )); } Ok(Scope::Email) @@ -2029,7 +2002,7 @@ impl Scope { /// Check if this scope grants the permissions of another scope pub fn grants(&self, other: &Scope) -> bool { match (self, other) { - // Atproto only grants itself (it's a required scope, not a permission grant) + // Atproto only grants itself (Scope::Atproto, Scope::Atproto) => true, (Scope::Atproto, _) => false, // Nothing else grants atproto @@ -2090,7 +2063,6 @@ impl Scope { let collection_match = match (&a.collection, &b.collection) { (RepoCollection::All, _) => true, (RepoCollection::Nsid(a_nsid), RepoCollection::Nsid(b_nsid)) => { - // Compare as strings to support cross-type-parameter equality. a_nsid.as_ref() == b_nsid.as_ref() } _ => false, @@ -2108,7 +2080,6 @@ impl Scope { } else { b.lxm.iter().all(|b_lxm| match b_lxm { RpcLexicon::All => false, - // Compare as strings to support cross-type-parameter equality. RpcLexicon::Nsid(b_nsid) => a.lxm.iter().any(|a_lxm| match a_lxm { RpcLexicon::All => false, RpcLexicon::Nsid(a_nsid) => a_nsid.as_ref() == b_nsid.as_ref(), @@ -2121,7 +2092,6 @@ impl Scope { } else { b.aud.iter().all(|b_aud| match b_aud { RpcAudience::All => false, - // Compare as strings to support cross-type-parameter equality. RpcAudience::Did(b_did) => a.aud.iter().any(|a_aud| match a_aud { RpcAudience::All => false, RpcAudience::Did(a_did) => a_did.as_ref() == b_did.as_ref(), @@ -2146,7 +2116,7 @@ impl MimePattern { } (MimePattern::TypeWildcard(a_type), MimePattern::Exact(b_mime)) => b_mime .as_ref() - .starts_with(&format!("{}/", a_type.as_ref())), + .starts_with(format_smolstr!("{}/", a_type.as_ref()).as_str()), (MimePattern::Exact(a), MimePattern::Exact(b)) => a.as_ref() == b.as_ref(), _ => false, } @@ -2167,7 +2137,7 @@ where } else if s.contains('/') { Ok(MimePattern::Exact(S::from_str(s).unwrap())) } else { - Err(ParseError::InvalidMimeType(s.to_string())) + Err(ParseError::InvalidMimeType(s.to_smolstr())) } } } @@ -2183,7 +2153,7 @@ impl<'a, S: BosStr + From<&'a str>> TryFrom<&'a str> for MimePattern { } else if s.contains('/') { Ok(MimePattern::Exact(S::from(s))) } else { - Err(ParseError::InvalidMimeType(s.to_string())) + Err(ParseError::InvalidMimeType(s.to_smolstr())) } } } @@ -2218,15 +2188,15 @@ fn parse_query_string(query: &str) -> BTreeMap> { pub enum PermissionSetConversionError { /// Unknown identity attribute in permission set #[error("unknown identity attribute: {0}")] - UnknownIdentityAttr(String), + UnknownIdentityAttr(SmolStr), /// Unknown account attribute in permission set #[error("unknown account attribute: {0}")] - UnknownAccountAttr(String), + UnknownAccountAttr(SmolStr), /// Invalid MIME pattern in blob permission #[error("invalid MIME pattern: {0}")] - InvalidMimePattern(String), + InvalidMimePattern(SmolStr), } /// Error type for scope parsing @@ -2234,15 +2204,15 @@ pub enum PermissionSetConversionError { #[non_exhaustive] pub enum ParseError { /// Unknown scope prefix - UnknownPrefix(String), + UnknownPrefix(SmolStr), /// Missing required resource MissingResource, /// Invalid resource type - InvalidResource(String), + InvalidResource(SmolStr), /// Invalid action type - InvalidAction(String), + InvalidAction(SmolStr), /// Invalid MIME type - InvalidMimeType(String), + InvalidMimeType(SmolStr), /// An AT Protocol string type (DID, NSID, etc.) failed validation during scope parsing. ParseError(#[from] AtStrError), } @@ -2347,7 +2317,7 @@ pub fn expand_permission_set( } Err(_) => { return Err(PermissionSetConversionError::InvalidMimePattern( - pattern_str.to_string(), + pattern_str.to_smolstr(), )); } } @@ -2363,7 +2333,7 @@ pub fn expand_permission_set( "*" => IdentityScope::All, other => { return Err(PermissionSetConversionError::UnknownIdentityAttr( - other.to_string(), + other.to_smolstr(), )); } }; @@ -2376,7 +2346,7 @@ pub fn expand_permission_set( "status" => AccountResource::Status, other => { return Err(PermissionSetConversionError::UnknownAccountAttr( - other.to_string(), + other.to_smolstr(), )); } }; @@ -3676,9 +3646,10 @@ mod tests { #[test] fn test_scopes_default() { // Test Default trait for Scopes. + // should return atproto scope let default: Scopes = Default::default(); - assert_eq!(default.len(), 0); - assert!(default.is_empty()); + assert_eq!(default.buffer.as_str(), "atproto"); + assert!(matches!(default.get(0), Some(Scope::Atproto))); } #[test] diff --git a/crates/jacquard-repo/Cargo.toml b/crates/jacquard-repo/Cargo.toml index f70dec82..1a8a2e8a 100644 --- a/crates/jacquard-repo/Cargo.toml +++ b/crates/jacquard-repo/Cargo.toml @@ -2,7 +2,7 @@ name = "jacquard-repo" description = "AT Protocol repository primitives: MST, commits, CAR I/O" edition.workspace = true -version = "0.12.0-beta.1" +version = "0.12.0-beta.2" authors.workspace = true repository.workspace = true keywords.workspace = true