Skip to content

Commit

Permalink
error api cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
mpiannucci committed Feb 1, 2023
1 parent 9da2887 commit 289b7ae
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 98 deletions.
31 changes: 15 additions & 16 deletions src/das.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,10 @@ use nom::{
IResult,
};

use crate::{data_type::{DataType, DataValue}, errors::Error};
use crate::{
data_type::{DataType, DataValue},
errors::Error,
};

#[derive(Clone, Debug)]
pub struct DasAttribute {
Expand Down Expand Up @@ -148,21 +151,17 @@ mod tests {
assert_eq!(attrs.len(), 5);
assert_eq!(attrs["long_name"].data_type, DataType::String);
assert_eq!(attrs["long_name"].name, "long_name");
assert!(
if let DataValue::String(s) = &attrs["long_name"].value {
s == "Spectral Wave Density"
} else {
false
}
);

assert!(
if let DataValue::Float32(f) = &attrs["_FillValue"].value {
(f - 999.0).abs() < 0.0001
} else {
false
}
);
assert!(if let DataValue::String(s) = &attrs["long_name"].value {
s == "Spectral Wave Density"
} else {
false
});

assert!(if let DataValue::Float32(f) = &attrs["_FillValue"].value {
(f - 999.0).abs() < 0.0001
} else {
false
});
}

#[test]
Expand Down
49 changes: 25 additions & 24 deletions src/data_type.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
use nom::{branch::alt, bytes::complete::tag, IResult, number::complete::{be_u32, be_i32, be_f32}, multi::{count}};
use nom::{
branch::alt,
bytes::complete::tag,
multi::count,
number::complete::{be_f32, be_i32, be_u32},
IResult,
};

#[derive(Clone, Debug, PartialEq, Eq)]
pub enum DataType {
Expand Down Expand Up @@ -38,34 +44,29 @@ pub enum DataValue {

#[derive(Clone, Debug)]
pub enum DataArray {
Int32(Vec<i32>),
Float32(Vec<f32>),
Int32(Vec<i32>),
Float32(Vec<f32>),
}

impl DataArray {
pub fn parse<"a>(input: &"a [u8], data_type: &"a DataType) -> IResult<&"a [u8], Self> {
let (input, length) = be_u32(input)?;
let (input, length_2) = be_u32(input)?;
pub fn parse<"a>(input: &"a [u8], data_type: &"a DataType) -> IResult<&"a [u8], Self> {
let (input, length) = be_u32(input)?;
let (input, length_2) = be_u32(input)?;

assert!(length == length_2);
assert!(length == length_2);

match data_type {
DataType::Int32 => {
let (input, values) = count(be_i32, length as usize)(input)?;
Ok((input, Self::Int32(values)))
},
DataType::Float32 => {
let (input, values) = count(be_f32, length as usize)(input)?;
Ok((input, Self::Float32(values)))
},
DataType::String => unreachable!(),
}
}
}

#[derive(Clone, Debug, Eq, PartialEq)]
pub enum DataArrayError {
ParseError,
match data_type {
DataType::Int32 => {
let (input, values) = count(be_i32, length as usize)(input)?;
Ok((input, Self::Int32(values)))
}
DataType::Float32 => {
let (input, values) = count(be_f32, length as usize)(input)?;
Ok((input, Self::Float32(values)))
}
DataType::String => unreachable!(),
}
}
}

#[cfg(test)]
Expand Down
71 changes: 35 additions & 36 deletions src/dds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,10 @@ use nom::{
IResult,
};

use crate::data_type::{DataArray, DataArrayError, DataType};
use crate::{
data_type::{DataArray, DataType},
errors::Error,
};

#[derive(Clone, Debug)]
pub struct DdsArray {
Expand Down Expand Up @@ -42,9 +45,8 @@ impl DdsArray {
8 + self.array_length() as usize * self.data_type.byte_count()
}

pub fn unpack_data(&self, bytes: &[u8]) -> Result<DataArray, DataArrayError> {
let (_, data) =
DataArray::parse(&bytes, &self.data_type).map_err(|_| DataArrayError::ParseError)?;
pub fn unpack_data(&self, bytes: &[u8]) -> Result<DataArray, Error> {
let (_, data) = DataArray::parse(&bytes, &self.data_type).map_err(|_| Error::ParseError)?;
Ok(data)
}
}
Expand Down Expand Up @@ -114,46 +116,43 @@ impl DdsGrid {
}

pub fn coords_offset(&self) -> usize {
self.array.byte_count()
self.array.byte_count()
}

pub fn coord_offsets(&self) -> Vec<usize> {
self.coords
.iter()
.scan(self.coords_offset(), |acc, c| {
let prev = *acc;
*acc = *acc + c.byte_count();
Some(prev)
})
.collect()
self.coords
.iter()
.scan(self.coords_offset(), |acc, c| {
let prev = *acc;
*acc = *acc + c.byte_count();
Some(prev)
})
.collect()
}

pub fn unpack_array_data(&self, bytes: &[u8]) -> Result<DataArray, DataArrayError> {
self.array.unpack_data(bytes)
pub fn unpack_array_data(&self, bytes: &[u8]) -> Result<DataArray, Error> {
self.array.unpack_data(bytes)
}

pub fn unpack_coords_data(&self, bytes: &[u8]) -> Result<Vec<DataArray>, DataArrayError> {
self.coords
.iter()
.scan(self.coords_offset(), |acc, c| {
let data = c.unpack_data(&bytes[*acc..]);
*acc = *acc + c.byte_count();
Some(data)
})
.collect()
pub fn unpack_coords_data(&self, bytes: &[u8]) -> Result<Vec<DataArray>, Error> {
self.coords
.iter()
.scan(self.coords_offset(), |acc, c| {
let data = c.unpack_data(&bytes[*acc..]);
*acc = *acc + c.byte_count();
Some(data)
})
.collect()
}

pub fn unpack_coord(&self, bytes: &[u8], key: &str) -> Result<DataArray, DataArrayError> {
let index = match self.coords
.iter()
.position(|c| c.name == key) {
Some(i) => Ok(i),
None => Err(DataArrayError::ParseError)
}?;


let offset = self.coord_offsets()[index];
self.coords[index].unpack_data(&bytes[offset..])
pub fn unpack_coord(&self, bytes: &[u8], key: &str) -> Result<DataArray, Error> {
let index = match self.coords.iter().position(|c| c.name == key) {
Some(i) => Ok(i),
None => Err(Error::ParseError),
}?;

let offset = self.coord_offsets()[index];
self.coords[index].unpack_data(&bytes[offset..])
}
}

Expand Down Expand Up @@ -200,7 +199,7 @@ impl DdsValue {
}

pub fn coords(&self) -> Vec<String> {
match self {
match self {
DdsValue::Array(a) => a.coords.iter().map(|c| c.0.clone()).collect(),
DdsValue::Grid(g) => g.coords.iter().map(|c| c.name.clone()).collect(),
}
Expand Down
33 changes: 11 additions & 22 deletions src/dods.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,4 @@
use crate::{
data_type::{DataArray, DataArrayError},
dds::{DdsDataset}, DdsValue,
};

#[derive(Clone, Debug)]
pub enum DodsDatasetError {
DdsParseFailure,
InvalidData,
DataUnpackingError,
}
use crate::{data_type::DataArray, dds::DdsDataset, errors::Error, DdsValue};

#[derive(Clone, Debug)]
pub struct DodsDataset {
Expand All @@ -17,14 +7,13 @@ pub struct DodsDataset {
}

impl DodsDataset {
pub fn from_bytes(bytes: &[u8]) -> Result<Self, DodsDatasetError> {
pub fn from_bytes(bytes: &[u8]) -> Result<Self, Error> {
let dods_string = String::from_utf8_lossy(&bytes);
let (_, dds) =
DdsDataset::parse(&dods_string).map_err(|_| DodsDatasetError::DdsParseFailure)?;
let (_, dds) = DdsDataset::parse(&dods_string).map_err(|_| Error::ParseError)?;

let binary_data_start = match dods_string.find("Data:\n") {
Some(p) => Ok(p),
None => Err(DodsDatasetError::InvalidData),
None => Err(Error::InvalidData),
}? + 6;

let data_bytes = bytes[binary_data_start..].to_vec();
Expand All @@ -46,22 +35,22 @@ impl DodsDataset {
Some(offset)
}

pub fn variable_data(&self, key: &str) -> Result<DataArray, DodsDatasetError> {
pub fn variable_data(&self, key: &str) -> Result<DataArray, Error> {
let index = match self.variable_index(key) {
Some(o) => Ok(o),
None => Err(DodsDatasetError::DataUnpackingError),
None => Err(Error::ParseError),
}?;

let offset = match self.variable_byte_offset(key) {
Some(o) => Ok(o),
None => Err(DodsDatasetError::DataUnpackingError),
None => Err(Error::ParseError),
}?;

let (_, data) = DataArray::parse(
&self.data_bytes[offset..],
&self.dds.values[index].array_data_type(),
)
.map_err(|_| DodsDatasetError::DataUnpackingError)?;
.map_err(|_| Error::ParseError)?;

Ok(data)
}
Expand All @@ -71,15 +60,15 @@ impl DodsDataset {
Some(self.dds.values[index].coords())
}

pub fn variable_coord_data(&self, key: &str) -> Result<Vec<DataArray>, DataArrayError> {
pub fn variable_coord_data(&self, key: &str) -> Result<Vec<DataArray>, Error> {
let position = match self.variable_byte_offset(key) {
Some(p) => Ok(p),
None => Err(DataArrayError::ParseError),
None => Err(Error::ParseError),
}?;

let index = match self.variable_index(key) {
Some(i) => Ok(i),
None => Err(DataArrayError::ParseError),
None => Err(Error::ParseError),
}?;

match &self.dds.values[index] {
Expand Down

0 comments on commit 289b7ae

Please sign in to comment.