Something went wrong. Try again.
atproto made easy crates.io/crates/jacquard
atproto rust
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516// @generated by jacquard-lexicon. DO NOT EDIT.//// Lexicon: dev.atfs.file//// 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, CowStr, DefaultStr, FromStaticStr};
#[allow(unused_imports)]use jacquard_common::deps::codegen::unicode_segmentation::UnicodeSegmentation;use jacquard_common::deps::smol_str::SmolStr;use jacquard_common::types::cid::CidLink;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::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, IntoStatic)]#[serde( rename_all = "camelCase", bound(deserialize = "S: Deserialize<'de> + BosStr"))]pub struct File<S: BosStr = DefaultStr> { /// The blessed CID of the file's bytes (CIDv1, raw multicodec, sha-256 multihash) — the canonical identity. This is what dev.atfs.repo.uploadFile (and its com.atproto.repo.uploadBlob alias) returns, what equality/dedup use, what atfs's own HTTP surfaces serve at any size, and the only DASL-compatible form. Never a DAG root. pub cid: CidLink<S>, /// The CID to fetch this file over the IPFS network: the UnixFS root for chunked (large) files, or exactly equal to `cid` when the file fits a single block. Always present, even when equal to `cid`, so consumers never need conditional logic — fetch `ipfsRoot`, then verify the bytes against `cid`. Chunker-dependent: this is *a* valid way to fetch the bytes, not a second identity — re-adding the same bytes elsewhere with different chunk settings would yield a different, equally valid root. pub ipfs_root: CidLink<S>, /// The IANA media type of the file's bytes, exactly as recorded at upload time (see dev.atfs.repo.uploadFile). Defaults to application/octet-stream when the uploader supplied no Content-Type. pub mime_type: S, /// Advisory HTTPS origins (not full URLs — each is expected to answer both /ipfs/<cid> and a dev.atfs.repo.getFile-style XRPC, with the rest supplied by the author's DID), ordered by preference with the uploader's own instance first. Never required for correctness: a full IPFS client can always fall back to DHT routing. HTTPS is meant literally — an atfs instance asked to pin this file skips any origin naming another scheme, and any origin resolving to an address that isn't routable on the public internet, since a providers list is a stranger's instruction about where to make connections. #[serde(skip_serializing_if = "Option::is_none")] pub providers: Option<Vec<UriValue<S>>>, /// Size of the file, in bytes. pub size: i64, /// Free-form labels attached to this content, deduplicated and sorted. Advisory and instance-local, in the same register as `providers`: never part of the file's identity (two identical uploads to two different instances, or under two different accounts, can carry entirely different tags for the same cid), never required for correctness, and not something a `dev.atfs.file` reference's recipient should trust as a global fact about the content — only as a note from whoever produced this reference. In dev.atfs.repo.listFiles output this is a union: every tag borne by ANY of that file's claims here — account-class and mirrored-server claims alike — with no indication of which claimant applied which; listFiles never discloses who pinned or tagged anything (pass listFiles' `did` parameter to scope this to one claimant's own tags instead). dev.atfs.repo.pinFile reads this field on input and adopts it verbatim under the calling instance's own claim (see dev.atfs.repo.pinFile). #[serde(skip_serializing_if = "Option::is_none")] pub tags: Option<Vec<S>>, #[serde( flatten, default, deserialize_with = "deserialize_file_extra_data", skip_serializing_if = "Option::is_none" )] pub extra_data: Option<BTreeMap<SmolStr, Data<S>>>,}
impl<S: BosStr> LexiconSchema for File<S> { fn nsid() -> &'static str { "dev.atfs.file" } fn def_name() -> &'static str { "main" } fn lexicon_doc() -> LexiconDoc<'static> { lexicon_doc_dev_atfs_file() } fn validate(&self) -> Result<(), ConstraintError> { if let Some(ref value) = self.providers { #[allow(unused_comparisons)] if value.len() > 16usize { return Err(ConstraintError::MaxLength { path: ValidationPath::from_field("providers"), max: 16usize, actual: value.len(), }); } } if let Some(ref value) = self.providers { #[allow(unused_comparisons)] if value.len() < 1usize { return Err(ConstraintError::MinLength { path: ValidationPath::from_field("providers"), min: 1usize, actual: value.len(), }); } } if let Some(ref value) = self.tags { #[allow(unused_comparisons)] if value.len() > 16usize { return Err(ConstraintError::MaxLength { path: ValidationPath::from_field("tags"), max: 16usize, actual: value.len(), }); } } if let Some(ref value) = self.tags { #[allow(unused_comparisons)] if value.len() < 1usize { return Err(ConstraintError::MinLength { path: ValidationPath::from_field("tags"), min: 1usize, actual: value.len(), }); } } if let Some(values) = &self.tags { for value in values { #[allow(unused_comparisons)] if <str>::len(value.as_ref()) > 128usize { return Err(ConstraintError::MaxLength { path: ValidationPath::from_field("tags"), max: 128usize, actual: <str>::len(value.as_ref()), }); } } } if let Some(values) = &self.tags { for value in values { #[allow(unused_comparisons)] if <str>::len(value.as_ref()) < 1usize { return Err(ConstraintError::MinLength { path: ValidationPath::from_field("tags"), min: 1usize, actual: <str>::len(value.as_ref()), }); } } } if let Some(values) = &self.tags { for value in values { { let count = UnicodeSegmentation::graphemes(value.as_ref(), true).count(); if count > 128usize { return Err(ConstraintError::MaxGraphemes { path: ValidationPath::from_field("tags"), max: 128usize, actual: count, }); } } } } Ok(()) }}
fn deserialize_file_extra_data<'de, S, D>( deserializer: D,) -> Result<Option<BTreeMap<SmolStr, Data<S>>>, D::Error>where S: BosStr + serde::Deserialize<'de>, D: serde::Deserializer<'de>,{ let data = <Option<BTreeMap<SmolStr, Data<S>>> as serde::Deserialize<'de>>::deserialize(deserializer)?; Ok(data.filter(|extra_data| !extra_data.is_empty()))}
pub mod file_state {
pub use crate::builder_types::{IsSet, IsUnset, Set, Unset}; #[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 IpfsRoot; type MimeType; type Size; } /// Empty state - all required fields are unset pub struct Empty(()); impl sealed::Sealed for Empty {} impl State for Empty { type Cid = Unset; type IpfsRoot = Unset; type MimeType = Unset; type Size = Unset; } ///State transition - sets the `cid` field to Set pub struct SetCid<St: State = Empty>(PhantomData<fn() -> St>); impl<St: State> sealed::Sealed for SetCid<St> {} impl<St: State> State for SetCid<St> { type Cid = Set<members::cid>; type IpfsRoot = St::IpfsRoot; type MimeType = St::MimeType; type Size = St::Size; } ///State transition - sets the `ipfs_root` field to Set pub struct SetIpfsRoot<St: State = Empty>(PhantomData<fn() -> St>); impl<St: State> sealed::Sealed for SetIpfsRoot<St> {} impl<St: State> State for SetIpfsRoot<St> { type Cid = St::Cid; type IpfsRoot = Set<members::ipfs_root>; type MimeType = St::MimeType; type Size = St::Size; } ///State transition - sets the `mime_type` field to Set pub struct SetMimeType<St: State = Empty>(PhantomData<fn() -> St>); impl<St: State> sealed::Sealed for SetMimeType<St> {} impl<St: State> State for SetMimeType<St> { type Cid = St::Cid; type IpfsRoot = St::IpfsRoot; type MimeType = Set<members::mime_type>; type Size = St::Size; } ///State transition - sets the `size` field to Set pub struct SetSize<St: State = Empty>(PhantomData<fn() -> St>); impl<St: State> sealed::Sealed for SetSize<St> {} impl<St: State> State for SetSize<St> { type Cid = St::Cid; type IpfsRoot = St::IpfsRoot; type MimeType = St::MimeType; type Size = Set<members::size>; } /// 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 `ipfs_root` field pub struct ipfs_root(()); ///Marker type for the `mime_type` field pub struct mime_type(()); ///Marker type for the `size` field pub struct size(()); }}
/// Builder for constructing an instance of this type.pub struct FileBuilder<St: file_state::State, S: BosStr = DefaultStr> { _state: PhantomData<fn() -> St>, _fields: ( Option<CidLink<S>>, Option<CidLink<S>>, Option<S>, Option<Vec<UriValue<S>>>, Option<i64>, Option<Vec<S>>, ), _type: PhantomData<fn() -> S>,}
impl File<DefaultStr> { /// Create a new builder for this type, using the default string type (DefaultStr = SmolStr) if needed pub fn new() -> FileBuilder<file_state::Empty, DefaultStr> { FileBuilder::new() }}
impl<S: BosStr> File<S> { /// Create a new builder for this type pub fn builder() -> FileBuilder<file_state::Empty, S> { FileBuilder::builder() }}
impl FileBuilder<file_state::Empty, DefaultStr> { /// Create a new builder with all fields unset, using the default string type, if needed pub fn new() -> Self { FileBuilder { _state: PhantomData, _fields: (None, None, None, None, None, None), _type: PhantomData, } }}
impl<S: BosStr> FileBuilder<file_state::Empty, S> { /// Create a new builder with all fields unset pub fn builder() -> Self { FileBuilder { _state: PhantomData, _fields: (None, None, None, None, None, None), _type: PhantomData, } }}
impl<St, S: BosStr> FileBuilder<St, S>where St: file_state::State, St::Cid: file_state::IsUnset,{ /// Set the `cid` field (required) pub fn cid(mut self, value: impl Into<CidLink<S>>) -> FileBuilder<file_state::SetCid<St>, S> { self._fields.0 = Option::Some(value.into()); FileBuilder { _state: PhantomData, _fields: self._fields, _type: PhantomData, } }}
impl<St, S: BosStr> FileBuilder<St, S>where St: file_state::State, St::IpfsRoot: file_state::IsUnset,{ /// Set the `ipfsRoot` field (required) pub fn ipfs_root( mut self, value: impl Into<CidLink<S>>, ) -> FileBuilder<file_state::SetIpfsRoot<St>, S> { self._fields.1 = Option::Some(value.into()); FileBuilder { _state: PhantomData, _fields: self._fields, _type: PhantomData, } }}
impl<St, S: BosStr> FileBuilder<St, S>where St: file_state::State, St::MimeType: file_state::IsUnset,{ /// Set the `mimeType` field (required) pub fn mime_type(mut self, value: impl Into<S>) -> FileBuilder<file_state::SetMimeType<St>, S> { self._fields.2 = Option::Some(value.into()); FileBuilder { _state: PhantomData, _fields: self._fields, _type: PhantomData, } }}
impl<St: file_state::State, S: BosStr> FileBuilder<St, S> { /// Set the `providers` field (optional) pub fn providers(mut self, value: impl Into<Option<Vec<UriValue<S>>>>) -> Self { self._fields.3 = value.into(); self } /// Set the `providers` field to an Option value (optional) pub fn maybe_providers(mut self, value: Option<Vec<UriValue<S>>>) -> Self { self._fields.3 = value; self }}
impl<St, S: BosStr> FileBuilder<St, S>where St: file_state::State, St::Size: file_state::IsUnset,{ /// Set the `size` field (required) pub fn size(mut self, value: impl Into<i64>) -> FileBuilder<file_state::SetSize<St>, S> { self._fields.4 = Option::Some(value.into()); FileBuilder { _state: PhantomData, _fields: self._fields, _type: PhantomData, } }}
impl<St: file_state::State, S: BosStr> FileBuilder<St, S> { /// Set the `tags` field (optional) pub fn tags(mut self, value: impl Into<Option<Vec<S>>>) -> Self { self._fields.5 = value.into(); self } /// Set the `tags` field to an Option value (optional) pub fn maybe_tags(mut self, value: Option<Vec<S>>) -> Self { self._fields.5 = value; self }}
impl<St, S: BosStr> FileBuilder<St, S>where St: file_state::State, St::Cid: file_state::IsSet, St::IpfsRoot: file_state::IsSet, St::MimeType: file_state::IsSet, St::Size: file_state::IsSet,{ /// Build the final struct. pub fn build(self) -> File<S> { File { cid: self._fields.0.unwrap(), ipfs_root: self._fields.1.unwrap(), mime_type: self._fields.2.unwrap(), providers: self._fields.3, size: self._fields.4.unwrap(), tags: self._fields.5, extra_data: Default::default(), } } /// Build the final struct with custom extra_data. pub fn build_with_data(self, extra_data: BTreeMap<SmolStr, Data<S>>) -> File<S> { File { cid: self._fields.0.unwrap(), ipfs_root: self._fields.1.unwrap(), mime_type: self._fields.2.unwrap(), providers: self._fields.3, size: self._fields.4.unwrap(), tags: self._fields.5, extra_data: Some(extra_data), } }}
fn lexicon_doc_dev_atfs_file() -> LexiconDoc<'static> { use alloc::collections::BTreeMap; #[allow(unused_imports)] use jacquard_common::{CowStr, deps::smol_str::SmolStr, types::blob::MimeType}; use jacquard_lexicon::lexicon::*; LexiconDoc { lexicon: Lexicon::Lexicon1, id: CowStr::new_static("dev.atfs.file"), defs: { let mut map = BTreeMap::new(); map.insert( SmolStr::new_static("main"), LexUserType::Object(LexObject { required: Some( vec![ SmolStr::new_static("cid"), SmolStr::new_static("ipfsRoot"), SmolStr::new_static("size"), SmolStr::new_static("mimeType") ], ), properties: { #[allow(unused_mut)] let mut map = BTreeMap::new(); map.insert( SmolStr::new_static("cid"), LexObjectProperty::CidLink(LexCidLink { ..Default::default() }), ); map.insert( SmolStr::new_static("ipfsRoot"), LexObjectProperty::CidLink(LexCidLink { ..Default::default() }), ); map.insert( SmolStr::new_static("mimeType"), LexObjectProperty::String(LexString { description: Some( CowStr::new_static( "The IANA media type of the file's bytes, exactly as recorded at upload time (see dev.atfs.repo.uploadFile). Defaults to application/octet-stream when the uploader supplied no Content-Type.", ), ), ..Default::default() }), ); map.insert( SmolStr::new_static("providers"), LexObjectProperty::Array(LexArray { description: Some( CowStr::new_static( "Advisory HTTPS origins (not full URLs — each is expected to answer both /ipfs/<cid> and a dev.atfs.repo.getFile-style XRPC, with the rest supplied by the author's DID), ordered by preference with the uploader's own instance first. Never required for correctness: a full IPFS client can always fall back to DHT routing. HTTPS is meant literally — an atfs instance asked to pin this file skips any origin naming another scheme, and any origin resolving to an address that isn't routable on the public internet, since a providers list is a stranger's instruction about where to make connections.", ), ), items: LexArrayItem::String(LexString { format: Some(LexStringFormat::Uri), ..Default::default() }), min_length: Some(1usize), max_length: Some(16usize), ..Default::default() }), ); map.insert( SmolStr::new_static("size"), LexObjectProperty::Integer(LexInteger { ..Default::default() }), ); map.insert( SmolStr::new_static("tags"), LexObjectProperty::Array(LexArray { description: Some( CowStr::new_static( "Free-form labels attached to this content, deduplicated and sorted. Advisory and instance-local, in the same register as `providers`: never part of the file's identity (two identical uploads to two different instances, or under two different accounts, can carry entirely different tags for the same cid), never required for correctness, and not something a `dev.atfs.file` reference's recipient should trust as a global fact about the content — only as a note from whoever produced this reference. In dev.atfs.repo.listFiles output this is a union: every tag borne by ANY of that file's claims here — account-class and mirrored-server claims alike — with no indication of which claimant applied which; listFiles never discloses who pinned or tagged anything (pass listFiles' `did` parameter to scope this to one claimant's own tags instead). dev.atfs.repo.pinFile reads this field on input and adopts it verbatim under the calling instance's own claim (see dev.atfs.repo.pinFile).", ), ), items: LexArrayItem::String(LexString { description: Some( CowStr::new_static( "A single free-form tag: 1-128 bytes, no control characters. maxGraphemes is the same 128 rather than a smaller, byte-aware figure, because the bound atfs actually enforces is bytes, not graphemes — a tighter maxGraphemes here would advertise a stricter limit than the server applies.", ), ), min_length: Some(1usize), max_length: Some(128usize), max_graphemes: Some(128usize), ..Default::default() }), min_length: Some(1usize), max_length: Some(16usize), ..Default::default() }), ); map }, ..Default::default() }), ); map }, ..Default::default() }}