conspire 0.7.7

The Rust interface to conspire.
Documentation
#[cfg(test)]
mod test;

pub(super) mod hdf5;
mod read;
mod write;
mod xdr;

pub(super) use write::finalize;
pub(super) use xdr::{decode_be, decode_le, encode_be, encode_le};

pub(super) fn parse(bytes: &[u8]) -> Parsed {
    match hdf5::superblock_offset(bytes) {
        Some(base) => hdf5::parse(bytes, base),
        None => read::parse(bytes),
    }
}

pub(super) const NC_INT: i32 = 4;
pub(super) const NC_FLOAT: i32 = 5;
pub(super) const NC_DOUBLE: i32 = 6;

const NC_CHAR_TYPE: i32 = 2;
const NC_DIMENSION: i32 = 0x0A;
const NC_VARIABLE: i32 = 0x0B;
const NC_ATTRIBUTE: i32 = 0x0C;

pub(super) fn type_size(xtype: i32) -> usize {
    match xtype {
        NC_INT | NC_FLOAT => 4,
        NC_DOUBLE => 8,
        _ => panic!("unsupported netCDF external type {xtype}"),
    }
}

pub(super) enum AttValue {
    Int(Vec<i32>),
    Float(Vec<f32>),
    Text(String),
}

pub(super) struct Attribute {
    pub name: String,
    pub value: AttValue,
}

pub(super) struct DimSpec {
    pub name: String,
    pub len: u64,
}

pub(super) struct VarSpec {
    pub name: String,
    pub xtype: i32,
    pub dimids: Vec<usize>,
    pub atts: Vec<Attribute>,
    pub begin: u64,
    pub vsize: u64,
    pub storage: Storage,
}

pub(super) enum Storage {
    Classic,
    Hdf5 {
        little_endian: bool,
        shape: Vec<u64>,
        layout: hdf5::Layout,
        filters: Vec<hdf5::Filter>,
        fill: Option<Vec<u8>>,
    },
}

impl VarSpec {
    pub fn shape(&self, dims: &[DimSpec]) -> Vec<u64> {
        self.dimids.iter().map(|&d| dims[d].len).collect()
    }
    pub fn elements(&self, dims: &[DimSpec]) -> u64 {
        self.dimids
            .iter()
            .map(|&d| dims[d].len)
            .product::<u64>()
            .max(1)
    }
}

pub(super) struct Parsed {
    pub dims: Vec<DimSpec>,
    #[allow(dead_code)]
    pub gatts: Vec<Attribute>,
    pub vars: Vec<VarSpec>,
}