tauri_plugin_nostr_sync/
models.rs1use chrono::{DateTime, Utc};
2use serde::{Deserialize, Serialize};
3use serde_json::Value;
4
5#[derive(Debug, Clone, Serialize, Deserialize)]
6#[serde(rename_all = "camelCase")]
7pub struct PublishRequest {
8 pub category: String,
9 pub payload: Value,
10 pub expiration: Option<u64>,
12}
13
14#[derive(Debug, Clone, Serialize, Deserialize)]
15#[serde(rename_all = "camelCase")]
16pub struct FetchRequest {
17 pub category: String,
18}
19
20#[derive(Debug, Clone, Serialize, Deserialize)]
21#[serde(rename_all = "camelCase")]
22pub struct FetchResult {
23 pub category: String,
24 pub payload: Value,
25 pub updated_at: DateTime<Utc>,
26 pub device_id: String,
27}
28
29#[derive(Debug, Clone, Serialize, Deserialize)]
30#[serde(rename_all = "camelCase")]
31pub struct SyncAllRequest {
32 pub categories: Vec<String>,
33}
34
35#[derive(Debug, Clone, Serialize, Deserialize)]
36#[serde(rename_all = "camelCase")]
37pub struct PollRequest {
38 pub categories: Vec<String>,
39}
40
41#[derive(Debug, Clone, Serialize, Deserialize)]
42#[serde(rename_all = "camelCase")]
43pub struct SyncStatus {
44 pub ready: bool,
45 pub relay_count: usize,
46 pub connected_relay_count: usize,
47 pub device_id: String,
48}
49
50#[derive(Debug, Clone, Serialize, Deserialize)]
51#[serde(rename_all = "camelCase")]
52pub struct RelayInfo {
53 pub url: String,
54 pub connected: bool,
55 pub last_seen: Option<DateTime<Utc>>,
56}
57
58#[cfg(test)]
59mod tests {
60 use super::*;
61 use chrono::TimeZone;
62
63 #[test]
64 fn fetch_result_serializes_camel_case() {
65 let result = FetchResult {
66 category: "ui-settings".to_string(),
67 payload: serde_json::json!({ "x": 1 }),
68 updated_at: Utc.timestamp_opt(1_700_000_000, 0).unwrap(),
69 device_id: "abc".to_string(),
70 };
71 let json = serde_json::to_value(&result).unwrap();
72 assert!(json.get("category").is_some(), "expected category field");
73 assert!(
74 json.get("updatedAt").is_some(),
75 "expected camelCase updatedAt"
76 );
77 assert!(
78 json.get("deviceId").is_some(),
79 "expected camelCase deviceId"
80 );
81 assert!(json.get("updated_at").is_none());
82 assert!(json.get("device_id").is_none());
83 }
84
85 #[test]
86 fn sync_status_serializes_camel_case() {
87 let status = SyncStatus {
88 ready: false,
89 relay_count: 2,
90 connected_relay_count: 1,
91 device_id: "test-device".to_string(),
92 };
93 let json = serde_json::to_value(&status).unwrap();
94 assert!(json.get("relayCount").is_some());
95 assert!(json.get("connectedRelayCount").is_some());
96 assert!(json.get("relay_count").is_none());
97 }
98
99 #[test]
100 fn relay_info_serializes_camel_case() {
101 let info = RelayInfo {
102 url: "wss://relay.example".to_string(),
103 connected: true,
104 last_seen: None,
105 };
106 let json = serde_json::to_value(&info).unwrap();
107 assert!(json.get("lastSeen").is_some());
108 assert!(json.get("last_seen").is_none());
109 }
110
111 #[test]
112 fn sync_all_request_deserializes_categories() {
113 let json = r#"{"categories":["ui-settings","wallet"]}"#;
114 let req: SyncAllRequest = serde_json::from_str(json).unwrap();
115 assert_eq!(req.categories, vec!["ui-settings", "wallet"]);
116 }
117
118 #[test]
119 fn poll_request_deserializes_categories() {
120 let json = r#"{"categories":["ui-settings","wallet"]}"#;
121 let req: PollRequest = serde_json::from_str(json).unwrap();
122 assert_eq!(req.categories, vec!["ui-settings", "wallet"]);
123 }
124}