use super::{
array_uri_reference::{AbsoluteUri, ArrayUriReference, Error},
Measurements,
};
use crate::array_cache::UriResolvable;
use serde::{Deserialize, Serialize};
use std::path::Path;
#[serde_with::skip_serializing_none]
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Channel {
pub index: i64,
pub name: String,
pub group: Option<String>, pub data: Measurements,
}
impl Channel {
pub fn from_json_file(path: &Path) -> Result<Self, Error> {
let mut channel: Self = read_json(path)?;
let absolute = path.canonicalize().map_err(|e| {
format!("Failed to build absolute directory from {path:?} file with an error {e}")
})?;
let uri = ArrayUriReference::from(absolute.as_path());
channel.set_base_for_relative_uris(uri.base().ok_or("Couldn't build URI for path.")?);
Ok(channel)
}
}
impl UriResolvable for Channel {
fn set_base_for_relative_uris(&mut self, base_uri: &AbsoluteUri) {
self.data.set_base_for_relative_uris(base_uri);
}
}
fn read_json<T: serde::de::DeserializeOwned>(path: &Path) -> Result<T, Error> {
let format_error = |error_message: String| -> Error {
format!(
"Failed to read JSON from {} due to an error: {}",
path.display(),
error_message
)
};
if !path.exists() || !path.is_file() {
return Err(format_error("invalid file path".into()));
}
serde_json::from_reader(
std::fs::OpenOptions::new()
.read(true)
.open(path)
.map_err(|e| format_error(e.to_string()))?,
)
.map_err(|e| format_error(e.to_string()))
}