use std::collections::HashMap;
use crate::backend::{AttributeOp, Backend, DataContainer, DataType, GroupOp};
use crate::data::{
array::slice::{SelectInfoElem, Shape},
array::DynScalar,
};
use anyhow::Result;
use serde_json::Value;
pub(crate) const MAPPING_ENCODING: MetaData = MetaData {
encoding_type: "dict",
version: "0.1.0",
metadata: None,
};
pub struct MetaData {
encoding_type: &'static str,
version: &'static str,
metadata: Option<HashMap<String, Value>>,
}
impl MetaData {
pub(crate) fn new(
encoding_type: &'static str,
version: &'static str,
metadata: Option<HashMap<String, Value>>,
) -> Self {
Self {
encoding_type,
version,
metadata,
}
}
pub(crate) fn save<B: Backend, A: AttributeOp<B>>(self, loc: &mut A) -> Result<()> {
loc.new_attr("encoding-type", self.encoding_type)?;
loc.new_attr("encoding-version", self.version)?;
if let Some(metadata) = self.metadata {
for (key, value) in metadata.into_iter() {
loc.new_attr(&key, value)?;
}
}
Ok(())
}
}
pub trait Element {
fn data_type(&self) -> DataType;
fn metadata(&self) -> MetaData;
}
impl<T> Element for &T
where
T: Element,
{
fn data_type(&self) -> DataType {
(*self).data_type()
}
fn metadata(&self) -> MetaData {
(*self).metadata()
}
}
pub trait Readable: Element {
fn read<B: Backend>(container: &DataContainer<B>) -> Result<Self>
where
Self: Sized;
}
pub trait Writable: Element {
fn write<B: Backend, G: GroupOp<B>>(
&self,
location: &G,
name: &str,
) -> Result<DataContainer<B>>;
fn overwrite<B: Backend>(&self, container: DataContainer<B>) -> Result<DataContainer<B>> {
let file = container.store()?;
let path = container.path();
let group = file.open_group(path.parent().unwrap().to_str().unwrap())?;
let name = path.file_name().unwrap().to_str().unwrap();
group.delete(name)?;
self.write(&group, name)
}
}
impl<T> Writable for &T
where
T: Writable,
{
fn write<B: Backend, G: GroupOp<B>>(
&self,
location: &G,
name: &str,
) -> Result<DataContainer<B>> {
(*self).write(location, name)
}
}
pub trait HasShape {
fn shape(&self) -> Shape;
}
impl<T> HasShape for &T
where
T: HasShape,
{
fn shape(&self) -> Shape {
(*self).shape()
}
}
pub trait Indexable: HasShape {
fn get(&self, index: &[usize]) -> Option<DynScalar>;
}
pub trait Selectable: HasShape {
fn select<S>(&self, info: &[S]) -> Self
where
S: AsRef<SelectInfoElem>;
fn select_axis<S>(&self, axis: usize, slice: S) -> Self
where
S: AsRef<SelectInfoElem>,
Self: Sized,
{
let full = SelectInfoElem::full();
let selection = slice.as_ref().set_axis(axis, self.shape().ndim(), &full);
self.select(selection.as_slice())
}
}
pub trait Stackable: HasShape {
fn vstack<I: Iterator<Item = Self>>(iter: I) -> Result<Self>
where
Self: Sized;
}
pub trait ReadableArray: Readable {
fn get_shape<B: Backend>(container: &DataContainer<B>) -> Result<Shape>;
fn read_select<B, S>(container: &DataContainer<B>, info: &[S]) -> Result<Self>
where
B: Backend,
S: AsRef<SelectInfoElem>,
Self: Sized;
fn read_axis<B, S>(container: &DataContainer<B>, axis: usize, slice: S) -> Result<Self>
where
B: Backend,
S: AsRef<SelectInfoElem>,
Self: Sized,
{
let ndim = Self::get_shape(container)?.ndim();
let full = SelectInfoElem::full();
let selection = slice.as_ref().set_axis(axis, ndim, &full);
Self::read_select(container, selection.as_slice())
}
}
pub trait WritableArray: Writable {}