Skip to content

Commit 5818946

Browse files
authored
Merge pull request #5 from artichoke/lopopolo/state-opaque
Make `sysdir_search_path_enumeration_state` opaque
2 parents 15f08fc + 1c9e08e commit 5818946

File tree

3 files changed

+70
-1
lines changed

3 files changed

+70
-1
lines changed

Rakefile

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ task :bindgen do
126126
bindgen --use-core
127127
--allowlist-function sysdir.*
128128
--allowlist-type sysdir.*
129+
--blocklist-type sysdir_search_path_enumeration_state
129130
--allowlist-var PATH_MAX
130131
--default-enum-style rust_non_exhaustive
131132
--constified-enum sysdir_search_path_domain_mask_t
@@ -150,6 +151,29 @@ task :bindgen do
150151
f.puts ''
151152

152153
IO.copy_stream(bindgen_io, f)
154+
155+
f.puts ''
156+
f.puts <<~NEWTYPE
157+
/// Opaque type for holding sysdir enumeration state.
158+
#[repr(transparent)]
159+
#[derive(Debug)]
160+
#[allow(missing_copy_implementations)]
161+
pub struct sysdir_search_path_enumeration_state(::core::ffi::c_uint);
162+
163+
impl PartialEq<::core::ffi::c_uint> for sysdir_search_path_enumeration_state {
164+
fn eq(&self, other: &::core::ffi::c_uint) -> bool {
165+
self.0 == *other
166+
}
167+
}
168+
169+
impl sysdir_search_path_enumeration_state {
170+
/// Return true if the state indicates the enumeration is finished.
171+
#[must_use]
172+
pub fn is_finished(&self) -> bool {
173+
self.0 == 0
174+
}
175+
}
176+
NEWTYPE
153177
end
154178
end
155179

src/lib.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,4 +143,30 @@ mod tests {
143143

144144
assert_eq!(count, 1, "Should iterate once and find `/Users`");
145145
}
146+
147+
#[test]
148+
fn example_and_linkage_with_opaque_state_helpers() {
149+
let mut count = 0_usize;
150+
let mut path = [0; PATH_MAX as usize];
151+
152+
let dir = sysdir_search_path_directory_t::SYSDIR_DIRECTORY_USER;
153+
let domain_mask = SYSDIR_DOMAIN_MASK_LOCAL;
154+
155+
unsafe {
156+
let mut state = sysdir_start_search_path_enumeration(dir, domain_mask);
157+
loop {
158+
let path = path.as_mut_ptr().cast::<c_char>();
159+
state = sysdir_get_next_search_path_enumeration(state, path);
160+
if state.is_finished() {
161+
break;
162+
}
163+
let path = CStr::from_ptr(path);
164+
let s = path.to_str().unwrap();
165+
assert_eq!(s, "/Users");
166+
count += 1;
167+
}
168+
}
169+
170+
assert_eq!(count, 1, "Should iterate once and find `/Users`");
171+
}
146172
}

src/sys.rs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ pub const SYSDIR_DOMAIN_MASK_NETWORK: sysdir_search_path_domain_mask_t = 4;
4848
pub const SYSDIR_DOMAIN_MASK_SYSTEM: sysdir_search_path_domain_mask_t = 8;
4949
pub const SYSDIR_DOMAIN_MASK_ALL: sysdir_search_path_domain_mask_t = 65535;
5050
pub type sysdir_search_path_domain_mask_t = ::core::ffi::c_uint;
51-
pub type sysdir_search_path_enumeration_state = ::core::ffi::c_uint;
5251
extern "C" {
5352
pub fn sysdir_start_search_path_enumeration(
5453
dir: sysdir_search_path_directory_t,
@@ -61,3 +60,23 @@ extern "C" {
6160
path: *mut ::core::ffi::c_char,
6261
) -> sysdir_search_path_enumeration_state;
6362
}
63+
64+
/// Opaque type for holding sysdir enumeration state.
65+
#[repr(transparent)]
66+
#[derive(Debug)]
67+
#[allow(missing_copy_implementations)]
68+
pub struct sysdir_search_path_enumeration_state(::core::ffi::c_uint);
69+
70+
impl PartialEq<::core::ffi::c_uint> for sysdir_search_path_enumeration_state {
71+
fn eq(&self, other: &::core::ffi::c_uint) -> bool {
72+
self.0 == *other
73+
}
74+
}
75+
76+
impl sysdir_search_path_enumeration_state {
77+
/// Return true if the state indicates the enumeration is finished.
78+
#[must_use]
79+
pub fn is_finished(&self) -> bool {
80+
self.0 == 0
81+
}
82+
}

0 commit comments

Comments
 (0)