WNJKYXDW4UGZ5MJEFMKHZHLWJC4SLHKIBFWGLPDKDT3BW2JRGDOQC
// Copyright © 2023 Kim Altintop <kim@eagain.io>
// SPDX-License-Identifier: GPL-2.0-only
use 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-only
use 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-only
use 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())
}
}