//// The repo-storage envelope around any generated record type: addressing //// (`uri`/`cid`/`rkey`) plus the decoded record `value`. Not a lexicon concept, //// so it's hand-written and generic over the record. import atproto/uri import gleam/dynamic/decode import gleam/json pub type StoredItem(record) { StoredItem(uri: String, cid: String, rkey: String, value: record) } /// Build a `StoredItem` for a `listRecords` row, deriving `rkey` from the /// record's at-uri. The single home for that derivation, shared by the row /// decoder below and by callers that already hold a decoded value. pub fn stored_row( at_uri: String, cid: String, value: record, ) -> StoredItem(record) { StoredItem(uri: at_uri, cid:, rkey: uri.rkey(at_uri), value:) } /// Decode one `com.atproto.repo.listRecords` row (`uri`/`cid`/`value`) into a /// `StoredItem`. `value_decoder` decodes the row's record body. pub fn list_records_row_decoder( value_decoder: decode.Decoder(record), ) -> decode.Decoder(StoredItem(record)) { use at_uri <- decode.field("uri", decode.string) use cid <- decode.field("cid", decode.string) use value <- decode.field("value", value_decoder) decode.success(stored_row(at_uri, cid, value)) } pub fn encode_stored_item( stored: StoredItem(record), encode_value: fn(record) -> json.Json, ) -> json.Json { json.object([ #("uri", json.string(stored.uri)), #("cid", json.string(stored.cid)), #("rkey", json.string(stored.rkey)), #("value", encode_value(stored.value)), ]) } pub fn stored_item_decoder( value_decoder: decode.Decoder(record), ) -> decode.Decoder(StoredItem(record)) { use uri <- decode.field("uri", decode.string) use cid <- decode.field("cid", decode.string) use rkey <- decode.field("rkey", decode.string) use value <- decode.field("value", value_decoder) decode.success(StoredItem(uri:, cid:, rkey:, value:)) }