boreholeio 0.1.0

A library for interacting with borehole.io, a subsurface data management, delivery and visualisation platform
Documentation
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>, // TODO: Not marked as optional in spec
    pub data: Measurements,
}

impl Channel {
    /// Two-pass JSON file deserialization that resolves all relative URIs.
    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);
    }
}

/// Deserializes the specified data structure from the JSON file at the given
/// path.
fn read_json<T: serde::de::DeserializeOwned>(path: &Path) -> Result<T, Error> {
    // Helper error formatting function.
    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()))
}