Skip to content

Commit

Permalink
Add minimal docs for public items
Browse files Browse the repository at this point in the history
  • Loading branch information
rytheo committed Jun 24, 2023
1 parent 26046fb commit 402f2d3
Show file tree
Hide file tree
Showing 26 changed files with 770 additions and 10 deletions.
1 change: 1 addition & 0 deletions hdf5-derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use syn::{
TypeGenerics, TypePath,
};

/// Derive macro generating an impl of the trait `H5Type`.
#[proc_macro_derive(H5Type, attributes(hdf5))]
#[proc_macro_error]
pub fn derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
Expand Down
14 changes: 14 additions & 0 deletions hdf5-types/src/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use std::ops::Deref;
use std::ptr;
use std::slice;

/// A variable-length array.
#[repr(C)]
pub struct VarLenArray<T: Copy> {
len: usize,
Expand All @@ -13,6 +14,14 @@ pub struct VarLenArray<T: Copy> {
}

impl<T: Copy> VarLenArray<T> {
/// Creates a `VarLenArray<T>` by copying the first `len` elements stored at `p`.
///
/// Returns an empty array if `p` is null.
///
/// # Safety
///
/// - `p` must be valid for reads of `len * size_of::<T>()` bytes.
/// - `p` must point to `len` consecutive properly initialized and aligned values of type `T`.
pub unsafe fn from_parts(p: *const T, len: usize) -> Self {
let (len, ptr) = if !p.is_null() && len != 0 {
let dst = crate::malloc(len * mem::size_of::<T>());
Expand All @@ -24,26 +33,31 @@ impl<T: Copy> VarLenArray<T> {
Self { len, ptr: ptr as *const _, tag: PhantomData }
}

/// Creates a `VarLenArray<T>` from a slice by copying its elements.
#[inline]
pub fn from_slice(arr: &[T]) -> Self {
unsafe { Self::from_parts(arr.as_ptr(), arr.len()) }
}

/// Returns a raw pointer to the array's buffer.
#[inline]
pub fn as_ptr(&self) -> *const T {
self.ptr
}

/// Returns the number of elements in the array.
#[inline]
pub fn len(&self) -> usize {
self.len as _
}

/// Returns `true` if the array has a length of zero.
#[inline]
pub fn is_empty(&self) -> bool {
self.len == 0
}

/// Returns a slice containing the entire array.
#[inline]
pub fn as_slice(&self) -> &[T] {
self
Expand Down
23 changes: 21 additions & 2 deletions hdf5-types/src/dyn_value.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
//! Dynamically-typed values.

use std::fmt::{self, Debug, Display};
use std::mem;
use std::ptr;
Expand Down Expand Up @@ -26,6 +28,7 @@ unsafe trait DynClone {
fn dyn_clone(&mut self, out: &mut [u8]);
}

/// A dynamically-typed integer.
#[derive(Copy, Clone, PartialEq, Eq)]
pub enum DynInteger {
Int8(i8),
Expand Down Expand Up @@ -114,6 +117,7 @@ impl From<DynInteger> for DynValue<'_> {
}
}

/// A dynamically-typed scalar.
#[derive(Copy, Clone, PartialEq)]
pub enum DynFloat {
#[cfg(feature = "f16")]
Expand Down Expand Up @@ -212,6 +216,7 @@ impl From<DynScalar> for DynValue<'static> {
}
}

/// A dynamically-typed enumeration value.
#[derive(Copy, Clone)]
pub struct DynEnum<'a> {
tp: &'a EnumType,
Expand Down Expand Up @@ -269,6 +274,7 @@ impl<'a> From<DynEnum<'a>> for DynValue<'a> {
}
}

/// A dynamically-typed compound value.
pub struct DynCompound<'a> {
tp: &'a CompoundType,
buf: &'a [u8],
Expand Down Expand Up @@ -354,6 +360,7 @@ impl<'a> From<DynCompound<'a>> for DynValue<'a> {
}
}

/// A dynamically-typed array.
pub struct DynArray<'a> {
tp: &'a TypeDescriptor,
buf: &'a [u8],
Expand Down Expand Up @@ -470,6 +477,7 @@ impl<'a> From<DynArray<'a>> for DynValue<'a> {
}
}

/// A fixed-length string with a dynamic encoding.
pub struct DynFixedString<'a> {
buf: &'a [u8],
unicode: bool,
Expand Down Expand Up @@ -529,6 +537,7 @@ impl<'a> From<DynFixedString<'a>> for DynValue<'a> {
}
}

/// A variable-length string with a dynamic encoding.
pub struct DynVarLenString<'a> {
buf: &'a [u8],
unicode: bool,
Expand Down Expand Up @@ -633,6 +642,7 @@ impl<'a> From<DynVarLenString<'a>> for DynValue<'a> {
}
}

/// A dynamically-typed string.
#[derive(PartialEq, Eq)]
pub enum DynString<'a> {
Fixed(DynFixedString<'a>),
Expand Down Expand Up @@ -677,6 +687,7 @@ impl<'a> From<DynString<'a>> for DynValue<'a> {
}
}

/// A borrowed value with dynamic type.
#[derive(PartialEq)]
pub enum DynValue<'a> {
Scalar(DynScalar),
Expand All @@ -687,6 +698,7 @@ pub enum DynValue<'a> {
}

impl<'a> DynValue<'a> {
/// Constructs a new `DynValue` from a `TypeDescriptor` and a byte slice.
pub fn new(tp: &'a TypeDescriptor, buf: &'a [u8]) -> Self {
use TypeDescriptor::*;
debug_assert_eq!(tp.size(), buf.len());
Expand Down Expand Up @@ -748,12 +760,14 @@ impl Display for DynValue<'_> {
}
}

/// An owned value with dynamic type.
pub struct OwnedDynValue {
tp: TypeDescriptor,
buf: Box<[u8]>,
}

impl OwnedDynValue {
/// Constructs a new `OwnedDynValue` from the given value.
pub fn new<T: H5Type>(value: T) -> Self {
let ptr = (&value as *const T).cast::<u8>();
let len = mem::size_of_val(&value);
Expand All @@ -762,10 +776,12 @@ impl OwnedDynValue {
Self { tp: T::type_descriptor(), buf: buf.to_owned().into_boxed_slice() }
}

/// Returns a borrowed version of the contained value.
pub fn get(&self) -> DynValue {
DynValue::new(&self.tp, &self.buf)
}

/// Returns the value's type descriptor.
pub fn type_descriptor(&self) -> &TypeDescriptor {
&self.tp
}
Expand All @@ -780,9 +796,12 @@ impl OwnedDynValue {
Self { tp, buf }
}

/// Cast to the concrete type
/// Tries to downcast the value to a concrete type.
///
/// # Errors
///
/// Will fail if the type-descriptors are not equal
/// If the type descriptors of `self` and `T` are not equal, this will fail and return a
/// `Result::Err` containing the original value.
pub fn cast<T: H5Type>(mut self) -> Result<T, Self> {
use mem::MaybeUninit;
if self.tp != T::type_descriptor() {
Expand Down
58 changes: 58 additions & 0 deletions hdf5-types/src/h5type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,21 @@ pub(crate) struct hvl_t {
pub ptr: *mut c_void,
}

/// A valid integer size.
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub enum IntSize {
/// 1 byte.
U1 = 1,
/// 2 bytes.
U2 = 2,
/// 4 bytes.
U4 = 4,
/// 8 bytes.
U8 = 8,
}

impl IntSize {
/// Returns an `IntSize` of `size` bytes, or `None` if `size` is invalid.
pub const fn from_int(size: usize) -> Option<Self> {
if size == 1 {
Some(Self::U1)
Expand All @@ -38,15 +44,20 @@ impl IntSize {
}
}

/// A valid floating-point number size.
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub enum FloatSize {
/// 2 bytes.
#[cfg(feature = "f16")]
U2 = 2,
/// 4 bytes.
U4 = 4,
/// 8 bytes.
U8 = 8,
}

impl FloatSize {
/// Returns a `FloatSize` of `size` bytes, or `None` if `size` is invalid.
pub const fn from_int(size: usize) -> Option<Self> {
#[cfg(feature = "f16")]
{
Expand All @@ -62,20 +73,28 @@ impl FloatSize {
}
}

/// A descriptor for an enumeration datatype member.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct EnumMember {
/// The name of the member.
pub name: String,
/// The value of the member.
pub value: u64,
}

/// A descriptor for an enumeration datatype.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct EnumType {
/// The size of the underlying integer type.
pub size: IntSize,
/// Whether to use a signed integer.
pub signed: bool,
/// The enumeration datatype members.
pub members: Vec<EnumMember>,
}

impl EnumType {
/// Returns the type descriptor of the underlying integer datatype.
#[inline]
pub fn base_type(&self) -> TypeDescriptor {
if self.signed {
Expand All @@ -86,31 +105,42 @@ impl EnumType {
}
}

/// A descriptor for a compound datatype field.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct CompoundField {
/// The name of the field.
pub name: String,
/// The type of the field.
pub ty: TypeDescriptor,
/// The byte offset of the field.
pub offset: usize,
/// The ordering of the field within the compound type.
pub index: usize,
}

impl CompoundField {
/// Creates a new `CompoundField`.
pub fn new(name: &str, ty: TypeDescriptor, offset: usize, index: usize) -> Self {
Self { name: name.to_owned(), ty, offset, index }
}

/// Creates a new `CompoundField` for a concrete type.
pub fn typed<T: H5Type>(name: &str, offset: usize, index: usize) -> Self {
Self::new(name, T::type_descriptor(), offset, index)
}
}

/// A descriptor for a compound datatype.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct CompoundType {
/// The fields of the datatype.
pub fields: Vec<CompoundField>,
/// The size in bytes of the datatype.
pub size: usize,
}

impl CompoundType {
/// Converts `self` to a C struct representation.
pub fn to_c_repr(&self) -> Self {
let mut layout = self.clone();
layout.fields.sort_by_key(|f| f.index);
Expand All @@ -133,6 +163,7 @@ impl CompoundType {
layout
}

/// Converts `self` to a packed representation.
pub fn to_packed_repr(&self) -> Self {
let mut layout = self.clone();
layout.fields.sort_by_key(|f| f.index);
Expand All @@ -146,19 +177,32 @@ impl CompoundType {
}
}

/// A descriptor for an HDF5 datatype.
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum TypeDescriptor {
/// A signed integer.
Integer(IntSize),
/// An unsigned integer.
Unsigned(IntSize),
/// A floating-point number.
Float(FloatSize),
/// A boolean value.
Boolean,
/// An enumeration datatype.
Enum(EnumType),
/// A compound datatype.
Compound(CompoundType),
/// A fixed-length array.
FixedArray(Box<Self>, usize),
/// A fixed-length ASCII string.
FixedAscii(usize),
/// A fixed-length UTF-8 string.
FixedUnicode(usize),
/// A variable-length array.
VarLenArray(Box<Self>),
/// A variable-length ASCII string.
VarLenAscii,
/// A variable-length UTF-8 string.
VarLenUnicode,
}

Expand Down Expand Up @@ -191,6 +235,7 @@ impl Display for TypeDescriptor {
}

impl TypeDescriptor {
/// Returns the size of the type in bytes.
pub fn size(&self) -> usize {
match *self {
Self::Integer(size) | Self::Unsigned(size) => size as _,
Expand All @@ -217,6 +262,7 @@ impl TypeDescriptor {
}
}

/// Converts `self` to a C-compatible representation.
pub fn to_c_repr(&self) -> Self {
match *self {
Self::Compound(ref compound) => Self::Compound(compound.to_c_repr()),
Expand All @@ -226,6 +272,7 @@ impl TypeDescriptor {
}
}

/// Converts `self` to a packed representation.
pub fn to_packed_repr(&self) -> Self {
match *self {
Self::Compound(ref compound) => Self::Compound(compound.to_packed_repr()),
Expand All @@ -236,7 +283,18 @@ impl TypeDescriptor {
}
}

/// A type that can be represented as an HDF5 datatype.
///
/// # Derivable
/// This trait can be used with `#[derive]`.
///
/// To `derive` on structs, they must be one of: `repr(C)`, `repr(packed)`, or `repr(transparent)`,
/// and have at least one field, all of which must implement `H5Type`.
///
/// To `derive` on enums, they must have an explicit `repr` and at least one variant, all of which
/// must be unit variants with explicit discriminants.
pub unsafe trait H5Type: 'static {
/// Returns a descriptor for an equivalent HDF5 datatype.
fn type_descriptor() -> TypeDescriptor;
}

Expand Down
1 change: 1 addition & 0 deletions hdf5-types/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ pub(crate) unsafe fn free(ptr: *mut core::ffi::c_void) {
}
}

/// Whether this crate is using the HDF5 library for allocations instead of `libc`.
pub const USING_H5_ALLOCATOR: bool = {
cfg_if::cfg_if! {
if #[cfg(any(feature = "h5-alloc", windows_dll))] {
Expand Down
Loading

0 comments on commit 402f2d3

Please sign in to comment.