jacquard_common/types/collection.rs
1use core::fmt;
2
3use serde::Serialize;
4
5use crate::types::{
6 aturi::RepoPath,
7 nsid::Nsid,
8 recordkey::{RecordKey, RecordKeyType, Rkey},
9};
10
11/// Trait for a collection of records that can be stored in a repository.
12///
13/// The records all have the same Lexicon schema.
14///
15/// Implemented on the record type itself.
16pub trait Collection: fmt::Debug + Serialize {
17 /// The NSID for the Lexicon that defines the schema of records in this collection.
18 const NSID: &'static str;
19
20 /// Returns the [`Nsid`] for the Lexicon that defines the schema of records in this
21 /// collection.
22 ///
23 /// This is a convenience method that parses [`Self::NSID`].
24 ///
25 /// # Panics
26 ///
27 /// Panics if [`Self::NSID`] is not a valid NSID.
28 ///
29 /// [`Nsid`]: crate::types::string::Nsid
30 fn nsid() -> crate::types::nsid::Nsid<'static> {
31 Nsid::new_static(Self::NSID).expect("should be valid NSID")
32 }
33
34 /// Returns the repo path for a record in this collection with the given record key.
35 ///
36 /// Per the [Repo Data Structure v3] specification:
37 /// > Repo paths currently have a fixed structure of `<collection>/<record-key>`. This
38 /// > means a valid, normalized [`Nsid`], followed by a `/`, followed by a valid
39 /// > [`RecordKey`].
40 ///
41 /// [Repo Data Structure v3]: https://atproto.com/specs/repository#repo-data-structure-v3
42 /// [`Nsid`]: crate::types::string::Nsid
43 fn repo_path<'u, T: RecordKeyType>(
44 rkey: &'u crate::types::recordkey::RecordKey<T>,
45 ) -> RepoPath<'u> {
46 RepoPath {
47 collection: Self::nsid(),
48 rkey: Some(RecordKey::from(Rkey::raw(rkey.as_ref()))),
49 }
50 }
51}