Skip to main content

systemconfiguration/
dynamic_store.rs

1use crate::{
2    bridge::{self, CStringArray},
3    error::Result,
4    ffi,
5    PropertyList, SystemConfigurationError,
6};
7
8#[derive(Clone, Debug)]
9pub struct DynamicStore {
10    raw: bridge::OwnedHandle,
11}
12
13impl DynamicStore {
14    pub fn new(name: &str) -> Result<Self> {
15        Self::create(name, false)
16    }
17
18    pub fn new_with_session_keys(name: &str) -> Result<Self> {
19        Self::create(name, true)
20    }
21
22    fn create(name: &str, use_session_keys: bool) -> Result<Self> {
23        let name = bridge::cstring(name, "sc_dynamic_store_create")?;
24        let raw = unsafe { ffi::dynamic_store::sc_dynamic_store_create(name.as_ptr(), u8::from(use_session_keys)) };
25        let raw = bridge::owned_handle_or_last("sc_dynamic_store_create", raw)?;
26        Ok(Self { raw })
27    }
28
29    pub fn copy_value(&self, key: &str) -> Result<Option<PropertyList>> {
30        let key = bridge::cstring(key, "sc_dynamic_store_copy_value")?;
31        let raw = unsafe { ffi::dynamic_store::sc_dynamic_store_copy_value(self.raw.as_ptr(), key.as_ptr()) };
32        Ok(unsafe { bridge::OwnedHandle::from_raw(raw) }.map(PropertyList::from_owned_handle))
33    }
34
35    pub fn copy_multiple<K, P>(&self, keys: &[K], patterns: &[P]) -> Result<Option<PropertyList>>
36    where
37        K: AsRef<str>,
38        P: AsRef<str>,
39    {
40        let keys = CStringArray::new(keys, "sc_dynamic_store_copy_multiple")?;
41        let patterns = CStringArray::new(patterns, "sc_dynamic_store_copy_multiple")?;
42        let raw = unsafe {
43            ffi::dynamic_store::sc_dynamic_store_copy_multiple(
44                self.raw.as_ptr(),
45                keys.as_ptr(),
46                keys.count(),
47                patterns.as_ptr(),
48                patterns.count(),
49            )
50        };
51        Ok(unsafe { bridge::OwnedHandle::from_raw(raw) }.map(PropertyList::from_owned_handle))
52    }
53
54    pub fn add_value(&self, key: &str, value: &PropertyList) -> Result<()> {
55        let key = bridge::cstring(key, "sc_dynamic_store_add_value")?;
56        let ok = unsafe {
57            ffi::dynamic_store::sc_dynamic_store_add_value(self.raw.as_ptr(), key.as_ptr(), value.as_ptr())
58        };
59        bridge::bool_result("sc_dynamic_store_add_value", ok)
60    }
61
62    pub fn add_temporary_value(&self, key: &str, value: &PropertyList) -> Result<()> {
63        let key = bridge::cstring(key, "sc_dynamic_store_add_temporary_value")?;
64        let ok = unsafe {
65            ffi::dynamic_store::sc_dynamic_store_add_temporary_value(
66                self.raw.as_ptr(),
67                key.as_ptr(),
68                value.as_ptr(),
69            )
70        };
71        bridge::bool_result("sc_dynamic_store_add_temporary_value", ok)
72    }
73
74    pub fn set_value(&self, key: &str, value: &PropertyList) -> Result<()> {
75        let key = bridge::cstring(key, "sc_dynamic_store_set_value")?;
76        let ok = unsafe {
77            ffi::dynamic_store::sc_dynamic_store_set_value(self.raw.as_ptr(), key.as_ptr(), value.as_ptr())
78        };
79        bridge::bool_result("sc_dynamic_store_set_value", ok)
80    }
81
82    pub fn remove_value(&self, key: &str) -> Result<()> {
83        let key = bridge::cstring(key, "sc_dynamic_store_remove_value")?;
84        let ok = unsafe { ffi::dynamic_store::sc_dynamic_store_remove_value(self.raw.as_ptr(), key.as_ptr()) };
85        bridge::bool_result("sc_dynamic_store_remove_value", ok)
86    }
87
88    pub fn notify_value(&self, key: &str) -> Result<()> {
89        let key = bridge::cstring(key, "sc_dynamic_store_notify_value")?;
90        let ok = unsafe { ffi::dynamic_store::sc_dynamic_store_notify_value(self.raw.as_ptr(), key.as_ptr()) };
91        bridge::bool_result("sc_dynamic_store_notify_value", ok)
92    }
93
94    pub fn copy_key_list(&self, pattern: &str) -> Result<Vec<String>> {
95        let pattern = bridge::cstring(pattern, "sc_dynamic_store_copy_key_list")?;
96        let raw = unsafe { ffi::dynamic_store::sc_dynamic_store_copy_key_list(self.raw.as_ptr(), pattern.as_ptr()) };
97        Ok(bridge::take_string_array(raw))
98    }
99
100    pub fn set_notification_keys<K, P>(&self, keys: &[K], patterns: &[P]) -> Result<()>
101    where
102        K: AsRef<str>,
103        P: AsRef<str>,
104    {
105        let keys = CStringArray::new(keys, "sc_dynamic_store_set_notification_keys")?;
106        let patterns = CStringArray::new(patterns, "sc_dynamic_store_set_notification_keys")?;
107        let ok = unsafe {
108            ffi::dynamic_store::sc_dynamic_store_set_notification_keys(
109                self.raw.as_ptr(),
110                keys.as_ptr(),
111                keys.count(),
112                patterns.as_ptr(),
113                patterns.count(),
114            )
115        };
116        bridge::bool_result("sc_dynamic_store_set_notification_keys", ok)
117    }
118
119    pub fn copy_notified_keys(&self) -> Vec<String> {
120        let raw = unsafe { ffi::dynamic_store::sc_dynamic_store_copy_notified_keys(self.raw.as_ptr()) };
121        bridge::take_string_array(raw)
122    }
123
124    pub fn computer_name(&self) -> Option<String> {
125        bridge::take_optional_string(unsafe {
126            ffi::dynamic_store::sc_dynamic_store_copy_computer_name(self.raw.as_ptr())
127        })
128    }
129
130    pub fn local_host_name(&self) -> Option<String> {
131        bridge::take_optional_string(unsafe {
132            ffi::dynamic_store::sc_dynamic_store_copy_local_host_name(self.raw.as_ptr())
133        })
134    }
135
136    pub fn location(&self) -> Option<String> {
137        bridge::take_optional_string(unsafe {
138            ffi::dynamic_store::sc_dynamic_store_copy_location(self.raw.as_ptr())
139        })
140    }
141
142    pub fn proxies(&self) -> Option<PropertyList> {
143        let raw = unsafe { ffi::dynamic_store::sc_dynamic_store_copy_proxies(self.raw.as_ptr()) };
144        unsafe { bridge::OwnedHandle::from_raw(raw) }.map(PropertyList::from_owned_handle)
145    }
146
147    pub fn dhcp_info(&self, service_id: Option<&str>) -> Result<Option<PropertyList>> {
148        let service_id = bridge::optional_cstring(service_id, "sc_dynamic_store_copy_dhcp_info")?;
149        let raw = unsafe {
150            ffi::dynamic_store::sc_dynamic_store_copy_dhcp_info(
151                self.raw.as_ptr(),
152                service_id.as_ref().map_or(std::ptr::null(), |value| value.as_ptr()),
153            )
154        };
155        Ok(unsafe { bridge::OwnedHandle::from_raw(raw) }.map(PropertyList::from_owned_handle))
156    }
157
158    pub fn network_global_entity_key(domain: &str, entity: &str) -> Result<String> {
159        let domain = bridge::cstring(domain, "sc_dynamic_store_key_create_network_global_entity")?;
160        let entity = bridge::cstring(entity, "sc_dynamic_store_key_create_network_global_entity")?;
161        bridge::take_optional_string(unsafe {
162            ffi::dynamic_store::sc_dynamic_store_key_create_network_global_entity(
163                domain.as_ptr(),
164                entity.as_ptr(),
165            )
166        })
167        .ok_or_else(|| {
168            SystemConfigurationError::null(
169                "sc_dynamic_store_key_create_network_global_entity",
170                "bridge returned null dynamic-store global entity key",
171            )
172        })
173    }
174
175    pub fn network_interface_key(domain: &str) -> Result<String> {
176        let domain = bridge::cstring(domain, "sc_dynamic_store_key_create_network_interface")?;
177        bridge::take_optional_string(unsafe {
178            ffi::dynamic_store::sc_dynamic_store_key_create_network_interface(domain.as_ptr())
179        })
180        .ok_or_else(|| {
181            SystemConfigurationError::null(
182                "sc_dynamic_store_key_create_network_interface",
183                "bridge returned null dynamic-store interface key",
184            )
185        })
186    }
187
188    pub fn network_interface_entity_key(
189        domain: &str,
190        interface_name: &str,
191        entity: Option<&str>,
192    ) -> Result<String> {
193        let domain = bridge::cstring(domain, "sc_dynamic_store_key_create_network_interface_entity")?;
194        let interface_name = bridge::cstring(
195            interface_name,
196            "sc_dynamic_store_key_create_network_interface_entity",
197        )?;
198        let entity = bridge::optional_cstring(entity, "sc_dynamic_store_key_create_network_interface_entity")?;
199        bridge::take_optional_string(unsafe {
200            ffi::dynamic_store::sc_dynamic_store_key_create_network_interface_entity(
201                domain.as_ptr(),
202                interface_name.as_ptr(),
203                entity.as_ref().map_or(std::ptr::null(), |value| value.as_ptr()),
204            )
205        })
206        .ok_or_else(|| {
207            SystemConfigurationError::null(
208                "sc_dynamic_store_key_create_network_interface_entity",
209                "bridge returned null dynamic-store interface-entity key",
210            )
211        })
212    }
213
214    pub fn network_service_entity_key(
215        domain: &str,
216        service_id: &str,
217        entity: Option<&str>,
218    ) -> Result<String> {
219        let domain = bridge::cstring(domain, "sc_dynamic_store_key_create_network_service_entity")?;
220        let service_id = bridge::cstring(service_id, "sc_dynamic_store_key_create_network_service_entity")?;
221        let entity = bridge::optional_cstring(entity, "sc_dynamic_store_key_create_network_service_entity")?;
222        bridge::take_optional_string(unsafe {
223            ffi::dynamic_store::sc_dynamic_store_key_create_network_service_entity(
224                domain.as_ptr(),
225                service_id.as_ptr(),
226                entity.as_ref().map_or(std::ptr::null(), |value| value.as_ptr()),
227            )
228        })
229        .ok_or_else(|| {
230            SystemConfigurationError::null(
231                "sc_dynamic_store_key_create_network_service_entity",
232                "bridge returned null dynamic-store service-entity key",
233            )
234        })
235    }
236
237    pub fn computer_name_key() -> Result<String> {
238        bridge::take_optional_string(unsafe { ffi::dynamic_store::sc_dynamic_store_key_create_computer_name() })
239            .ok_or_else(|| {
240                SystemConfigurationError::null(
241                    "sc_dynamic_store_key_create_computer_name",
242                    "bridge returned null computer-name notification key",
243                )
244            })
245    }
246
247    pub fn console_user_key() -> Result<String> {
248        bridge::take_optional_string(unsafe { ffi::dynamic_store::sc_dynamic_store_key_create_console_user() })
249            .ok_or_else(|| {
250                SystemConfigurationError::null(
251                    "sc_dynamic_store_key_create_console_user",
252                    "bridge returned null console-user notification key",
253                )
254            })
255    }
256
257    pub fn host_names_key() -> Result<String> {
258        bridge::take_optional_string(unsafe { ffi::dynamic_store::sc_dynamic_store_key_create_host_names() })
259            .ok_or_else(|| {
260                SystemConfigurationError::null(
261                    "sc_dynamic_store_key_create_host_names",
262                    "bridge returned null host-names notification key",
263                )
264            })
265    }
266
267    pub fn location_key() -> Result<String> {
268        bridge::take_optional_string(unsafe { ffi::dynamic_store::sc_dynamic_store_key_create_location() })
269            .ok_or_else(|| {
270                SystemConfigurationError::null(
271                    "sc_dynamic_store_key_create_location",
272                    "bridge returned null location notification key",
273                )
274            })
275    }
276
277    pub fn proxies_key() -> Result<String> {
278        bridge::take_optional_string(unsafe { ffi::dynamic_store::sc_dynamic_store_key_create_proxies() })
279            .ok_or_else(|| {
280                SystemConfigurationError::null(
281                    "sc_dynamic_store_key_create_proxies",
282                    "bridge returned null proxies notification key",
283                )
284            })
285    }
286}