use super::*;
use std::collections::HashMap;
pub struct Params {
inner: NonNull<bindings::nixl_capi_params_s>,
}
#[derive(Debug)]
pub struct ParamPair<'a> {
pub key: &'a str,
pub value: &'a str,
}
pub struct ParamIterator<'a> {
iter: NonNull<bindings::nixl_capi_param_iter_s>,
_phantom: std::marker::PhantomData<&'a ()>,
}
pub struct ParamIntoIter<'a> {
inner: ParamIterator<'a>,
}
impl<'a> Iterator for ParamIntoIter<'a> {
type Item = (&'a str, &'a str);
fn next(&mut self) -> Option<Self::Item> {
self.inner.find_map(Result::ok)
}
}
impl<'a> Iterator for ParamIterator<'a> {
type Item = Result<(&'a str, &'a str), NixlError>;
fn next(&mut self) -> Option<Self::Item> {
let mut key_ptr = ptr::null();
let mut value_ptr = ptr::null();
let mut has_next = false;
let status = unsafe {
nixl_capi_params_iterator_next(
self.iter.as_ptr(),
&mut key_ptr,
&mut value_ptr,
&mut has_next,
)
};
match status {
0 if key_ptr.is_null() => None,
0 => {
let result = unsafe {
let key = CStr::from_ptr(key_ptr).to_str().unwrap();
let value = CStr::from_ptr(value_ptr).to_str().unwrap();
Ok((key, value))
};
Some(result)
}
-1 => Some(Err(NixlError::InvalidParam)),
_ => Some(Err(NixlError::BackendError)),
}
}
}
impl Drop for ParamIterator<'_> {
fn drop(&mut self) {
unsafe {
nixl_capi_params_destroy_iterator(self.iter.as_ptr());
}
}
}
impl From<ParamIterator<'_>> for HashMap<String, String> {
fn from(iter: ParamIterator<'_>) -> Self {
iter.filter_map(Result::ok)
.map(|(k, v)| (k.to_string(), v.to_string()))
.collect()
}
}
impl<'a> IntoIterator for &'a Params {
type Item = (&'a str, &'a str);
type IntoIter = ParamIntoIter<'a>;
fn into_iter(self) -> Self::IntoIter {
ParamIntoIter {
inner: self.iter().expect("Failed to create param iterator"),
}
}
}
impl Params {
pub(crate) fn new(inner: NonNull<bindings::nixl_capi_params_s>) -> Self {
Self { inner }
}
pub(crate) fn create() -> Result<Self, NixlError> {
let mut params = ptr::null_mut();
let status = unsafe { nixl_capi_create_params(&mut params) };
match status {
0 => {
let inner = unsafe { NonNull::new_unchecked(params) };
Ok(Self { inner })
}
-1 => Err(NixlError::InvalidParam),
_ => Err(NixlError::BackendError),
}
}
pub fn from<I, K, V>(iter: I) -> Result<Self, NixlError>
where
I: IntoIterator<Item = (K, V)>,
K: AsRef<str>,
V: AsRef<str>,
{
let mut params = Self::create()?;
for (key, value) in iter {
params.set(key.as_ref(), value.as_ref())?;
}
Ok(params)
}
pub fn clone(&self) -> Result<Self, NixlError> {
Params::from(self)
}
pub fn set(&mut self, key: &str, value: &str) -> Result<(), NixlError> {
let c_key = CString::new(key)?;
let c_value = CString::new(value)?;
let status = unsafe {
nixl_capi_params_add(self.inner.as_ptr(), c_key.as_ptr(), c_value.as_ptr())
};
match status {
0 => Ok(()),
-1 => Err(NixlError::InvalidParam),
_ => Err(NixlError::BackendError),
}
}
pub fn is_empty(&self) -> Result<bool, NixlError> {
let mut is_empty = false;
let status = unsafe { nixl_capi_params_is_empty(self.inner.as_ptr(), &mut is_empty) };
match status {
0 => Ok(is_empty),
-1 => Err(NixlError::InvalidParam),
_ => Err(NixlError::BackendError),
}
}
pub fn iter(&self) -> Result<ParamIterator<'_>, NixlError> {
let mut iter = ptr::null_mut();
let status = unsafe { nixl_capi_params_create_iterator(self.inner.as_ptr(), &mut iter) };
match status {
0 => {
let iter = unsafe { NonNull::new_unchecked(iter) };
Ok(ParamIterator {
iter,
_phantom: std::marker::PhantomData,
})
}
-1 => Err(NixlError::InvalidParam),
_ => Err(NixlError::BackendError),
}
}
pub(crate) fn handle(&self) -> *mut bindings::nixl_capi_params_s {
self.inner.as_ptr()
}
}
impl Drop for Params {
fn drop(&mut self) {
unsafe {
nixl_capi_destroy_params(self.inner.as_ptr());
}
}
}