use std::{ffi::c_int, iter::FusedIterator, ptr::NonNull};
#[derive(Debug)]
pub struct MetadataNode<'node> {
pub kind: c_int,
pub data: &'node [u8],
}
#[derive(Debug)]
pub struct MetadataNodeMut<'node> {
pub kind: c_int,
pub data: &'node mut [u8],
}
#[derive(Debug, Clone)]
pub struct Metadata<'img>(Option<&'img libplum_sys::plum_metadata>);
impl<'img> Metadata<'img> {
pub(super) fn new(img: &'img libplum_sys::plum_image) -> Self {
Self(unsafe { Self::make_inner(img.metadata) })
}
unsafe fn make_inner(
ptr: *const libplum_sys::plum_metadata,
) -> Option<&'img libplum_sys::plum_metadata> {
unsafe { ptr.as_ref() }
}
}
impl<'img> Iterator for Metadata<'img> {
type Item = MetadataNode<'img>;
fn next(&mut self) -> Option<Self::Item> {
let raw_node = self.0?;
self.0 = unsafe { Self::make_inner(raw_node.next) };
let data_ptr = NonNull::new(raw_node.data as *mut u8).unwrap_or(NonNull::dangling());
assert!(raw_node.size <= isize::MAX as usize); let slice_ptr = NonNull::slice_from_raw_parts(data_ptr, raw_node.size);
let data = unsafe { slice_ptr.as_ref() };
Some(MetadataNode {
kind: raw_node.type_,
data,
})
}
}
impl FusedIterator for Metadata<'_> {}
#[derive(Debug)]
pub struct MetadataMut<'img>(Option<&'img mut libplum_sys::plum_metadata>);
impl<'img> MetadataMut<'img> {
pub(super) fn new(img: &'img mut libplum_sys::plum_image) -> Self {
Self(unsafe { Self::make_inner(img.metadata) })
}
unsafe fn make_inner(
ptr: *mut libplum_sys::plum_metadata,
) -> Option<&'img mut libplum_sys::plum_metadata> {
unsafe { ptr.as_mut() }
}
}
impl<'img> Iterator for MetadataMut<'img> {
type Item = MetadataNodeMut<'img>;
fn next(&mut self) -> Option<Self::Item> {
let raw_node = self.0.take()?;
self.0 = unsafe { Self::make_inner(raw_node.next) };
let data_ptr = NonNull::new(raw_node.data as *mut u8).unwrap_or(NonNull::dangling());
assert!(raw_node.size <= isize::MAX as usize); let mut slice_ptr = NonNull::slice_from_raw_parts(data_ptr, raw_node.size);
let data = unsafe { slice_ptr.as_mut() };
Some(MetadataNodeMut {
kind: raw_node.type_,
data,
})
}
}
impl FusedIterator for MetadataMut<'_> {}