Something went wrong. Try again.
Monorepo for Tangled tangled.org
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136use knot_git::CommitRange;use knot_types::{AccountDid, Oid, RecordBody, RecordBodyError, Tid, UnixSeconds};use serde::{Serialize, Serializer};
use crate::{CreatedAt, RecordError, encoded};
pub const PATCH_COLLECTION: &str = "org.tangled.review.patch";
collection!( patch_collection, PATCH_COLLECTION, "Patch collection is valid nsid");
#[derive(Debug, Clone, PartialEq, Eq)]pub struct PatchRecord { ticket: Tid, range: CommitRange, created_at: CreatedAt, editor: AccountDid,}
impl PatchRecord { pub fn new( ticket: Tid, range: CommitRange, created_at: UnixSeconds, editor: AccountDid, ) -> Result<Self, RecordError> { Ok(Self { ticket, range, created_at: CreatedAt::at(created_at)?, editor, }) }
pub fn body(&self) -> Result<RecordBody, RecordBodyError> { encoded(self) }}
#[derive(Serialize)]struct OidEncoding<'a> { oid: &'a Oid,}
#[derive(Serialize)]struct PatchEncoding<'a> { #[serde(rename = "$type")] record_type: knot_types::RecordCollection, ticket: &'a Tid, base: OidEncoding<'a>, head: OidEncoding<'a>, #[serde(rename = "createdAt")] created_at: &'a CreatedAt, #[serde(rename = "x-tngl-editor")] editor: &'a AccountDid,}
impl Serialize for PatchRecord { fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> { PatchEncoding { record_type: patch_collection(), ticket: &self.ticket, base: OidEncoding { oid: &self.range.base, }, head: OidEncoding { oid: &self.range.head, }, created_at: &self.created_at, editor: &self.editor, } .serialize(serializer) }}
#[cfg(test)]mod tests { use super::*; use crate::frozen;
const PATCH: &str = "a66462617365a1636f69647828616161616161616161616161616161616161616161616161616161616161616161616161616161616468656164a1636f696478286262626262626262626262626262626262626262626262626262626262626262626262626262626265247479706578186f72672e74616e676c65642e7265766965772e7061746368667469636b65746d336c75627270747835376432326963726561746564417474313937302d30312d30315430303a30303a30315a6d782d746e676c2d656469746f7278206469643a706c633a3366776563646e76746373636a6e72783270346e37616c7a";
fn editor() -> AccountDid { AccountDid::new("did:plc:3fwecdnvtcscjnrx2p4n7alz").unwrap() }
fn oid(byte: u8) -> Oid { Oid::from_hex(&(byte as char).to_string().repeat(40)).unwrap() }
fn range() -> CommitRange { CommitRange { base: oid(b'a'), head: oid(b'b'), } }
#[test] fn patch_record_bytes_frozen() { let record = PatchRecord::new( Tid::new("3lubrptx57d22").unwrap(), range(), UnixSeconds::new(1), editor(), ) .unwrap(); let body = record.body().unwrap(); assert_eq!( body.as_bytes(), frozen(PATCH).as_slice(), "the first emitted patch must freeze these bytes: whole seconds, utc z" ); }
#[test] fn patch_embeds_ticket_and_oid_pair() { let record = PatchRecord::new( Tid::new("3lubrptx57d22").unwrap(), range(), UnixSeconds::new(1), editor(), ) .unwrap(); let value: serde_json::Value = serde_ipld_dagcbor::from_slice(record.body().unwrap().as_bytes()).unwrap(); assert_eq!(value["$type"], PATCH_COLLECTION); assert_eq!(value["ticket"], "3lubrptx57d22"); assert_eq!(value["base"]["oid"], "a".repeat(40)); assert_eq!(value["head"]["oid"], "b".repeat(40)); assert_eq!(value["x-tngl-editor"], editor().as_str()); }}