-
-
Notifications
You must be signed in to change notification settings - Fork 108
Open
Labels
Description
Consider how FullChat.chat_type
is defined:
chat_type: u32, |
This generates the following TypeScript definition:
"chatType": U32;
which is IMO too weakly typed. This has been an issue in the v2 migration in Delta Chat Desktop, where a new chat_type
has been added, TypeScript did not assist us here.
I have tried to solve this with the following patch, but for some reason it turns chatType
into a string union (type ChatChattype = ("Single" | "Group" | "Mailinglist" | "OutBroadcast" | "InBroadcast");
)
patch
diff --git a/Cargo.lock b/Cargo.lock
index d967b3aae..bff535463 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1408,6 +1408,7 @@ dependencies = [
"schemars",
"serde",
"serde_json",
+ "serde_repr",
"tempfile",
"tokio",
"typescript-type-def",
@@ -5403,6 +5404,17 @@ dependencies = [
"serde",
]
+[[package]]
+name = "serde_repr"
+version = "0.1.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "175ee3e80ae9982737ca543e96133087cbd9a485eecc3bc4de9c1a37b47ea59c"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn 2.0.104",
+]
+
[[package]]
name = "serde_spanned"
version = "0.6.9"
diff --git a/deltachat-jsonrpc/Cargo.toml b/deltachat-jsonrpc/Cargo.toml
index 1b64fda1e..1357a0b1c 100644
--- a/deltachat-jsonrpc/Cargo.toml
+++ b/deltachat-jsonrpc/Cargo.toml
@@ -13,6 +13,7 @@ deltachat-contact-tools = { workspace = true }
num-traits = { workspace = true }
schemars = "0.8.22"
serde = { workspace = true, features = ["derive"] }
+serde_repr = "0.1"
async-channel = { workspace = true }
serde_json = { workspace = true }
yerpc = { workspace = true, features = ["anyhow_expose", "openrpc"] }
diff --git a/deltachat-jsonrpc/src/api/types/chat.rs b/deltachat-jsonrpc/src/api/types/chat.rs
index e75892bb7..9f2a70448 100644
--- a/deltachat-jsonrpc/src/api/types/chat.rs
+++ b/deltachat-jsonrpc/src/api/types/chat.rs
@@ -13,6 +13,49 @@
use super::color_int_to_hex_string;
use super::contact::ContactObject;
+// https://serde.rs/enum-number.html
+// https://graham.cool/schemars/examples/8-enum_repr/
+#[derive(
+ serde_repr::Serialize_repr,
+ serde_repr::Deserialize_repr,
+ schemars::JsonSchema_repr,
+ PartialEq,
+ TypeDef,
+)]
+#[repr(u32)]
+enum ChatChattype {
+ Single = 100,
+ Group = 120,
+ Mailinglist = 140,
+ OutBroadcast = 160,
+ InBroadcast = 165,
+}
+
+// TODO use newtype pattern, untagged stuff IDK.
+impl From<Chattype> for ChatChattype {
+ fn from(chattype: Chattype) -> Self {
+ match chattype {
+ Chattype::Single => ChatChattype::Single,
+ Chattype::Group => ChatChattype::Group,
+ Chattype::Mailinglist => ChatChattype::Mailinglist,
+ Chattype::OutBroadcast => ChatChattype::OutBroadcast,
+ Chattype::InBroadcast => ChatChattype::InBroadcast,
+ }
+ }
+}
+
+impl From<ChatChattype> for Chattype {
+ fn from(chattype: ChatChattype) -> Self {
+ match chattype {
+ ChatChattype::Single => Chattype::Single,
+ ChatChattype::Group => Chattype::Group,
+ ChatChattype::Mailinglist => Chattype::Mailinglist,
+ ChatChattype::OutBroadcast => Chattype::OutBroadcast,
+ ChatChattype::InBroadcast => Chattype::InBroadcast,
+ }
+ }
+}
+
#[derive(Serialize, TypeDef, schemars::JsonSchema)]
#[serde(rename_all = "camelCase")]
pub struct FullChat {
@@ -58,7 +101,7 @@ pub struct FullChat {
archived: bool,
pinned: bool,
// subtitle - will be moved to frontend because it uses translation functions
- chat_type: u32,
+ chat_type: ChatChattype,
is_unpromoted: bool,
is_self_talk: bool,
contacts: Vec<ContactObject>,
@@ -136,7 +179,7 @@ pub async fn try_from_dc_chat_id(context: &Context, chat_id: u32) -> Result<Self
profile_image, //BLOBS ?
archived: chat.get_visibility() == chat::ChatVisibility::Archived,
pinned: chat.get_visibility() == chat::ChatVisibility::Pinned,
- chat_type: chat.get_type().to_u32().context("unknown chat type id")?,
+ chat_type: chat.get_type().into(),
is_unpromoted: chat.is_unpromoted(),
is_self_talk: chat.is_self_talk(),
contacts,
We have a few other such places that use numbers:
pub status: u32, // in reality this is an enum, but for simplicity and because it gets converted into a number anyway, we use an u32 here. |
chat_type: u32, |
If nobody knows how to fix the repr
serialization, I suggest to just add another field chatTypeV2
(for backwards compatibility) that would be a string union.
Note that we're already utilizing such string unions, e.g. here
view_type: MessageViewtype, |