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}