1use super::*;
17use std::collections::HashMap;
18
19pub struct Params {
21 inner: NonNull<bindings::nixl_capi_params_s>,
22}
23
24#[derive(Debug)]
26pub struct ParamPair<'a> {
27 pub key: &'a str,
28 pub value: &'a str,
29}
30
31pub struct ParamIterator<'a> {
33 iter: NonNull<bindings::nixl_capi_param_iter_s>,
34 _phantom: std::marker::PhantomData<&'a ()>,
35}
36
37pub struct ParamIntoIter<'a> {
39 inner: ParamIterator<'a>,
40}
41
42impl<'a> Iterator for ParamIntoIter<'a> {
43 type Item = (&'a str, &'a str);
44
45 fn next(&mut self) -> Option<Self::Item> {
46 self.inner.find_map(Result::ok)
47 }
48}
49
50impl<'a> Iterator for ParamIterator<'a> {
51 type Item = Result<(&'a str, &'a str), NixlError>;
52
53 fn next(&mut self) -> Option<Self::Item> {
54 let mut key_ptr = ptr::null();
55 let mut value_ptr = ptr::null();
56 let mut has_next = false;
57
58 let status = unsafe {
60 nixl_capi_params_iterator_next(
61 self.iter.as_ptr(),
62 &mut key_ptr,
63 &mut value_ptr,
64 &mut has_next,
65 )
66 };
67
68 match status {
69 0 if key_ptr.is_null() => None,
70 0 => {
71 let result = unsafe {
73 let key = CStr::from_ptr(key_ptr).to_str().unwrap();
74 let value = CStr::from_ptr(value_ptr).to_str().unwrap();
75 Ok((key, value))
76 };
77 Some(result)
78 }
79 -1 => Some(Err(NixlError::InvalidParam)),
80 _ => Some(Err(NixlError::BackendError)),
81 }
82 }
83}
84
85impl Drop for ParamIterator<'_> {
86 fn drop(&mut self) {
87 unsafe {
89 nixl_capi_params_destroy_iterator(self.iter.as_ptr());
90 }
91 }
92}
93
94impl From<ParamIterator<'_>> for HashMap<String, String> {
95 fn from(iter: ParamIterator<'_>) -> Self {
96 iter.filter_map(Result::ok)
97 .map(|(k, v)| (k.to_string(), v.to_string()))
98 .collect()
99 }
100}
101
102impl<'a> IntoIterator for &'a Params {
103 type Item = (&'a str, &'a str);
104 type IntoIter = ParamIntoIter<'a>;
105
106 fn into_iter(self) -> Self::IntoIter {
107 ParamIntoIter {
108 inner: self.iter().expect("Failed to create param iterator"),
109 }
110 }
111}
112
113impl Params {
114 pub(crate) fn new(inner: NonNull<bindings::nixl_capi_params_s>) -> Self {
115 Self { inner }
116 }
117
118 pub(crate) fn create() -> Result<Self, NixlError> {
120 let mut params = ptr::null_mut();
121
122 let status = unsafe { nixl_capi_create_params(&mut params) };
123
124 match status {
125 0 => {
126 let inner = unsafe { NonNull::new_unchecked(params) };
127 Ok(Self { inner })
128 }
129 -1 => Err(NixlError::InvalidParam),
130 _ => Err(NixlError::BackendError),
131 }
132 }
133
134 pub fn from<I, K, V>(iter: I) -> Result<Self, NixlError>
149 where
150 I: IntoIterator<Item = (K, V)>,
151 K: AsRef<str>,
152 V: AsRef<str>,
153 {
154 let mut params = Self::create()?;
155 for (key, value) in iter {
156 params.set(key.as_ref(), value.as_ref())?;
157 }
158 Ok(params)
159 }
160
161 pub fn clone(&self) -> Result<Self, NixlError> {
170 Params::from(self)
171 }
172
173 pub fn set(&mut self, key: &str, value: &str) -> Result<(), NixlError> {
175 let c_key = CString::new(key)?;
176 let c_value = CString::new(value)?;
177
178 let status = unsafe {
179 nixl_capi_params_add(self.inner.as_ptr(), c_key.as_ptr(), c_value.as_ptr())
180 };
181
182 match status {
183 0 => Ok(()),
184 -1 => Err(NixlError::InvalidParam),
185 _ => Err(NixlError::BackendError),
186 }
187 }
188
189 pub fn is_empty(&self) -> Result<bool, NixlError> {
191 let mut is_empty = false;
192
193 let status = unsafe { nixl_capi_params_is_empty(self.inner.as_ptr(), &mut is_empty) };
195
196 match status {
197 0 => Ok(is_empty),
198 -1 => Err(NixlError::InvalidParam),
199 _ => Err(NixlError::BackendError),
200 }
201 }
202
203 pub fn iter(&self) -> Result<ParamIterator<'_>, NixlError> {
205 let mut iter = ptr::null_mut();
206
207 let status = unsafe { nixl_capi_params_create_iterator(self.inner.as_ptr(), &mut iter) };
209
210 match status {
211 0 => {
212 let iter = unsafe { NonNull::new_unchecked(iter) };
214 Ok(ParamIterator {
215 iter,
216 _phantom: std::marker::PhantomData,
217 })
218 }
219 -1 => Err(NixlError::InvalidParam),
220 _ => Err(NixlError::BackendError),
221 }
222 }
223
224 pub(crate) fn handle(&self) -> *mut bindings::nixl_capi_params_s {
225 self.inner.as_ptr()
226 }
227}
228
229impl Drop for Params {
230 fn drop(&mut self) {
231 unsafe {
233 nixl_capi_destroy_params(self.inner.as_ptr());
234 }
235 }
236}