cobia/
cape_registry_key.rs

1use crate::C;
2use crate::*;
3
4/// Private trait that provides the key to the registry key
5/// used by CapeRegistryKeyReader trait
6pub(crate) trait CapeRegistryKeyReaderKey {
7	fn get_read_key(&self) -> *mut C::ICapeRegistryKey;
8}
9
10/// Public trait that provides methods to read from the registry key
11///
12/// This trait provides methods to read values from the registry key.
13/// This is implemented by CapeRegistryKey as well as CapeRegistryKeyWriter.
14///
15/// # Example
16///
17/// ```
18/// use cobia;
19/// use cobia::prelude::*;
20/// cobia::cape_open_initialize().unwrap();
21/// let lib_key=cobia::CapeRegistryKey::from_path("/types/libraries/{8d1d724f-ab15-48e5-80e4-a612468e68d4}").unwrap(); //points to the CAPE-OPEN 1.2 type library
22/// assert_eq!(lib_key.get_string_value("name",None).unwrap(), "CAPEOPEN_1_2".to_string()); //check its name
23/// cobia::cape_open_cleanup();
24/// ```
25
26#[allow(private_bounds)]
27pub trait CapeRegistryKeyReader: CapeRegistryKeyReaderKey {
28
29	/// Get a list of all values names in the key
30	///
31	/// This method returns a list of all value names in the key.
32	/// The values can be of different types: string, integer, UUID or empty.
33	///
34	/// # Example
35	///
36	/// ```
37	/// use cobia;
38	/// use cobia::prelude::*;
39	/// cobia::cape_open_initialize().unwrap();
40	/// let lib_key=cobia::CapeRegistryKey::from_path("/types/libraries/{8d1d724f-ab15-48e5-80e4-a612468e68d4}").unwrap(); //points to the CAPE-OPEN 1.2 type library
41	/// assert!(lib_key.get_values().unwrap().contains(&("name".to_string()))); //see that 'name' is amongst them
42	/// cobia::cape_open_cleanup();
43	/// ```
44
45	fn get_values(&self) -> Result<Vec<String>, COBIAError> {
46		let mut sa = CapeArrayStringVec::new();
47		let iface = self.get_read_key();
48		let result = unsafe {
49			((*(*iface).vTbl).getValues.unwrap())((*iface).me,(&sa.as_cape_array_string_out() as *const C::ICapeArrayString).cast_mut())
50		};
51		if result == COBIAERR_NOERROR {
52			Ok(sa.as_string_vec())
53		} else {
54			Err(COBIAError::Code(result))
55		}
56	}
57	
58	/// Get a list of all sub key names in the key
59	///
60	/// This method returns a list of all sub key names in the key.
61	///
62	/// # Example
63	///
64	/// ```
65	/// use cobia;
66	/// use cobia::prelude::*;
67	/// cobia::cape_open_initialize().unwrap();
68	/// let lib_key=cobia::CapeRegistryKey::from_path("/types").unwrap(); //points to the CAPE-OPEN 1.2 type library
69	/// let keys=lib_key.get_keys().unwrap();
70	/// assert!(keys.contains(&("categories".to_string()))); //see that 'categories' is amongst them
71	/// assert!(keys.contains(&("interfaces".to_string()))); //see that 'interfaces' is amongst them
72	/// assert!(keys.contains(&("enumerations".to_string()))); //see that 'enumerations' is amongst them
73	/// assert!(keys.contains(&("libraries".to_string()))); //see that 'libraries' is amongst them
74	/// cobia::cape_open_cleanup();
75	/// ```
76
77	fn get_keys(&self) -> Result<Vec<String>, COBIAError> {
78		let mut sa = CapeArrayStringVec::new();
79		let iface = self.get_read_key();
80		let result =
81			unsafe { ((*(*iface).vTbl).getKeys.unwrap())((*iface).me, (&sa.as_cape_array_string_out() as *const C::ICapeArrayString).cast_mut()) };
82		if result == COBIAERR_NOERROR {
83			Ok(sa.as_string_vec())
84		} else {
85			Err(COBIAError::Code(result))
86		}
87	}
88
89	/// Get the type of a value
90	///
91	/// This method returns the type of a value in the key.
92	/// The value can be of different types, such as string, integer, or UUID.
93	///
94	/// # Example
95	///
96	/// ```
97	/// use cobia;
98	/// use cobia::prelude::*;
99	/// cobia::cape_open_initialize().unwrap();
100	/// let lib_key=cobia::CapeRegistryKey::from_path("/types/libraries/{8d1d724f-ab15-48e5-80e4-a612468e68d4}").unwrap(); //points to the CAPE-OPEN 1.2 type library
101	/// assert_eq!(lib_key.get_value_type("name",None).unwrap(), cobia::CapeRegistryValueType::String); //check that 'name' is a string
102	/// cobia::cape_open_cleanup();
103
104	fn get_value_type(
105		&self,
106		value_name: &str,
107		sub_key: Option<&str>,
108	) -> Result<CapeRegistryValueType, COBIAError> {
109		let mut val: i32 = 0;
110		let iface = self.get_read_key();
111		let string_constant;  
112		let sub_key=match sub_key {
113			Some(sub_key) => {
114					string_constant=CapeStringImpl::from(sub_key); //must remain in scope
115					string_constant.as_capechar_const()
116				},
117			None => std::ptr::null(),
118		};
119		let result = unsafe {
120			((*(*iface).vTbl).getValueType.unwrap())(
121				(*iface).me,
122				CapeStringImpl::from_string(value_name).as_capechar_const(),
123				sub_key,
124				&mut val as *mut i32,
125			)
126		};
127		if result == COBIAERR_NOERROR {
128			match CapeRegistryValueType::from(val) {
129				Some(v) => Ok(v),
130				None => Err(COBIAError::Code(COBIAERR_REGISTRY_INVALIDVALUE)),
131			}
132		} else {
133			Err(COBIAError::Code(result))
134		}
135	}
136
137	/// Get a string value
138	///
139	/// This method returns a string value from the key.
140	///
141	/// # Arguments
142	///
143	/// * `value_name` - The name of the value to get
144	/// * `sub_key` - The name of the sub key to get the value from. If None, the value is taken from the key itself.
145	///
146	/// # Example
147	///
148	/// ```
149	/// use cobia;
150	/// use cobia::prelude::*;
151	/// cobia::cape_open_initialize().unwrap();
152	/// let lib_key=cobia::CapeRegistryKey::from_path("/types/interfaces/{12ebf184-f47a-4407-b52a-7fcc0a70451c}").unwrap(); //points to the CAPE-OPEN 1.2 ICapeIdentification interface
153	/// assert_eq!(lib_key.get_string_value("name",None).unwrap(), "ICapeIdentification".to_string()); //check its name
154	/// cobia::cape_open_cleanup();
155	/// ```
156	///
157	/// Or, equivalently,
158	///
159	/// ```
160	/// use cobia;
161	/// use cobia::prelude::*;
162	/// cobia::cape_open_initialize().unwrap();
163	/// let lib_key=cobia::CapeRegistryKey::from_path("/types").unwrap(); //points to the types key
164	/// assert_eq!(lib_key.get_string_value("name",Some("interfaces/{12ebf184-f47a-4407-b52a-7fcc0a70451c}")).unwrap(), "ICapeIdentification".to_string()); //check name of ICapeIdentification interface
165	/// cobia::cape_open_cleanup();
166	/// ```
167	/// 
168	/// This will not work, as the vlaue is not a string
169	///
170	/// ```should_panic
171	/// use cobia;
172	/// use cobia::prelude::*;
173	/// cobia::cape_open_initialize().unwrap();
174	/// let lib_key=cobia::CapeRegistryKey::from_path("/types/interfaces/{}").unwrap(); //points to the CAPE-OPEN 1.2 type library
175	/// assert_eq!(lib_key.get_string_value("version",None).unwrap(), "1.2".to_string()); //check its version
176	/// let str=lib_key.get_string_value("library",None).unwrap(); //fails, this is a uuid
177	/// cobia::cape_open_cleanup();
178	/// ```
179
180	fn get_string_value(
181		&self,
182		value_name: &str,
183		sub_key: Option<&str>,
184	) -> Result<String, COBIAError> {
185		let mut s = CapeStringImpl::new();
186		let iface = self.get_read_key();
187		let string_constant;
188		let sub_key=match sub_key {
189			Some(sub_key) => {
190					string_constant=CapeStringImpl::from(sub_key); //must remain in scope
191					string_constant.as_capechar_const()
192			},
193			None => std::ptr::null(),
194		};
195		let result = unsafe {
196			((*(*iface).vTbl).getStringValue.unwrap())(
197				(*iface).me,
198				CapeStringImpl::from(value_name).as_capechar_const().cast_mut(),
199				sub_key,
200				(&s.as_cape_string_out() as *const C::ICapeString).cast_mut()
201			)
202		};
203		if result == COBIAERR_NOERROR {
204			Ok(s.as_string())
205		} else {
206			Err(COBIAError::Code(result))
207		}
208	}
209
210	/// Get an integer value
211	///
212	/// This method returns an integer value from the key.
213	///
214	/// # Arguments
215	///
216	/// * `value_name` - The name of the value to get
217	/// * `sub_key` - The name of the sub key to get the value from. If None, the value is taken from the key itself.
218	///
219	/// # Example
220	///
221	/// ```
222	/// use cobia;
223	/// use cobia::prelude::*;
224	/// cobia::cape_open_initialize().unwrap();
225	/// let lib_key=cobia::CapeRegistryKey::from_path("/types/interfaces/{b135a443-2ed8-45ef-bb2d-e68d2e631c31}").unwrap(); //points to the CAPE-OPEN 1.2 ICapeCollection interface
226	/// assert_eq!(lib_key.get_integer_value("numberOfTemplateArguments",None).unwrap(), 1); //check number of template arguments
227	/// cobia::cape_open_cleanup();
228	/// ```
229	///
230	/// Or, equivalently,
231	///
232	/// ```
233	/// use cobia;
234	/// use cobia::prelude::*;
235	/// cobia::cape_open_initialize().unwrap();
236	/// let lib_key=cobia::CapeRegistryKey::from_path("/types/interfaces").unwrap(); //points to the interfaces key
237	/// assert_eq!(lib_key.get_integer_value("numberOfTemplateArguments",Some("{b135a443-2ed8-45ef-bb2d-e68d2e631c31}")).unwrap(), 1); //check number of template arguments of ICapeCollection interface
238	/// cobia::cape_open_cleanup();
239	/// ```
240
241	fn get_integer_value(
242		&self,
243		value_name: &str,
244		sub_key: Option<&str>,
245	) -> Result<i32, COBIAError> {
246		let mut i = 0i32;
247		let iface = self.get_read_key();
248		let string_constant;
249		let sub_key=match sub_key {
250			Some(sub_key) => {
251					string_constant=CapeStringImpl::from(sub_key); //must remain in scope
252					string_constant.as_capechar_const()
253			},
254			None => std::ptr::null(),
255		};
256		let result = unsafe {
257			((*(*iface).vTbl).getIntegerValue.unwrap())(
258				(*iface).me,
259				CapeStringImpl::from(value_name).as_capechar_const().cast_mut(),
260				sub_key,
261				&mut i as *mut i32,
262			)
263		};
264		if result == COBIAERR_NOERROR {
265			Ok(i)
266		} else {
267			Err(COBIAError::Code(result))
268		}
269	}
270
271	/// Get a UUID value
272	///
273	/// This method returns a UUID value from the key.
274	///
275	/// # Arguments
276	///
277	/// * `value_name` - The name of the value to get
278	/// * `sub_key` - The name of the sub key to get the value from. If None, the value is taken from the key itself.
279	///
280	/// # Example
281	///
282	/// ```
283	/// use cobia;
284	/// use cobia::cape_open_1_2;
285	/// use cobia::prelude::*;
286	/// cobia::cape_open_initialize().unwrap();
287	/// let lib_key=cobia::CapeRegistryKey::from_path("/types/interfaces/{12ebf184-f47a-4407-b52a-7fcc0a70451c}").unwrap(); //points to the CAPE-OPEN 1.2 ICapeIdentification interface
288	/// assert_eq!(lib_key.get_uuid_value("library",None).unwrap(), cobia::cape_open_1_2::LIBRARY_ID); //check library id
289	/// cobia::cape_open_cleanup();
290	/// ```
291
292	fn get_uuid_value(&self, value_name: &str, sub_key: Option<&str>) -> Result<CapeUUID, COBIAError> {
293		let mut uuid = CapeUUID {
294			data: [0; 16],
295		};
296		let iface = self.get_read_key();
297		let string_constant;
298		let sub_key=match sub_key {
299			Some(sub_key) => {
300					string_constant=CapeStringImpl::from(sub_key); //must remain in scope
301					string_constant.as_capechar_const()
302			},
303			None => std::ptr::null(),
304		};
305		let result = unsafe {
306			((*(*iface).vTbl).getUUIDValue.unwrap())(
307				(*iface).me,
308				CapeStringImpl::from(value_name).as_capechar_const().cast_mut(),
309				sub_key,
310				&mut uuid as *mut CapeUUID,
311			)
312		};
313		if result == COBIAERR_NOERROR {
314			Ok(uuid)
315		} else {
316			Err(COBIAError::Code(result))
317		}
318	}
319
320	/// Get a sub key
321	///
322	/// This method returns a sub key from the key.
323	///
324	/// # Arguments
325	///
326	/// * `key_name` - The name of the sub key to get
327	///
328	/// # Example
329	///
330	/// ```
331	/// use cobia;
332	/// use cobia::prelude::*;
333	/// cobia::cape_open_initialize().unwrap();
334	/// let lib_key=cobia::CapeRegistryKey::from_path("/types/interfaces").unwrap(); //points to the interfaces key
335	/// let icape_collection_key=lib_key.get_sub_key("{b135a443-2ed8-45ef-bb2d-e68d2e631c31}").unwrap(); //points to the ICapeCollection interface
336	/// assert_eq!(icape_collection_key.get_string_value("name",None).unwrap(), "ICapeCollection".to_string()); //check its name
337	/// cobia::cape_open_cleanup();
338	/// ```
339
340	fn get_sub_key(&self, key_name: &str) -> Result<CapeRegistryKey, COBIAError> {
341		let mut key: *mut C::ICapeRegistryKey = std::ptr::null_mut();
342		let iface = self.get_read_key();
343		let result = unsafe {
344			((*(*iface).vTbl).getSubKey.unwrap())(
345				(*iface).me,
346				CapeStringImpl::from(key_name).as_capechar_const(),
347				&mut key as *mut *mut C::ICapeRegistryKey,
348			)
349		};
350		if result == COBIAERR_NOERROR {
351			Ok(CapeRegistryKey { interface: key })
352		} else {
353			Err(COBIAError::Code(result))
354		}
355	}
356
357	/// Check whether a particular value is in the registry for all users or just the current user
358	///
359	/// This method checks whether a particular value is in the registry for all users or just the current user.
360	///
361	/// # Arguments
362	///
363	/// * `value_name` - The name of the value to check
364	///
365	/// # Example
366	///
367	/// ```
368	/// use cobia;
369	/// use cobia::prelude::*;
370	/// cobia::cape_open_initialize().unwrap();
371	/// let lib_key=cobia::CapeRegistryKey::from_path("/types/interfaces/{12ebf184-f47a-4407-b52a-7fcc0a70451c}").unwrap(); //points to the CAPE-OPEN 1.2 ICapeIdentification interface
372	/// println!("The name for  CAPE-OPEN 1.2 ICapeIdentification is in the {} part of the registry", 
373	///             if lib_key.is_all_users("name").unwrap() {"all users"} else {"current user"} ); 
374	/// cobia::cape_open_cleanup();
375	/// ```
376
377	fn is_all_users(&self, value_name: &str) -> Result<bool, COBIAError> {
378		let mut all_users = 0u32;
379		let iface = self.get_read_key();
380		let result = unsafe {
381			((*(*iface).vTbl).isAllUsers.unwrap())(
382				(*iface).me,
383				CapeStringImpl::from(value_name).as_capechar_const(),
384				&mut all_users as *mut u32,
385			)
386		};
387		if result == COBIAERR_NOERROR {
388			Ok(all_users != 0)
389		} else {
390			Err(COBIAError::Code(result))
391		}
392	}
393
394}
395
396/// A class that provides access to a COBIA registry key in a read-only manner
397///
398/// This class provides access to a COBIA registry key in a read-only manner; for
399/// writing to the COBIA registry, consider using CapeRegistryKeyWriter.
400///
401/// # Example
402///
403/// ```
404/// use cobia;
405/// use cobia::prelude::*;
406/// cobia::cape_open_initialize().unwrap();
407/// let lib_key=cobia::CapeRegistryKey::from_path("/types/libraries/{8d1d724f-ab15-48e5-80e4-a612468e68d4}").unwrap(); //points to the CAPE-OPEN 1.2 type library
408/// assert_eq!(lib_key.get_string_value("name",None).unwrap(), "CAPEOPEN_1_2".to_string()); //check its name
409/// cobia::cape_open_cleanup();
410/// ```
411
412pub struct CapeRegistryKey {
413	pub(crate) interface: *mut C::ICapeRegistryKey,
414}
415
416impl CapeRegistryKey {
417
418	/// Get a reference to the root key
419	///
420	/// This method returns a reference to the root key.
421	///
422	/// # Example
423	///
424	/// ```
425	/// use cobia;
426	/// use cobia::prelude::*;
427	/// cobia::cape_open_initialize().unwrap();
428	/// let root_key=cobia::CapeRegistryKey::new().unwrap(); //points to the root key
429	/// //note the absense of a leading slash in the sub-key to the root key
430	/// assert_eq!(root_key.get_string_value("name",Some("types/libraries/{8d1d724f-ab15-48e5-80e4-a612468e68d4}")).unwrap(), "CAPEOPEN_1_2".to_string()); //check name of CAPE-OPEN 1.2 type library
431	/// cobia::cape_open_cleanup();
432	/// ```
433
434	pub fn new() -> Result<CapeRegistryKey, COBIAError> {
435		let mut key: *mut C::ICapeRegistryKey = std::ptr::null_mut();
436		let result = unsafe {
437			C::capeGetRegistryKey(
438				std::ptr::null_mut(),
439				&mut key as *mut *mut C::ICapeRegistryKey,
440			)
441		};
442		if result == COBIAERR_NOERROR {
443			Ok(CapeRegistryKey { interface: key })
444		} else {
445			Err(COBIAError::Code(result))
446		}
447	}
448
449	/// Get a reference to a key from a path
450	///
451	/// This method returns a reference to a key from a path.
452	///
453	/// # Arguments
454	///
455	/// * `loc` - The path to the key to get
456	///
457	/// # Example
458	///
459	/// ```
460	/// use cobia;
461	/// use cobia::prelude::*;
462	/// cobia::cape_open_initialize().unwrap();
463	/// let lib_key=cobia::CapeRegistryKey::from_path("/types/libraries/{8d1d724f-ab15-48e5-80e4-a612468e68d4}").unwrap(); //points to the CAPE-OPEN 1.2 type library
464	/// assert_eq!(lib_key.get_string_value("name",None).unwrap(), "CAPEOPEN_1_2".to_string()); //check its name
465	/// cobia::cape_open_cleanup();
466	/// ```
467
468	pub fn from_path(loc: &str) -> Result<CapeRegistryKey, COBIAError> {
469		let mut key: *mut C::ICapeRegistryKey = std::ptr::null_mut();
470		let result = unsafe {
471			C::capeGetRegistryKey(
472				CapeStringImpl::from(loc).as_capechar_const(),
473				&mut key as *mut *mut C::ICapeRegistryKey,
474			)
475		};
476		if result == COBIAERR_NOERROR {
477			Ok(CapeRegistryKey { interface: key })
478		} else {
479			Err(COBIAError::Code(result))
480		}
481	}
482}
483
484impl CapeRegistryKeyReaderKey for CapeRegistryKey {
485	fn get_read_key(&self) -> *mut C::ICapeRegistryKey {
486		self.interface
487	}
488}
489
490impl CapeRegistryKeyReader for CapeRegistryKey {}
491
492/// Release pointer
493///
494/// ICapeRegistryKey derives from ICobiaBase, which contains
495/// addReference() and release(). The Drop trait calls release.
496
497impl Drop for CapeRegistryKey {
498	fn drop(&mut self) {
499		unsafe {
500			((*(*self.interface).vTbl).base.release.unwrap())((*self.interface).me);
501		}
502	}
503}
504
505/// Add pointer reference
506///
507/// ICapeRegistryKey derives from ICobiaBase, which contains
508/// addReference() and release(). The Clone trait calls addReference.
509
510impl Clone for CapeRegistryKey {
511	fn clone(&self) -> Self {
512		unsafe {
513			((*(*self.interface).vTbl).base.addReference.unwrap())((*self.interface).me);
514		}
515		CapeRegistryKey {
516			interface: self.interface,
517		}
518	}
519}