1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
use std::marker::PhantomData;
use std::ptr;
use std::sync::RwLockReadGuard;
use ffi;
use {Protocol, TOKEN, Token};
use error::Result;
use utils::{self, StrResult};
#[derive(Debug, Copy, Clone)]
pub struct EngineInfo<'a, T: 'a> {
raw: ffi::gpgme_engine_info_t,
phantom: PhantomData<&'a T>,
}
impl<'a, T> EngineInfo<'a, T> {
pub unsafe fn from_raw<'b>(raw: ffi::gpgme_engine_info_t) -> EngineInfo<'b, T> {
debug_assert!(!raw.is_null());
EngineInfo {
raw: raw,
phantom: PhantomData,
}
}
pub fn raw(&self) -> ffi::gpgme_engine_info_t {
self.raw
}
pub fn protocol(&self) -> Protocol {
unsafe { Protocol::from_raw((*self.raw).protocol) }
}
pub fn filename(&self) -> StrResult<'a> {
unsafe { utils::from_cstr((*self.raw).file_name) }
}
pub fn home_dir(&self) -> StrResult<'a> {
unsafe { utils::from_cstr((*self.raw).file_name) }
}
pub fn version(&self) -> StrResult<'a> {
unsafe { utils::from_cstr((*self.raw).version) }
}
pub fn required_version(&self) -> StrResult<'a> {
unsafe { utils::from_cstr((*self.raw).req_version) }
}
}
#[derive(Debug, Copy, Clone)]
pub struct EngineInfoIter<'a, T: 'a> {
current: ffi::gpgme_engine_info_t,
phantom: PhantomData<&'a T>,
}
impl<'a, T> EngineInfoIter<'a, T> {
pub unsafe fn from_list<'b>(raw: ffi::gpgme_engine_info_t) -> EngineInfoIter<'b, T> {
EngineInfoIter {
current: raw,
phantom: PhantomData,
}
}
}
impl<'a, T> Iterator for EngineInfoIter<'a, T> {
list_iterator!(EngineInfo<'a, T>, EngineInfo::from_raw);
}
pub struct EngineInfoGuard(RwLockReadGuard<'static, ()>);
impl EngineInfoGuard {
pub fn new(_token: &Token) -> Result<EngineInfoGuard> {
let lock = TOKEN.0.engine_info.read().expect("Engine info lock could not be acquired");
unsafe {
let mut info = ptr::null_mut();
return_err!(ffi::gpgme_get_engine_info(&mut info));
}
Ok(EngineInfoGuard(lock))
}
pub fn get(&self, proto: Protocol) -> Option<EngineInfo<()>> {
self.iter().find(|info| info.protocol() == proto)
}
pub fn iter(&self) -> EngineInfoIter<()> {
unsafe {
let mut first = ptr::null_mut();
assert_eq!(ffi::gpgme_get_engine_info(&mut first), 0);
EngineInfoIter::from_list(first)
}
}
}
impl<'a> IntoIterator for &'a EngineInfoGuard {
type Item = EngineInfo<'a, ()>;
type IntoIter = EngineInfoIter<'a, ()>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}