use std::{fs::File, path::{Path, PathBuf}};
use serde_json::{Map, Value};
use uuid::Uuid;
use crate::{ApicizeError, ExecutionConcurrency};
pub fn generate_uuid() -> String {
Uuid::new_v4().to_string()
}
pub fn sequential() -> ExecutionConcurrency {
ExecutionConcurrency::Sequential
}
pub fn convert_json(name: &str, value: &str) -> Result<Value, ApicizeError> {
match serde_json::from_str::<Value>(value) {
Ok(v) => Ok(v),
Err(err) => Err(ApicizeError::from_serde(err, name.to_string())),
}
}
pub fn extract_json(
name: &str,
file_name: &str,
allowed_path: &Option<PathBuf>,
) -> Result<Value, ApicizeError> {
match get_existing_absolute_file_name(file_name, allowed_path) {
Ok(full_file_name) => match File::open(full_file_name) {
Ok(file) => match serde_json::from_reader::<File, Value>(file) {
Ok(v) => Ok(v),
Err(err) => Err(ApicizeError::from_serde(err, name.to_string())),
},
Err(err) => Err(ApicizeError::from_io(err, Some(file_name.to_string()))),
},
Err(err) => Err(err),
}
}
pub fn extract_csv(
name: &str,
file_name: &str,
allowed_path: &Option<PathBuf>,
) -> Result<Value, ApicizeError> {
match get_existing_absolute_file_name(file_name, allowed_path) {
Ok(full_file_name) => match File::open(full_file_name.clone()) {
Ok(file) => {
let mut rdr = csv::Reader::from_reader(file);
let mut data = Vec::<Value>::new();
for record in rdr.deserialize::<Map<String, Value>>() {
match record {
Ok(r) => data.push(serde_json::Value::Object(r)),
Err(err) => return Err(ApicizeError::from_csv(err, name.to_string())),
}
}
Ok(serde_json::Value::Array(data))
}
Err(err) => Err(ApicizeError::from_io(
err,
Some(full_file_name.to_string_lossy().to_string()),
)),
},
Err(err) => Err(err),
}
}
pub fn get_existing_absolute_file_name(
file_name: &str,
allowed_parent_directory: &Option<PathBuf>,
) -> Result<PathBuf, ApicizeError> {
match allowed_parent_directory {
Some(parent_data_path) => {
let data_path = PathBuf::from(parent_data_path).join(file_name);
if data_path.exists() {
Ok(data_path)
} else {
Err(ApicizeError::FileAccess {
description: "Not found".to_string(),
file_name: Some(file_name.to_string()),
})
}
}
None => Err(ApicizeError::Error {
description: "External data files are unavailable in an unsaved workbook".to_string(),
}),
}
}
pub fn build_absolute_file_name(
file_name: &str,
directory: &Path,
) -> Result<PathBuf, ApicizeError> {
let result = PathBuf::from(directory).join(file_name);
if !directory.exists() {
Err(ApicizeError::FileAccess {
description: "Unable to create (invalid directory)".to_string(),
file_name: Some(result.to_string_lossy().to_string()),
})
} else {
Ok(result)
}
}
pub fn get_relative_file_name(
file_path: &Path,
parent_directory: &Path,
) -> Result<String, ApicizeError> {
if !file_path.is_absolute() {
return Err(ApicizeError::Error {
description: format!(
"File path '{}' is not an absolute path",
file_path.display()
),
});
}
match file_path.strip_prefix(parent_directory) {
Ok(relative_path) => Ok(relative_path.to_string_lossy().to_string()),
Err(_) => Err(ApicizeError::Error {
description: format!(
"File '{}' is not a child of '{}'",
file_path.display(),
parent_directory.display()
),
}),
}
}