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