cobia/cape_registry_writer.rs
1use crate::C;
2use crate::*;
3use std::path::Path;
4
5/// Opens the COBIA registry for writing
6///
7/// This struct is used to write to the COBIA registry. To
8/// write values in the registry one obtains a sub-key
9/// using create_key, which is created if it does not already
10/// exist.
11///
12/// Values are not written to the registry until commit() is
13/// called.
14///
15/// # Example
16///
17/// ```
18/// use cobia::*;
19/// cobia::cape_open_initialize().unwrap();
20/// let writer = CapeRegistryWriter::new(false).unwrap();
21/// cobia::cape_open_cleanup();
22/// ```
23
24pub struct CapeRegistryWriter {
25 interface: *mut C::ICapeRegistryWriter,
26}
27
28impl CapeRegistryWriter {
29
30 /// Opens the COBIA registry for writing
31 ///
32 /// This function opens the COBIA registry for writing. If all_users is true
33 /// the registry is opened for all users, otherwise it is opened for the current
34 /// user.
35 ///
36 /// Opening the registry for writing to the all-users hive typically requires
37 /// administrative privileges.
38 ///
39 /// # Arguments
40 ///
41 /// * `all_users` - If true the registry is opened for all users, otherwise it is opened for the current user.
42 ///
43 /// # Returns
44 ///
45 /// A CapeRegistryWriter object if successful, otherwise a COBIAError.
46 ///
47 /// # Example
48 ///
49 /// ```
50 /// use cobia::*;
51 /// cobia::cape_open_initialize().unwrap();
52 /// let writer = CapeRegistryWriter::new(false).unwrap();
53 /// cobia::cape_open_cleanup();
54 /// ```
55
56 pub fn new(all_users: bool) -> Result<CapeRegistryWriter, COBIAError> {
57 let mut writer: *mut C::ICapeRegistryWriter = std::ptr::null_mut();
58 let result = unsafe {
59 C::capeGetRegistryWriter(all_users, &mut writer as *mut *mut C::ICapeRegistryWriter)
60 };
61 if result == COBIAERR_NOERROR {
62 Ok(CapeRegistryWriter { interface: writer })
63 } else {
64 Err(COBIAError::Code(result))
65 }
66 }
67
68 /// Creates or opens key in the registry
69 ///
70 /// This function creates or opens a key in the registry. If the key does not
71 /// exist it is created.
72 ///
73 /// # Arguments
74 ///
75 /// * `key_name` - The name of the key to create or open. Must be an absolute path, starting with a forward slash.
76 ///
77 /// # Returns
78 ///
79 /// A CapeRegistryKeyWriter object if successful, otherwise a COBIAError.
80 ///
81 /// # Example
82 ///
83 /// ```
84 /// use cobia::*;
85 /// cobia::cape_open_initialize().unwrap();
86 /// let writer = CapeRegistryWriter::new(false).unwrap();
87 /// let key=writer.create_key("/cobia_rust_create_key").unwrap();
88 /// //note the key does not actually appear in the registry at this point, as we did
89 /// //not call commit().
90 /// cobia::cape_open_cleanup();
91 /// ```
92
93 pub fn create_key(&self, key_name: &str) -> Result<CapeRegistryKeyWriter<'_>, COBIAError> {
94 let mut key: *mut C::ICapeRegistryKeyWriter = std::ptr::null_mut();
95 let result = unsafe {
96 ((*(*self.interface).vTbl).createKey.unwrap())(
97 (*self.interface).me,
98 CapeStringImpl::from_string(key_name)
99 .as_capechar_const()
100 .cast_mut(),
101 &mut key as *mut *mut C::ICapeRegistryKeyWriter,
102 )
103 };
104 if result == COBIAERR_NOERROR {
105 Ok(CapeRegistryKeyWriter { interface: key, writer:self })
106 } else {
107 Err(COBIAError::Code(result))
108 }
109 }
110
111 /// Opens key in the registry for reading.
112 ///
113 /// This function returns a read-only key; for a writable key, use create_key instead.
114 ///
115 /// This function opens an existing key in the registry. If the key does not
116 /// exist it fails.
117 ///
118 /// # Arguments
119 ///
120 /// * `key_name` - The name of the key to open. Must be an absolute path, starting with a forward slash.
121 ///
122 /// # Returns
123 ///
124 /// A CapeRegistryKeyWriter object if successful, otherwise a COBIAError.
125 ///
126 /// # Example
127 ///
128 /// ```
129 /// use cobia::*;
130 /// cobia::cape_open_initialize().unwrap();
131 /// let writer = CapeRegistryWriter::new(false).unwrap();
132 /// let key=writer.get_key("/types").unwrap();
133 /// cobia::cape_open_cleanup();
134 /// ```
135
136 pub fn get_key(&self, key_name: &str) -> Result<CapeRegistryKey, COBIAError> {
137 let mut key: *mut C::ICapeRegistryKey = std::ptr::null_mut();
138 let result = unsafe {
139 ((*(*self.interface).vTbl).getKey.unwrap())(
140 (*self.interface).me,
141 CapeStringImpl::from_string(key_name)
142 .as_capechar_const()
143 .cast_mut(),
144 &mut key as *mut *mut C::ICapeRegistryKey,
145 )
146 };
147 if result == COBIAERR_NOERROR {
148 Ok(CapeRegistryKey { interface: key })
149 } else {
150 Err(COBIAError::Code(result))
151 }
152 }
153
154 /// Deletes key in the registry
155 ///
156 /// This function deletes a key in the registry. If the key does not
157 /// exist it succeeds. Changes to do not take effect until commit() is called.
158 ///
159 /// # Arguments
160 ///
161 /// * `key_name` - The name of the key to delete. Must be an absolute path, starting with a forward slash.
162 ///
163 /// # Example
164 ///
165 /// ```
166 /// use cobia::*;
167 /// cobia::cape_open_initialize().unwrap();
168 /// //first create a sub key for the current user
169 /// {
170 /// let writer = CapeRegistryWriter::new(false).unwrap();
171 /// writer.create_key("/cobia_rust_delete_key").unwrap();
172 /// writer.commit().unwrap();
173 /// }
174 /// //now delete the key for the current user
175 /// let writer = CapeRegistryWriter::new(false).unwrap();
176 /// writer.delete_key("/cobia_rust_delete_key").unwrap();
177 /// writer.commit().unwrap();
178 /// cobia::cape_open_cleanup();
179 /// ```
180 ///
181 /// This will succeed, as the key does not exist:
182 ///
183 /// ```
184 /// use cobia::*;
185 /// cobia::cape_open_initialize().unwrap();
186 /// let writer = CapeRegistryWriter::new(false).unwrap();
187 /// writer.delete_key("/key_that_does_not_exist").unwrap();
188 /// cobia::cape_open_cleanup();
189 /// ```
190
191 pub fn delete_key(&self, key_name: &str) -> Result<(), COBIAError> {
192 let result = unsafe {
193 ((*(*self.interface).vTbl).deleteKey.unwrap())(
194 (*self.interface).me,
195 CapeStringImpl::from_string(key_name)
196 .as_capechar_const()
197 .cast_mut(),
198 )
199 };
200 if result == COBIAERR_NOERROR {
201 Ok(())
202 } else {
203 Err(COBIAError::Code(result))
204 }
205 }
206
207 /// Deletes a value in the registry
208 ///
209 /// This function deletes a value in the registry. If the value does not
210 /// exist it fails. Changes to do not take effect until commit() is called.
211 ///
212 /// # Arguments
213 ///
214 /// * `key_name` - The name of the key containing the value. Must be an absolute path, starting with a forward slash.
215 /// * `value_name` - The name of the value to delete.
216 ///
217 /// ```
218 /// use cobia::*;
219 /// cobia::cape_open_initialize().unwrap();
220 /// //first create a sub key for the current user
221 /// {
222 /// let writer = CapeRegistryWriter::new(false).unwrap();
223 /// writer.create_key("/cobia_rust_delete_value").unwrap().
224 /// set_string_value("test_value", "test_value").unwrap();
225 /// writer.commit().unwrap();
226 /// }
227 /// //now delete the value for the current user
228 /// let writer = CapeRegistryWriter::new(false).unwrap();
229 /// writer.delete_value("/cobia_rust_delete_value","test_value").unwrap();
230 /// writer.commit().unwrap();
231 /// cobia::cape_open_cleanup();
232 /// ```
233
234 pub fn delete_value(&self, key_name: &str, value_name: &str) -> Result<(), COBIAError> {
235 let result = unsafe {
236 ((*(*self.interface).vTbl).deleteValue.unwrap())(
237 (*self.interface).me,
238 CapeStringImpl::from_string(key_name)
239 .as_capechar_const()
240 .cast_mut(),
241 CapeStringImpl::from_string(value_name)
242 .as_capechar_const()
243 .cast_mut(),
244 )
245 };
246 if result == COBIAERR_NOERROR {
247 Ok(())
248 } else {
249 Err(COBIAError::Code(result))
250 }
251 }
252
253 /// Get a registrar object
254 ///
255 /// Registrar object facilitate the registration of PMCs.
256 ///
257 /// This function is not typically called directly; it is used
258 /// in the self-registation entry point, which is typically
259 /// generated using the pmc_entry_points! macro.
260
261 pub fn get_pmc_registrar(&self) -> Result<CapeRegistrar, COBIAError> {
262 let mut registrar: *mut C::ICapePMCRegistrar = std::ptr::null_mut();
263 let result = unsafe {
264 ((*(*self.interface).vTbl).getPMCRegistrar.unwrap())(
265 (*self.interface).me,
266 &mut registrar as *mut *mut C::ICapePMCRegistrar,
267 )
268 };
269 if result == COBIAERR_NOERROR {
270 Ok(CapeRegistrar {
271 interface: registrar,
272 })
273 } else {
274 Err(COBIAError::Code(result))
275 }
276 }
277
278 /// Unregister a PMC by uuid.
279 ///
280 /// This function unregisters a PMC by uuid.
281 /// Changes to do not take effect until commit() is called.
282 ///
283 /// This function is not typically called directly; it is used
284 /// in the self-unregistation entry point, which is typically
285 /// generated using the pmc_entry_points! macro.
286
287 pub fn unregister_pmc(&self, uuid: &CapeUUID) -> Result<(), COBIAError> {
288 let result = unsafe {
289 ((*(*self.interface).vTbl).unregisterPMC.unwrap())(
290 (*self.interface).me,
291 uuid as *const C::CapeUUID,
292 )
293 };
294 if result == COBIAERR_NOERROR {
295 Ok(())
296 } else {
297 Err(COBIAError::Code(result))
298 }
299 }
300
301 /// Unregister a service for a PMC by uuid.
302 ///
303 /// This function unregisters service for a PMC by uuid.
304 /// Changes to do not take effect until commit() is called.
305 ///
306 /// This function is not typically called directly; it is used
307 /// in the self-unregistation entry point, which is typically
308 /// generated using the pmc_entry_points! macro.
309
310 pub fn unregister_pmc_service(
311 &self,
312 uuid: &CapeUUID,
313 service: CapePMCServiceType,
314 ) -> Result<(), COBIAError> {
315 let result = unsafe {
316 ((*(*self.interface).vTbl).unregisterPMCService.unwrap())(
317 (*self.interface).me,
318 uuid as *const C::CapeUUID,
319 service as i32,
320 )
321 };
322 if result == COBIAERR_NOERROR {
323 Ok(())
324 } else {
325 Err(COBIAError::Code(result))
326 }
327 }
328
329 /// Commit changes to the registry
330 ///
331 /// This function commits changes to the registry. Changes are not
332 /// written to the registry until this function is called.
333 ///
334 /// # Example
335 ///
336 /// ```
337 /// use cobia::*;
338 /// cobia::cape_open_initialize().unwrap();
339 /// let writer = CapeRegistryWriter::new(false).unwrap();
340 /// writer.create_key("/cobia_rust_commit").unwrap().
341 /// set_string_value("test_value", "test_value").unwrap();
342 /// writer.commit().unwrap();
343 /// //now the key and value are in the registry
344 /// let key=writer.get_key("/cobia_rust_commit").unwrap();
345 /// let value=key.get_string_value("test_value",None).unwrap();
346 /// assert_eq!(value,"test_value");
347 /// //delete the key
348 /// let writer = CapeRegistryWriter::new(false).unwrap();
349 /// writer.delete_key("/cobia_rust_commit").unwrap();
350 /// writer.commit().unwrap();
351 /// cobia::cape_open_cleanup();
352
353 pub fn commit(&self) -> Result<(), COBIAError> {
354 let result = unsafe { ((*(*self.interface).vTbl).commit.unwrap())((*self.interface).me) };
355 if result == COBIAERR_NOERROR {
356 Ok(())
357 } else {
358 Err(COBIAError::Code(result))
359 }
360 }
361
362 /// Revert changes to the registry
363 ///
364 /// This function ignores all changes made to the registry
365 /// since the last commit without committing them.
366 ///
367 /// # Example
368 ///
369 /// ```
370 /// use cobia::*;
371 /// cobia::cape_open_initialize().unwrap();
372 /// let writer = CapeRegistryWriter::new(false).unwrap();
373 /// writer.create_key("/rust_cobia_test_key").unwrap().
374 /// set_string_value("test_value", "test_value").unwrap();
375 /// writer.revert().unwrap();
376 /// //start over
377 /// writer.create_key("/rust_cobia_test_key").unwrap().
378 /// set_string_value("test_value", "1-2-3-test").unwrap();
379 /// cobia::cape_open_cleanup();
380
381 pub fn revert(&self) -> Result<(), COBIAError> {
382 let result = unsafe { ((*(*self.interface).vTbl).revert.unwrap())((*self.interface).me) };
383 if result == COBIAERR_NOERROR {
384 Ok(())
385 } else {
386 Err(COBIAError::Code(result))
387 }
388 }
389
390 /// Register types from IDL
391 ///
392 /// This function registers types from IDL files. This function is not
393 /// typically called. It is called for example by the cobiaRegister
394 /// registration tool.
395 ///
396 /// # Arguments
397 ///
398 /// * `idl_files` - A vector of strings containing the paths to the IDL files.
399
400 pub fn register_types_from_idl<T: AsRef<str>>(
401 &self,
402 idl_files: &[T],
403 ) -> Result<(), COBIAError> {
404 let result = unsafe {
405 ((*(*self.interface).vTbl).registerTypesFromIDL.unwrap())(
406 (*self.interface).me,
407 (&CapeArrayStringVec::from_slice(idl_files).as_cape_array_string_in() as *const C::ICapeArrayString).cast_mut()
408 )
409 };
410 if result == COBIAERR_NOERROR {
411 Ok(())
412 } else {
413 Err(COBIAError::Code(result))
414 }
415 }
416
417 /// Register types from IDL
418 ///
419 /// This function registers types from IDL files. This function is not
420 /// typically called. It is called for example by the cobiaRegister
421 /// registration tool.
422 ///
423 /// # Arguments
424 ///
425 /// * `idl_files` - A vector of Paths to the IDL files.
426
427 pub fn register_types_from_idl_paths(&self, idl_files: &[&Path]) -> Result<(), COBIAError> {
428 let mut paths_as_string = Vec::<String>::new();
429 paths_as_string.reserve(idl_files.len());
430 for p in idl_files {
431 paths_as_string.push(p.to_str().unwrap().to_string());
432 }
433 self.register_types_from_idl(&paths_as_string)
434 }
435
436 ///Unregister types from IDL
437 ///
438 /// This function unregisters types from IDL files by library ID.
439 /// This function is not
440 /// typically called. It is called for example by the cobiaRegister
441 /// registration tool.
442 ///
443 /// # Arguments
444 ///
445 /// * `library_id` - The library ID of the types to unregister.
446
447 pub fn unregister_types(&self, library_id: &CapeUUID) -> Result<(), COBIAError> {
448 let result = unsafe {
449 ((*(*self.interface).vTbl).unregisterTypes.unwrap())(
450 (*self.interface).me,
451 library_id as *const C::CapeUUID,
452 )
453 };
454 if result == COBIAERR_NOERROR {
455 Ok(())
456 } else {
457 Err(COBIAError::Code(result))
458 }
459 }
460
461 /// Register proxy interface provider
462 ///
463 /// This function registers a proxy interface provider. This function is not
464 /// typically called. It is called for example by the cobiaRegister
465 /// registration tool.
466 ///
467 /// # Arguments
468 ///
469 /// * `library_id` - The library ID of the proxy interface provider.
470 /// * `service_type` - The service type of the proxy interface provider.
471 /// * `location` - The location of the proxy interface provider, typically a path to a shared library.
472
473 pub fn register_proxy_interface_provider(
474 &self,
475 library_id: &CapeUUID,
476 service_type: CapePMCServiceType,
477 location: &str,
478 ) -> Result<(), COBIAError> {
479 let result = unsafe {
480 ((*(*self.interface).vTbl)
481 .registerProxyInterfaceProvider
482 .unwrap())(
483 (*self.interface).me,
484 library_id as *const C::CapeUUID,
485 service_type as i32,
486 CapeStringImpl::from_string(location)
487 .as_capechar_const()
488 .cast_mut(),
489 )
490 };
491 if result == COBIAERR_NOERROR {
492 Ok(())
493 } else {
494 Err(COBIAError::Code(result))
495 }
496 }
497
498 /// Unregister proxy interface provider
499 ///
500 /// This function unregisters a proxy interface provider. This function is not
501 /// typically called. It is called for example by the cobiaRegister
502 /// registration tool.
503 ///
504 /// # Arguments
505 ///
506 /// * `library_id` - The library ID of the proxy interface provider.
507 /// * `service_type` - The service type of the proxy interface provider.
508
509 pub fn unregister_proxy_interface_provider(
510 &self,
511 library_id: &CapeUUID,
512 service_type: CapePMCServiceType,
513 ) -> Result<(), COBIAError> {
514 let result = unsafe {
515 ((*(*self.interface).vTbl)
516 .unregisterProxyInterfaceProvider
517 .unwrap())(
518 (*self.interface).me,
519 library_id as *const C::CapeUUID,
520 service_type as i32,
521 )
522 };
523 if result == COBIAERR_NOERROR {
524 Ok(())
525 } else {
526 Err(COBIAError::Code(result))
527 }
528 }
529}
530
531/// Release pointer
532///
533/// ICapeRegistryWriter derives from ICobiaBase, which contains
534/// addReference() and release(). The Drop trait calls release.
535
536impl Drop for CapeRegistryWriter {
537 fn drop(&mut self) {
538 unsafe {
539 ((*(*self.interface).vTbl).base.release.unwrap())((*self.interface).me);
540 }
541 }
542}
543
544/// Add pointer reference
545///
546/// ICapeRegistryWriter derives from ICobiaBase, which contains
547/// addReference() and release(). The Clone trait calls addReference.
548
549impl Clone for CapeRegistryWriter {
550 fn clone(&self) -> Self {
551 unsafe {
552 ((*(*self.interface).vTbl).base.addReference.unwrap())((*self.interface).me);
553 }
554 CapeRegistryWriter {
555 interface: self.interface,
556 }
557 }
558}