1use uuid::{uuid, Uuid};
4
5#[cfg(feature = "chumsky")]
6use chumsky::{
7 prelude::{just, one_of, Simple},
8 Parser,
9};
10
11#[cfg(feature = "chumsky")]
17#[must_use]
18pub fn uuid_parser() -> impl Parser<char, uuid::Uuid, Error = Simple<char>> {
19 one_of("0123456789abcdef")
20 .repeated()
21 .exactly(8)
22 .collect::<String>()
23 .then_ignore(just('-'))
24 .then(
25 one_of("0123456789abcdef")
26 .repeated()
27 .exactly(4)
28 .collect::<String>(),
29 )
30 .then_ignore(just('-'))
31 .then(
32 one_of("0123456789abcdef")
33 .repeated()
34 .exactly(4)
35 .collect::<String>(),
36 )
37 .then_ignore(just('-'))
38 .then(
39 one_of("0123456789abcdef")
40 .repeated()
41 .exactly(4)
42 .collect::<String>(),
43 )
44 .then_ignore(just('-'))
45 .then(
46 one_of("0123456789abcdef")
47 .repeated()
48 .exactly(12)
49 .collect::<String>(),
50 )
51 .try_map(|((((a, b), c), d), e), span: std::ops::Range<usize>| {
52 uuid::Uuid::parse_str(&format!("{}-{}-{}-{}-{}", a, b, c, d, e))
53 .map_err(|e| Simple::custom(span.clone(), format!("{:?}", e)))
54 })
55}
56
57#[derive(Debug, Clone, PartialEq, Eq)]
60pub struct Key(pub Uuid);
61
62impl std::fmt::Display for Key {
63 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
64 write!(f, "{}", self.0)
65 }
66}
67
68#[cfg(feature = "chumsky")]
74#[must_use]
75pub fn key_parser() -> impl Parser<char, Key, Error = Simple<char>> {
76 uuid_parser().map(Key)
77}
78
79pub const NULL_KEY: Key = Key(uuid!("00000000-0000-0000-0000-000000000000"));
82
83pub const COMBAT_LOG_ID: Key = Key(uuid!("45e0fcfa-2268-4490-a51c-3e51bdfe80d1"));
85
86#[derive(Debug, Clone, PartialEq, Eq)]
88pub struct AgentKey(pub Key);
89
90impl std::fmt::Display for AgentKey {
91 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
92 write!(f, "{}", self.0)
93 }
94}
95
96impl From<AgentKey> for Key {
97 fn from(val: AgentKey) -> Self {
98 val.0
99 }
100}
101
102#[cfg(feature = "chumsky")]
108#[must_use]
109pub fn agent_key_parser() -> impl Parser<char, AgentKey, Error = Simple<char>> {
110 key_parser().map(AgentKey)
111}
112
113#[cfg(feature = "chumsky")]
120#[must_use]
121pub fn app_agent_uri_as_agent_key_parser() -> impl Parser<char, AgentKey, Error = Simple<char>> {
122 crate::viewer_uri::viewer_app_agent_uri_parser().try_map(|uri, span| match uri {
123 crate::viewer_uri::ViewerUri::AgentAbout(agent_key)
124 | crate::viewer_uri::ViewerUri::AgentInspect(agent_key) => Ok(agent_key),
125 _ => Err(Simple::custom(span, "Unexpected type of Agent viewer URI")),
126 })
127}
128
129#[derive(Debug, Clone, PartialEq, Eq)]
131pub struct ClassifiedKey(pub Key);
132
133impl std::fmt::Display for ClassifiedKey {
134 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
135 write!(f, "{}", self.0)
136 }
137}
138
139impl From<ClassifiedKey> for Key {
140 fn from(val: ClassifiedKey) -> Self {
141 val.0
142 }
143}
144
145#[cfg(feature = "chumsky")]
151#[must_use]
152pub fn classified_key_parser() -> impl Parser<char, ClassifiedKey, Error = Simple<char>> {
153 key_parser().map(ClassifiedKey)
154}
155
156#[derive(Debug, Clone, PartialEq, Eq)]
158pub struct EventKey(pub Key);
159
160impl std::fmt::Display for EventKey {
161 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
162 write!(f, "{}", self.0)
163 }
164}
165
166impl From<EventKey> for Key {
167 fn from(val: EventKey) -> Self {
168 val.0
169 }
170}
171
172#[cfg(feature = "chumsky")]
178#[must_use]
179pub fn event_key_parser() -> impl Parser<char, EventKey, Error = Simple<char>> {
180 key_parser().map(EventKey)
181}
182
183#[derive(Debug, Clone, PartialEq, Eq)]
185pub struct ExperienceKey(pub Key);
186
187impl std::fmt::Display for ExperienceKey {
188 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
189 write!(f, "{}", self.0)
190 }
191}
192
193impl From<ExperienceKey> for Key {
194 fn from(val: ExperienceKey) -> Self {
195 val.0
196 }
197}
198
199#[cfg(feature = "chumsky")]
205#[must_use]
206pub fn experience_key_parser() -> impl Parser<char, ExperienceKey, Error = Simple<char>> {
207 key_parser().map(ExperienceKey)
208}
209
210#[derive(Debug, Clone, PartialEq, Eq)]
212pub struct FriendKey(pub Key);
213
214impl std::fmt::Display for FriendKey {
215 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
216 write!(f, "{}", self.0)
217 }
218}
219
220impl From<FriendKey> for Key {
221 fn from(val: FriendKey) -> Self {
222 val.0
223 }
224}
225
226impl From<FriendKey> for AgentKey {
227 fn from(val: FriendKey) -> Self {
228 AgentKey(val.0)
229 }
230}
231
232#[cfg(feature = "chumsky")]
238#[must_use]
239pub fn friend_key_parser() -> impl Parser<char, FriendKey, Error = Simple<char>> {
240 key_parser().map(FriendKey)
241}
242
243#[derive(Debug, Clone, PartialEq, Eq)]
245pub struct GroupKey(pub Key);
246
247impl std::fmt::Display for GroupKey {
248 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
249 write!(f, "{}", self.0)
250 }
251}
252
253impl From<GroupKey> for Key {
254 fn from(val: GroupKey) -> Self {
255 val.0
256 }
257}
258
259#[cfg(feature = "chumsky")]
265#[must_use]
266pub fn group_key_parser() -> impl Parser<char, GroupKey, Error = Simple<char>> {
267 key_parser().map(GroupKey)
268}
269
270#[cfg(feature = "chumsky")]
277#[must_use]
278pub fn app_group_uri_as_group_key_parser() -> impl Parser<char, GroupKey, Error = Simple<char>> {
279 crate::viewer_uri::viewer_app_group_uri_parser().try_map(|uri, span| match uri {
280 crate::viewer_uri::ViewerUri::GroupAbout(group_key)
281 | crate::viewer_uri::ViewerUri::GroupInspect(group_key) => Ok(group_key),
282 _ => Err(Simple::custom(span, "Unexpected type of group viewer URI")),
283 })
284}
285
286#[derive(Debug, Clone, PartialEq, Eq)]
288pub struct InventoryKey(pub Key);
289
290impl std::fmt::Display for InventoryKey {
291 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
292 write!(f, "{}", self.0)
293 }
294}
295
296impl From<InventoryKey> for Key {
297 fn from(val: InventoryKey) -> Self {
298 val.0
299 }
300}
301
302#[cfg(feature = "chumsky")]
308#[must_use]
309pub fn inventory_key_parser() -> impl Parser<char, InventoryKey, Error = Simple<char>> {
310 key_parser().map(InventoryKey)
311}
312
313#[derive(Debug, Clone, PartialEq, Eq)]
315pub struct ObjectKey(pub Key);
316
317impl std::fmt::Display for ObjectKey {
318 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
319 write!(f, "{}", self.0)
320 }
321}
322
323impl From<ObjectKey> for Key {
324 fn from(val: ObjectKey) -> Self {
325 val.0
326 }
327}
328
329#[cfg(feature = "chumsky")]
335#[must_use]
336pub fn object_key_parser() -> impl Parser<char, ObjectKey, Error = Simple<char>> {
337 key_parser().map(ObjectKey)
338}
339
340#[derive(Debug, Clone, PartialEq, Eq)]
342pub struct ParcelKey(pub Key);
343
344impl std::fmt::Display for ParcelKey {
345 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
346 write!(f, "{}", self.0)
347 }
348}
349
350impl From<ParcelKey> for Key {
351 fn from(val: ParcelKey) -> Self {
352 val.0
353 }
354}
355
356#[cfg(feature = "chumsky")]
362#[must_use]
363pub fn parcel_key_parser() -> impl Parser<char, ParcelKey, Error = Simple<char>> {
364 key_parser().map(ParcelKey)
365}
366
367#[derive(Debug, Clone, PartialEq, Eq)]
369pub struct TextureKey(pub Key);
370
371impl std::fmt::Display for TextureKey {
372 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
373 write!(f, "{}", self.0)
374 }
375}
376
377impl From<TextureKey> for Key {
378 fn from(val: TextureKey) -> Self {
379 val.0
380 }
381}
382
383#[cfg(feature = "chumsky")]
389#[must_use]
390pub fn texture_key_parser() -> impl Parser<char, TextureKey, Error = Simple<char>> {
391 key_parser().map(TextureKey)
392}
393
394#[derive(Debug, Clone, PartialEq, Eq)]
396pub struct InventoryFolderKey(pub Key);
397
398impl std::fmt::Display for InventoryFolderKey {
399 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
400 write!(f, "{}", self.0)
401 }
402}
403
404impl From<InventoryFolderKey> for Key {
405 fn from(val: InventoryFolderKey) -> Self {
406 val.0
407 }
408}
409
410#[cfg(feature = "chumsky")]
416#[must_use]
417pub fn inventory_folder_key_parser() -> impl Parser<char, InventoryFolderKey, Error = Simple<char>>
418{
419 key_parser().map(InventoryFolderKey)
420}
421
422#[derive(Debug, Clone, PartialEq, Eq, strum::EnumIs)]
424pub enum OwnerKey {
425 Agent(AgentKey),
427 Group(GroupKey),
429}
430
431impl std::fmt::Display for OwnerKey {
432 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
433 match self {
434 OwnerKey::Agent(agent_key) => write!(f, "{}", agent_key),
435 OwnerKey::Group(group_key) => write!(f, "{}", group_key),
436 }
437 }
438}
439
440#[derive(Debug, Clone)]
442pub struct OwnerIsGroupError(GroupKey);
443
444impl std::fmt::Display for OwnerIsGroupError {
445 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
446 write!(f, "The owner is not an agent but the group {}", self.0)
447 }
448}
449
450impl TryInto<AgentKey> for OwnerKey {
451 type Error = OwnerIsGroupError;
452
453 fn try_into(self) -> Result<AgentKey, Self::Error> {
454 match self {
455 OwnerKey::Agent(agent_key) => Ok(agent_key),
456 OwnerKey::Group(group_key) => Err(OwnerIsGroupError(group_key)),
457 }
458 }
459}
460
461#[derive(Debug, Clone)]
463pub struct OwnerIsAgentError(AgentKey);
464
465impl std::fmt::Display for OwnerIsAgentError {
466 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
467 write!(f, "The owner is not a group but the agent {}", self.0)
468 }
469}
470
471impl TryInto<GroupKey> for OwnerKey {
472 type Error = OwnerIsAgentError;
473
474 fn try_into(self) -> Result<GroupKey, Self::Error> {
475 match self {
476 OwnerKey::Agent(agent_key) => Err(OwnerIsAgentError(agent_key)),
477 OwnerKey::Group(group_key) => Ok(group_key),
478 }
479 }
480}
481
482impl From<OwnerKey> for Key {
483 fn from(val: OwnerKey) -> Self {
484 match val {
485 OwnerKey::Agent(agent_key) => agent_key.into(),
486 OwnerKey::Group(group_key) => group_key.into(),
487 }
488 }
489}
490
491#[cfg(feature = "chumsky")]
498#[must_use]
499pub fn app_agent_or_group_uri_as_owner_key_parser(
500) -> impl Parser<char, OwnerKey, Error = Simple<char>> {
501 app_agent_uri_as_agent_key_parser()
502 .map(OwnerKey::Agent)
503 .or(app_group_uri_as_group_key_parser().map(OwnerKey::Group))
504}