use std::{
env, fs,
path::{Path, PathBuf},
};
#[cfg(feature = "pyo3")]
use pyo3::prelude::*;
use kortex_gen_grpc::hstp::v1::ErrorCode;
use serde_json::Value;
use crate::types::{entity::HSMLEntity, error::HstpError};
fn get_absolute_path<P: AsRef<Path>>(relative_path: P) -> Option<PathBuf> {
let current_dir = env::current_dir().ok()?;
let relative_path = relative_path.as_ref();
let mut absolute_path = current_dir.join(relative_path);
absolute_path = absolute_path
.components()
.fold(PathBuf::new(), |mut acc, component| {
match component {
std::path::Component::Normal(part) => acc.push(part),
std::path::Component::ParentDir => {
acc.pop();
}
_ => (),
}
acc
});
Some(absolute_path)
}
#[cfg(feature = "pyo3")]
#[pyfunction]
pub fn make_swid(class: &str) -> String {
let mut swid = format!("swid:{}:", class);
swid.push_str(&nanoid::nanoid!());
swid
}
pub fn read_hsml_json<P: AsRef<Path>>(path: P) -> Result<Vec<HSMLEntity>, HstpError> {
let ref_path: &Path = path.as_ref();
let file = fs::read_to_string(ref_path).map_err(|e| {
let absolute_str = get_absolute_path(ref_path).unwrap();
HstpError::new(
ErrorCode::None,
format!(
"Failed to read file, you were tyring to read {:?}. {}",
absolute_str.to_string_lossy().replace("./", ""),
e
),
"".into(),
)
})?;
let value: Value = serde_json::from_str(&file).map_err(|e| {
HstpError::new(
ErrorCode::None,
format!("Failed to parse json file (read_hsml_json): {}", e),
"".into(),
)
})?;
value_to_hsml(value)
}
pub fn value_to_hsml(value: Value) -> Result<Vec<HSMLEntity>, HstpError> {
let is_array = value.is_array();
let value = if !is_array {
vec![value]
} else {
value.as_array().unwrap().clone()
};
value
.iter()
.map(HSMLEntity::from_value)
.collect::<Result<Vec<_>, _>>()
}