From 88b8a124b4b0189ed6d4ee189ba7022c4c49424a Mon Sep 17 00:00:00 2001 From: Hayleigh Thompson Date: Sat, 25 Jul 2026 23:09:52 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=93=9D=20Add=20doc=20comments.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/at/rkey.gleam | 48 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 35 insertions(+), 13 deletions(-) diff --git a/src/at/rkey.gleam b/src/at/rkey.gleam index c331914..818a3dc 100644 --- a/src/at/rkey.gleam +++ b/src/at/rkey.gleam @@ -3,7 +3,6 @@ import at/nsid import at/tid import gleam/dynamic/decode -import gleam/result // TYPES ----------------------------------------------------------------------- @@ -13,8 +12,24 @@ pub opaque type Rkey { Rkey(value: Value) } +/// The four kinds of [`Rkey`](#Rkey) recognised by atproto. A Lexicon schema will +/// specify which of these a given record collection expects, but this type can +/// enumerate all of them. +/// +/// - `Tid`: a [`Tid`](./tid#Tid), the most common scheme. These are +/// usually generated from the current time when a record is created, which +/// gives records within a collection a rough chronological ordering. +/// +/// - `Nsid`: a valid [`Nsid`](./nsid#Nsid), used when a record's key itself needs +/// to identify a schema or namespace. +/// +/// - `Literal`: a fixed, well-known string, most commonly `"self"`. Used when +/// a collection should only ever contain a single record, such as an account's +/// profile. Literal record keys are always prefixed with `"literal:"` in their +/// string representation. +/// +/// - `Any`: any other string that satisfies the general [record key syntax](https://atproto.com/specs/record-key#record-key-syntax). /// -/// pub type Value { Tid(tid.Tid) Nsid(nsid.Nsid) @@ -29,31 +44,32 @@ pub const zero = Rkey(Literal("self")) // CONSTRUCTORS ---------------------------------------------------------------- -/// +/// Attempt to parse a string into an [`Rkey`](#Rkey). This function will accept +/// strings that are valid according to the general [record key syntax](https://atproto.com/specs/record-key#record-key-syntax) +/// but can detect and classify `Tid` and `Nsid` keys specifically. /// pub fn from_string(value: String) -> Result(Rkey, Nil) { case value { "." | ".." -> Error(Nil) + "literal:self" -> Ok(Rkey(Literal("self"))) "literal:" <> rest -> from_raw_string(rest, Literal) - value -> - from_tid_string(value) - |> result.lazy_or(fn() { from_nsid_string(value) }) - |> result.lazy_or(fn() { from_raw_string(value, Any) }) + + value -> from_tid_string(value) } } fn from_tid_string(value: String) -> Result(Rkey, Nil) { case tid.from_string(value) { Ok(tid) -> Ok(Rkey(Tid(tid))) - Error(_) -> Error(Nil) + Error(_) -> from_nsid_string(value) } } fn from_nsid_string(value: String) -> Result(Rkey, Nil) { case nsid.from_string(value) { Ok(nsid) -> Ok(Rkey(Nsid(nsid))) - Error(_) -> Error(Nil) + Error(_) -> from_raw_string(value, Any) } } @@ -155,20 +171,23 @@ fn is_valid_rkey(remaining: String, length: Int) -> Bool { } } +/// Construct a [`Rkey`](#Rkey) from a [`Tid`](./tid#Tid), such as one freshly +/// generated with [`tid.now`](./tid#now). /// -/// pub fn from_tid(tid: tid.Tid) -> Rkey { Rkey(Tid(tid)) } +/// Construct a [`Rkey`](#Rkey) from a valid [`Nsid`](./nsid#Nsid). /// -/// pub fn from_nsid(nsid: nsid.Nsid) -> Rkey { Rkey(Nsid(nsid)) } +/// A [`Decoder`](https://gleam-stdlib.hexdocs.pm/gleam/dynamic/decode.html#Decoder) +/// for [`Rkey`](#Rkey) strings. You'll need this any time you want to decode a +/// [`Rkey`](#Rkey) from a JSON payload, for example. /// -/// pub fn decoder() -> decode.Decoder(Rkey) { use string <- decode.then(decode.string) @@ -180,13 +199,16 @@ pub fn decoder() -> decode.Decoder(Rkey) { // QUERIES --------------------------------------------------------------------- +/// Get the [`Value`](#Value) of a [`Rkey`](#Rkey), letting you pattern match +/// on which of the four kinds it is. +/// pub fn value(rkey: Rkey) -> Value { rkey.value } // CONVERSIONS ----------------------------------------------------------------- -/// +/// Convert a [`Rkey`](#Rkey) back to its string representation. /// pub fn to_string(rkey: Rkey) -> String { case rkey.value { -- 2.51.2