WNJKYXDW4UGZ5MJEFMKHZHLWJC4SLHKIBFWGLPDKDT3BW2JRGDOQC // Copyright © 2023 Kim Altintop <kim@eagain.io>// SPDX-License-Identifier: GPL-2.0-onlyuse autosurgeon::{reconcile::NoKey,Hydrate,HydrateError,Reconcile,Reconciler,};use chrono::{DateTime,NaiveDateTime,Utc,};#[derive(Clone, Copy, Debug)]pub struct Timestamp {inner: DateTime<Utc>,}impl Timestamp {pub fn now() -> Self {Self { inner: Utc::now() }}}impl Hydrate for Timestamp {fn hydrate_timestamp(t: i64) -> Result<Self, HydrateError> {NaiveDateTime::from_timestamp_millis(t).map_or_else(|| {Err(HydrateError::unexpected("invalid timestamp",format!("too large integer: {t}"),))},|ndt| {Ok(Timestamp {inner: DateTime::from_naive_utc_and_offset(ndt, Utc),})},)}}impl Reconcile for Timestamp {type Key<'a> = NoKey;fn reconcile<R: Reconciler>(&self, mut reconciler: R) -> Result<(), R::Error> {reconciler.timestamp(self.inner.timestamp_millis())}}
// Copyright © 2023 Kim Altintop <kim@eagain.io>// SPDX-License-Identifier: GPL-2.0-onlyuse autosurgeon::{hydrate,reconcile,};use super::*;#[test]fn play() {let mut doc = automerge::AutoCommit::new();reconcile(&mut doc,&Discussion {id: 0,topic: "test".into(),tags: vec![],entries: vec![],},).unwrap();let mut doc2 = doc.fork().with_actor(automerge::ActorId::random());let mut disc2: Discussion = hydrate(&doc2).unwrap();disc2.entries.push(Entry {meta: EntryMeta::from("Dylan"),kind: EntryKind::Comment("Yo".into()),});reconcile(&mut doc2, &disc2).unwrap();let mut doc1 = doc.fork().with_actor(automerge::ActorId::random());let mut disc1: Discussion = hydrate(&doc1).unwrap();disc1.entries.push(Entry {meta: EntryMeta::from("dave"),kind: EntryKind::Comment("hey".into()),});reconcile(&mut doc1, &disc1).unwrap();doc.merge(&mut doc1).unwrap();doc.merge(&mut doc2).unwrap();let merged: Discussion = hydrate(&doc).unwrap();println!("{merged:#?}");println!("Changes:");for change in doc.get_changes(&[]) {println!("{change:#?}");}}
// Copyright © 2023 Kim Altintop <kim@eagain.io>// SPDX-License-Identifier: GPL-2.0-onlyuse autosurgeon::{reconcile::NoKey,Hydrate,HydrateError,Reconcile,Reconciler,};#[derive(Clone, Debug)]pub struct Patch {hash: libpijul::Hash,}impl Hydrate for Patch {fn hydrate_bytes(bytes: &[u8]) -> Result<Self, HydrateError> {libpijul::Hash::from_bytes(bytes).map_or_else(|| Err(HydrateError::unexpected("invalid hash", String::new())),|hash| Ok(Self { hash }),)}}impl Reconcile for Patch {type Key<'a> = NoKey;fn reconcile<R: Reconciler>(&self, mut reconciler: R) -> Result<(), R::Error> {reconciler.bytes(self.hash.to_bytes())}}