1use serde::{Deserialize, Serialize};
2
3/// AT Protocol URI (at://) types and validation
4pub mod aturi;
5/// Blob references for binary data
6pub mod blob;
7/// Content Identifier (CID) types for IPLD
8pub mod cid;
9/// Repository collection trait for records
10pub mod collection;
11/// AT Protocol datetime string type
12pub mod datetime;
13/// Decentralized Identifier (DID) types and validation
14pub mod did;
15/// DID Document types and helpers
16pub mod did_doc;
17/// Crypto helpers for keys (Multikey decoding, conversions)
18pub mod crypto;
19/// AT Protocol handle types and validation
20pub mod handle;
21/// AT Protocol identifier types (handle or DID)
22pub mod ident;
23/// Integer type with validation
24pub mod integer;
25/// Language tag types per BCP 47
26pub mod language;
27/// CID link wrapper for JSON serialization
28pub mod link;
29/// Namespaced Identifier (NSID) types and validation
30pub mod nsid;
31/// Record key types and validation
32pub mod recordkey;
33/// String types with format validation
34pub mod string;
35/// Timestamp Identifier (TID) types and generation
36pub mod tid;
37/// URI types with scheme validation
38pub mod uri;
39/// Generic data value types for lexicon data model
40pub mod value;
41/// XRPC protocol types and traits
42pub mod xrpc;
43
44/// Trait for a constant string literal type
45pub trait Literal: Clone + Copy + PartialEq + Eq + Send + Sync + 'static {
46 /// The string literal
47 const LITERAL: &'static str;
48}
49
50/// top-level domains which are not allowed in at:// handles or dids
51pub const DISALLOWED_TLDS: &[&str] = &[
52 ".local",
53 ".arpa",
54 ".invalid",
55 ".localhost",
56 ".internal",
57 ".example",
58 ".alt",
59 // policy could concievably change on ".onion" some day
60 ".onion",
61 // NOTE: .test is allowed in testing and devopment. In practical terms
62 // "should" "never" actually resolve and get registered in production
63];
64
65/// checks if a string ends with anything from the provided list of strings.
66pub fn ends_with(string: impl AsRef<str>, list: &[&str]) -> bool {
67 let string = string.as_ref();
68 for item in list {
69 if string.ends_with(item) {
70 return true;
71 }
72 }
73 false
74}
75
76#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Hash)]
77#[serde(rename_all = "kebab-case")]
78/// Valid types in the AT protocol [data model](https://atproto.com/specs/data-model). Type marker only, used in concert with `[Data<'_>]`.
79pub enum DataModelType {
80 /// Null type. IPLD type `null`, JSON type `Null`, CBOR Special Value (major 7)
81 Null,
82 /// Boolean type. IPLD type `boolean`, JSON type Boolean, CBOR Special Value (major 7)
83 Boolean,
84 /// Integer type. IPLD type `integer`, JSON type Number, CBOR Special Value (major 7)
85 Integer,
86 /// Byte type. IPLD type `bytes`, in JSON a `{ "$bytes": bytes }` Object, CBOR Byte String (major 2)
87 Bytes,
88 /// CID (content identifier) link. IPLD type `link`, in JSON a `{ "$link": cid }` Object, CBOR CID (tag 42)
89 CidLink,
90 /// Blob type. No special IPLD type. in JSON a `{ "$type": "blob" }` Object. in CBOR a `{ "$type": "blob" }` Map.
91 Blob,
92 /// Array type. IPLD type `list`. JSON type `Array`, CBOR type Array (major 4)
93 Array,
94 /// Object type. IPLD type `map`. JSON type `Object`, CBOR type Map (major 5). keys are always SmolStr.
95 Object,
96 #[serde(untagged)]
97 /// String type (lots of variants). JSON String, CBOR UTF-8 String (major 3)
98 String(LexiconStringType),
99}
100
101/// Lexicon string format types for typed strings in the AT Protocol data model
102#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Hash)]
103#[serde(rename_all = "kebab-case")]
104pub enum LexiconStringType {
105 /// ISO 8601 datetime string
106 Datetime,
107 /// AT Protocol URI (at://)
108 AtUri,
109 /// Decentralized Identifier
110 Did,
111 /// AT Protocol handle
112 Handle,
113 /// Handle or DID
114 AtIdentifier,
115 /// Namespaced Identifier
116 Nsid,
117 /// Content Identifier
118 Cid,
119 /// BCP 47 language tag
120 Language,
121 /// Timestamp Identifier
122 Tid,
123 /// Record key
124 RecordKey,
125 /// URI with type constraint
126 Uri(UriType),
127 /// Plain string
128 #[serde(untagged)]
129 String,
130}
131
132/// URI scheme types for lexicon URI format constraints
133#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
134#[serde(tag = "type")]
135pub enum UriType {
136 /// DID URI (did:)
137 Did,
138 /// AT Protocol URI (at://)
139 At,
140 /// HTTPS URI
141 Https,
142 /// WebSocket Secure URI
143 Wss,
144 /// CID URI
145 Cid,
146 /// DNS name
147 Dns,
148 /// Any valid URI
149 Any,
150}