genius-core-client 0.4.0

Genius Core Client Library. Written in Rust and using PyO3 for Python bindings.
Documentation
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> {
    // Get the current working directory
    let current_dir = env::current_dir().ok()?;

    // Create a Path object from the relative path
    let relative_path = relative_path.as_ref();

    // Combine the current directory with the relative path to get the absolute path
    let mut absolute_path = current_dir.join(relative_path);

    // Clean up the path by removing '.', '..' and similar components
    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
        });

    // Return the absolute path
    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();
    //read file to string
    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(),
        )
    })?;

    //parse file to json
    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> {
    //is json an array?
    let is_array = value.is_array();

    //if not an array, make it an array of one
    let value = if !is_array {
        vec![value]
    } else {
        value.as_array().unwrap().clone()
    };

    //convert json to hsml
    value
        .iter()
        .map(HSMLEntity::from_value)
        .collect::<Result<Vec<_>, _>>()
}