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}