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}