Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add minimal documentation for public items #249

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
24 changes: 22 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 floating-point value.
#[derive(Copy, Clone, PartialEq)]
pub enum DynFloat {
#[cfg(feature = "f16")]
Expand Down Expand Up @@ -173,6 +177,7 @@ impl From<DynFloat> for DynValue<'_> {
}
}

/// A dynamically-typed scalar value.
#[derive(Copy, Clone, PartialEq)]
pub enum DynScalar {
Integer(DynInteger),
Expand Down Expand Up @@ -212,6 +217,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 +275,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 +361,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 +478,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 +538,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 +643,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 +688,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 +699,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 +761,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 +777,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 +797,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
Loading
Loading