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