use super::*;
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
pub enum Metadata {
Text(String),
Integer(usize),
Float(f32),
Array(Vec<Metadata>),
Object(HashMap<String, Metadata>),
}
impl From<usize> for Metadata {
fn from(value: usize) -> Self {
Metadata::Integer(value)
}
}
impl From<f32> for Metadata {
fn from(value: f32) -> Self {
Metadata::Float(value)
}
}
impl From<String> for Metadata {
fn from(value: String) -> Self {
Metadata::Text(value)
}
}
impl From<&str> for Metadata {
fn from(value: &str) -> Self {
Metadata::Text(value.to_string())
}
}
impl<T> From<Vec<T>> for Metadata
where
Metadata: From<T>,
{
fn from(value: Vec<T>) -> Self {
let arr = value.into_iter().map(|v| v.into()).collect();
Metadata::Array(arr)
}
}
impl<T> From<HashMap<String, T>> for Metadata
where
Metadata: From<T>,
{
fn from(value: HashMap<String, T>) -> Self {
let iter = value.into_iter();
let obj = iter.map(|(k, v)| (k, v.into())).collect();
Metadata::Object(obj)
}
}
impl<T> From<HashMap<&str, T>> for Metadata
where
Metadata: From<T>,
{
fn from(value: HashMap<&str, T>) -> Self {
let iter = value.into_iter();
let obj = iter.map(|(k, v)| (k.into(), v.into())).collect();
Metadata::Object(obj)
}
}
impl From<&PyAny> for Metadata {
fn from(value: &PyAny) -> Self {
if let Ok(text) = value.extract::<String>() {
return Metadata::Text(text);
}
if let Ok(int) = value.extract::<usize>() {
return Metadata::Integer(int);
}
if let Ok(float) = value.extract::<f32>() {
return Metadata::Float(float);
}
if let Ok(list) = value.extract::<Vec<&PyAny>>() {
let arr = list.into_iter().map(|v| v.into()).collect();
return Metadata::Array(arr);
}
if let Ok(dict) = value.extract::<HashMap<String, &PyAny>>() {
let obj = dict.into_iter().map(|(k, v)| (k, v.into())).collect();
return Metadata::Object(obj);
}
panic!("Unsupported type for the metadata.");
}
}
impl IntoPy<Py<PyAny>> for Metadata {
fn into_py(self, py: Python) -> Py<PyAny> {
let list_converter = |vec: Vec<Metadata>| {
let list = vec
.into_iter()
.map(|metadata: Metadata| metadata.into_py(py))
.collect::<Vec<Py<PyAny>>>();
list.into_py(py)
};
let dict_converter = |map: HashMap<String, Metadata>| {
let dict = map
.into_iter()
.map(|(key, value)| (key, value.into_py(py)))
.collect::<HashMap<String, Py<PyAny>>>();
dict.into_py(py)
};
match self {
Metadata::Text(text) => text.into_py(py),
Metadata::Integer(int) => int.into_py(py),
Metadata::Float(float) => float.into_py(py),
Metadata::Array(arr) => list_converter(arr),
Metadata::Object(obj) => dict_converter(obj),
}
}
}