tauri_plugin_nostr_sync/
builder.rs1use tauri::{plugin::TauriPlugin, Manager, Runtime};
2
3pub struct PluginBuilder {
4 pub(crate) relays: Vec<String>,
5 pub(crate) namespace: String,
6 pub(crate) device_id: String,
7 pub(crate) max_payload_size: usize,
8}
9
10impl PluginBuilder {
11 pub fn new() -> Self {
12 Self {
13 relays: Vec::new(),
14 namespace: "default".to_string(),
15 device_id: uuid::Uuid::new_v4().to_string(),
16 max_payload_size: crate::state::DEFAULT_PAYLOAD_LIMIT,
17 }
18 }
19
20 pub fn relays(mut self, urls: impl IntoIterator<Item = impl Into<String>>) -> Self {
21 self.relays = urls.into_iter().map(|u| u.into()).collect();
22 self
23 }
24
25 pub fn app_namespace(mut self, ns: impl Into<String>) -> Self {
26 self.namespace = ns.into();
27 self
28 }
29
30 pub fn device_id(mut self, id: impl Into<String>) -> Self {
37 self.device_id = id.into();
38 self
39 }
40
41 pub fn max_payload_size(mut self, bytes: usize) -> Self {
46 self.max_payload_size = bytes;
47 self
48 }
49
50 pub fn build<R: Runtime>(self) -> TauriPlugin<R> {
51 crate::state::validate_namespace(&self.namespace)
53 .unwrap_or_else(|e| panic!("invalid app_namespace: {e}"));
54
55 let relays = self.relays;
56 let namespace = self.namespace;
57 let device_id = self.device_id;
58 let max_payload_size = self.max_payload_size;
59
60 tauri::plugin::Builder::<R>::new("nostr-sync")
61 .invoke_handler(tauri::generate_handler![
62 crate::commands::publish,
63 crate::commands::fetch,
64 crate::commands::sync_all,
65 crate::commands::add_relay,
66 crate::commands::remove_relay,
67 crate::commands::get_relays,
68 crate::commands::get_pubkey,
69 crate::commands::get_status,
70 crate::commands::poll,
71 ])
72 .setup(move |app, api| {
73 #[cfg(mobile)]
74 {
75 let plugin = crate::mobile::init(
76 app,
77 api,
78 relays,
79 &namespace,
80 &device_id,
81 max_payload_size,
82 )?;
83 app.manage(plugin);
84 }
85 #[cfg(desktop)]
86 {
87 let _ = &api;
88 let plugin = crate::desktop::init(
89 app,
90 relays,
91 &namespace,
92 &device_id,
93 max_payload_size,
94 )?;
95 app.manage(plugin);
96 }
97 Ok(())
98 })
99 .build()
100 }
101}
102
103impl Default for PluginBuilder {
104 fn default() -> Self {
105 Self::new()
106 }
107}
108
109#[cfg(test)]
110mod tests {
111 use super::*;
112
113 #[test]
114 fn defaults_to_default_namespace() {
115 let b = PluginBuilder::new();
116 assert_eq!(b.namespace, "default");
117 }
118
119 #[test]
120 fn defaults_to_empty_relays() {
121 let b = PluginBuilder::new();
122 assert!(b.relays.is_empty());
123 }
124
125 #[test]
126 fn defaults_to_ephemeral_device_id() {
127 let b = PluginBuilder::new();
128 assert!(!b.device_id.is_empty());
129 assert_ne!(b.device_id, PluginBuilder::new().device_id);
131 }
132
133 #[test]
134 fn device_id_overrides_ephemeral() {
135 let b = PluginBuilder::new().device_id("my-stable-device");
136 assert_eq!(b.device_id, "my-stable-device");
137 }
138
139 #[test]
140 fn app_namespace_overrides_default() {
141 let b = PluginBuilder::new().app_namespace("sage");
142 assert_eq!(b.namespace, "sage");
143 }
144
145 #[test]
146 fn relays_stores_provided_urls() {
147 let b = PluginBuilder::new().relays(vec!["wss://relay.damus.io", "wss://nos.lol"]);
148 assert_eq!(b.relays, vec!["wss://relay.damus.io", "wss://nos.lol"]);
149 }
150
151 #[test]
152 fn max_payload_size_defaults_to_64kb() {
153 let b = PluginBuilder::new();
154 assert_eq!(b.max_payload_size, crate::state::DEFAULT_PAYLOAD_LIMIT);
155 }
156
157 #[test]
158 fn max_payload_size_setter_stores_value() {
159 let b = PluginBuilder::new().max_payload_size(128 * 1024);
160 assert_eq!(b.max_payload_size, 128 * 1024);
161 }
162}