summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock147
-rw-r--r--Cargo.toml1
-rw-r--r--src/conversation/history.rs5
-rw-r--r--src/conversation/repo.rs15
-rw-r--r--src/conversation/snapshot.rs14
-rw-r--r--src/message/history.rs5
-rw-r--r--src/message/repo.rs18
-rw-r--r--src/message/snapshot.rs13
8 files changed, 182 insertions, 36 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 59ac88e..b24fc91 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -449,6 +449,41 @@ dependencies = [
]
[[package]]
+name = "darling"
+version = "0.20.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee"
+dependencies = [
+ "darling_core",
+ "darling_macro",
+]
+
+[[package]]
+name = "darling_core"
+version = "0.20.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e"
+dependencies = [
+ "fnv",
+ "ident_case",
+ "proc-macro2",
+ "quote",
+ "strsim",
+ "syn",
+]
+
+[[package]]
+name = "darling_macro"
+version = "0.20.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead"
+dependencies = [
+ "darling_core",
+ "quote",
+ "syn",
+]
+
+[[package]]
name = "der"
version = "0.7.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -466,6 +501,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
dependencies = [
"powerfmt",
+ "serde",
]
[[package]]
@@ -525,6 +561,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b"
[[package]]
+name = "dyn-clone"
+version = "1.0.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555"
+
+[[package]]
name = "either"
version = "1.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -773,6 +815,12 @@ checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
[[package]]
name = "hashbrown"
+version = "0.12.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
+
+[[package]]
+name = "hashbrown"
version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
@@ -1101,6 +1149,12 @@ dependencies = [
]
[[package]]
+name = "ident_case"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39"
+
+[[package]]
name = "idna"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1123,12 +1177,24 @@ dependencies = [
[[package]]
name = "indexmap"
+version = "1.9.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99"
+dependencies = [
+ "autocfg",
+ "hashbrown 0.12.3",
+ "serde",
+]
+
+[[package]]
+name = "indexmap"
version = "2.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652"
dependencies = [
"equivalent",
"hashbrown 0.15.2",
+ "serde",
]
[[package]]
@@ -1445,6 +1511,7 @@ dependencies = [
"rust-embed",
"serde",
"serde_json",
+ "serde_with",
"sqlx",
"thiserror",
"tokio",
@@ -1600,6 +1667,26 @@ dependencies = [
]
[[package]]
+name = "ref-cast"
+version = "1.0.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4a0ae411dbe946a674d89546582cea4ba2bb8defac896622d6496f14c23ba5cf"
+dependencies = [
+ "ref-cast-impl",
+]
+
+[[package]]
+name = "ref-cast-impl"
+version = "1.0.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1165225c21bff1f3bbce98f5a1f889949bc902d3575308cc7b0de30b4f6d27c7"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
name = "rsa"
version = "0.9.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1709,6 +1796,30 @@ dependencies = [
]
[[package]]
+name = "schemars"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4cd191f9397d57d581cddd31014772520aa448f65ef991055d7f61582c65165f"
+dependencies = [
+ "dyn-clone",
+ "ref-cast",
+ "serde",
+ "serde_json",
+]
+
+[[package]]
+name = "schemars"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "82d20c4491bc164fa2f6c5d44565947a52ad80b9505d8e36f8d54c27c739fcd0"
+dependencies = [
+ "dyn-clone",
+ "ref-cast",
+ "serde",
+ "serde_json",
+]
+
+[[package]]
name = "scopeguard"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1741,7 +1852,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d2de91cf02bbc07cde38891769ccd5d4f073d22a40683aa4bc7a95781aaa2c4"
dependencies = [
"form_urlencoded",
- "indexmap",
+ "indexmap 2.7.1",
"itoa",
"ryu",
"serde",
@@ -1782,6 +1893,38 @@ dependencies = [
]
[[package]]
+name = "serde_with"
+version = "3.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f2c45cd61fefa9db6f254525d46e392b852e0e61d9a1fd36e5bd183450a556d5"
+dependencies = [
+ "base64 0.22.1",
+ "chrono",
+ "hex",
+ "indexmap 1.9.3",
+ "indexmap 2.7.1",
+ "schemars 0.9.0",
+ "schemars 1.0.4",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "serde_with_macros",
+ "time",
+]
+
+[[package]]
+name = "serde_with_macros"
+version = "3.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "de90945e6565ce0d9a25098082ed4ee4002e047cb59892c318d66821e14bb30f"
+dependencies = [
+ "darling",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
name = "sha1"
version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1906,7 +2049,7 @@ dependencies = [
"futures-util",
"hashbrown 0.15.2",
"hashlink 0.10.0",
- "indexmap",
+ "indexmap 2.7.1",
"log",
"memchr",
"once_cell",
diff --git a/Cargo.toml b/Cargo.toml
index beb83b3..5b861a8 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -42,6 +42,7 @@ rusqlite = { version = "=0.32.1", features = ["backup"] }
rust-embed = { version = "8.5.0", features = ["interpolate-folder-path"] }
serde = { version = "1.0.217", features = ["derive"] }
serde_json = "1.0.138"
+serde_with = "3.14.0"
# Pinned to maintain libsqlite3 version match between this and rusqlite. See
# also: <https://docs.rs/sqlx/latest/sqlx/sqlite/index.html>
sqlx = { version = "=0.8.3", features = ["chrono", "runtime-tokio", "sqlite"] }
diff --git a/src/conversation/history.rs b/src/conversation/history.rs
index 601614c..746a1b0 100644
--- a/src/conversation/history.rs
+++ b/src/conversation/history.rs
@@ -4,12 +4,11 @@ use super::{
Conversation, Id,
event::{Created, Deleted, Event},
};
-use crate::event::{Instant, Sequence};
+use crate::event::Sequence;
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct History {
pub conversation: Conversation,
- pub deleted: Option<Instant>,
}
// State interface
@@ -58,7 +57,7 @@ impl History {
}
fn deleted(&self) -> Option<Event> {
- self.deleted.map(|instant| {
+ self.conversation.deleted.map(|instant| {
Deleted {
instant,
id: self.conversation.id.clone(),
diff --git a/src/conversation/repo.rs b/src/conversation/repo.rs
index e40a5bd..7e38b62 100644
--- a/src/conversation/repo.rs
+++ b/src/conversation/repo.rs
@@ -59,9 +59,8 @@ impl Conversations<'_> {
created,
id,
name: name.clone(),
- deleted_at: None,
+ deleted: None,
},
- deleted: None,
};
Ok(conversation)
@@ -93,9 +92,8 @@ impl Conversations<'_> {
created: Instant::new(row.created_at, row.created_sequence),
id: row.id,
name: Name::optional(row.display_name, row.canonical_name)?.unwrap_or_default(),
- deleted_at: row.deleted_at,
+ deleted: Instant::optional(row.deleted_at, row.deleted_sequence),
},
- deleted: Instant::optional(row.deleted_at, row.deleted_sequence),
})
})
.fetch_one(&mut *self.0)
@@ -131,9 +129,8 @@ impl Conversations<'_> {
created: Instant::new(row.created_at, row.created_sequence),
id: row.id,
name: Name::optional(row.display_name, row.canonical_name)?.unwrap_or_default(),
- deleted_at: row.deleted_at,
+ deleted: Instant::optional(row.deleted_at, row.deleted_sequence),
},
- deleted: Instant::optional(row.deleted_at, row.deleted_sequence),
})
})
.fetch(&mut *self.0)
@@ -170,9 +167,8 @@ impl Conversations<'_> {
created: Instant::new(row.created_at, row.created_sequence),
id: row.id,
name: Name::optional(row.display_name, row.canonical_name)?.unwrap_or_default(),
- deleted_at: row.deleted_at,
+ deleted: Instant::optional(row.deleted_at, row.deleted_sequence),
},
- deleted: Instant::optional(row.deleted_at, row.deleted_sequence),
})
})
.fetch(&mut *self.0)
@@ -297,9 +293,8 @@ impl Conversations<'_> {
created: Instant::new(row.created_at, row.created_sequence),
id: row.id,
name: Name::optional(row.display_name, row.canonical_name)?.unwrap_or_default(),
- deleted_at: row.deleted_at,
+ deleted: Instant::optional(row.deleted_at, row.deleted_sequence),
},
- deleted: Instant::optional(row.deleted_at, row.deleted_sequence),
})
})
.fetch(&mut *self.0)
diff --git a/src/conversation/snapshot.rs b/src/conversation/snapshot.rs
index da9eaae..440f3c0 100644
--- a/src/conversation/snapshot.rs
+++ b/src/conversation/snapshot.rs
@@ -1,8 +1,10 @@
+use serde_with::with_prefix;
+
use super::{
Id,
event::{Created, Event},
};
-use crate::{clock::DateTime, event::Instant, name::Name};
+use crate::{event::Instant, name::Name};
#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize)]
pub struct Conversation {
@@ -10,10 +12,16 @@ pub struct Conversation {
pub created: Instant,
pub id: Id,
pub name: Name,
- #[serde(skip_serializing_if = "Option::is_none")]
- pub deleted_at: Option<DateTime>,
+ #[serde(
+ flatten,
+ with = "prefix_deleted",
+ skip_serializing_if = "Option::is_none"
+ )]
+ pub deleted: Option<Instant>,
}
+with_prefix!(prefix_deleted "deleted_");
+
impl Conversation {
fn apply(state: Option<Self>, event: Event) -> Option<Self> {
match (state, event) {
diff --git a/src/message/history.rs b/src/message/history.rs
index 7585e1c..d4d4500 100644
--- a/src/message/history.rs
+++ b/src/message/history.rs
@@ -4,12 +4,11 @@ use super::{
Id, Message,
event::{Deleted, Event, Sent},
};
-use crate::event::{Instant, Sequence};
+use crate::event::Sequence;
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct History {
pub message: Message,
- pub deleted: Option<Instant>,
}
// State interface
@@ -43,7 +42,7 @@ impl History {
}
fn deleted(&self) -> Option<Event> {
- self.deleted.map(|instant| {
+ self.message.deleted.map(|instant| {
Deleted {
instant,
id: self.message.id.clone(),
diff --git a/src/message/repo.rs b/src/message/repo.rs
index b4c086d..2e9700a 100644
--- a/src/message/repo.rs
+++ b/src/message/repo.rs
@@ -58,9 +58,8 @@ impl Messages<'_> {
sender: row.sender,
id: row.id,
body: row.body.unwrap_or_default(),
- deleted_at: None,
+ deleted: None,
},
- deleted: None,
})
.fetch_one(&mut *self.0)
.await?;
@@ -99,9 +98,8 @@ impl Messages<'_> {
sender: row.sender,
id: row.id,
body: row.body.unwrap_or_default(),
- deleted_at: row.deleted_at,
+ deleted: Instant::optional(row.deleted_at, row.deleted_sequence),
},
- deleted: Instant::optional(row.deleted_at, row.deleted_sequence),
})
.fetch_all(&mut *self.0)
.await?;
@@ -136,9 +134,8 @@ impl Messages<'_> {
sender: row.sender,
id: row.id,
body: row.body.unwrap_or_default(),
- deleted_at: row.deleted_at,
+ deleted: Instant::optional(row.deleted_at, row.deleted_sequence),
},
- deleted: Instant::optional(row.deleted_at, row.deleted_sequence),
})
.fetch_all(&mut *self.0)
.await?;
@@ -172,9 +169,8 @@ impl Messages<'_> {
sender: row.sender,
id: row.id,
body: row.body.unwrap_or_default(),
- deleted_at: row.deleted_at,
+ deleted: Instant::optional(row.deleted_at, row.deleted_sequence),
},
- deleted: Instant::optional(row.deleted_at, row.deleted_sequence),
})
.fetch_one(&mut *self.0)
.await?;
@@ -277,9 +273,8 @@ impl Messages<'_> {
conversation: row.conversation,
sender: row.sender,
body: row.body.unwrap_or_default(),
- deleted_at: row.deleted_at,
+ deleted: Instant::optional(row.deleted_at, row.deleted_sequence),
},
- deleted: Instant::optional(row.deleted_at, row.deleted_sequence),
})
.fetch_all(&mut *self.0)
.await?;
@@ -313,9 +308,8 @@ impl Messages<'_> {
sender: row.sender,
id: row.id,
body: row.body.unwrap_or_default(),
- deleted_at: row.deleted_at,
+ deleted: Instant::optional(row.deleted_at, row.deleted_sequence),
},
- deleted: Instant::optional(row.deleted_at, row.deleted_sequence),
})
.fetch_all(&mut *self.0)
.await?;
diff --git a/src/message/snapshot.rs b/src/message/snapshot.rs
index 12d4daa..19a98a3 100644
--- a/src/message/snapshot.rs
+++ b/src/message/snapshot.rs
@@ -2,7 +2,8 @@ use super::{
Body, Id,
event::{Event, Sent},
};
-use crate::{clock::DateTime, conversation, event::Instant, user};
+use crate::{conversation, event::Instant, user};
+use serde_with::with_prefix;
#[derive(Clone, Debug, Eq, PartialEq, serde::Serialize)]
pub struct Message {
@@ -12,10 +13,16 @@ pub struct Message {
pub sender: user::Id,
pub id: Id,
pub body: Body,
- #[serde(skip_serializing_if = "Option::is_none")]
- pub deleted_at: Option<DateTime>,
+ #[serde(
+ flatten,
+ with = "prefix_deleted",
+ skip_serializing_if = "Option::is_none"
+ )]
+ pub deleted: Option<Instant>,
}
+with_prefix!(prefix_deleted "deleted_");
+
impl Message {
fn apply(state: Option<Self>, event: Event) -> Option<Self> {
match (state, event) {