boreholeio 0.1.0

A library for interacting with borehole.io, a subsurface data management, delivery and visualisation platform
Documentation
pub mod array_uri_reference;
pub mod axes;
mod channel;
mod location;
mod logging_run;
mod measurements;
mod raw_data;

use array_uri_reference::ArrayUriReference;
use axes::TileAxis;
use std::fmt::Display;

pub use channel::Channel;
pub use location::Location;
pub use logging_run::LoggingRun;
pub use measurements::Measurements;
pub use raw_data::RawData;

pub type JsonValue = serde_json::Value;
pub type Uuid = String;
pub type DateTime = chrono::DateTime<chrono::FixedOffset>;

// TODO: use a library to handle this?
#[expect(unused)]
type JsonWebToken = String;

#[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize)]
pub struct AccountStatus {
    pub storage_limit: u64,
    pub storage_used_bytes: u64,
}

#[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize)]
pub struct Application {
    pub id: Uuid,
    pub configuration: JsonValue,
    pub sharing: bool,
    pub instance_name: String,
    pub last_connected_at: DateTime,
    pub currently_connected: bool,
    pub organisation: Option<Organisation>,
}

#[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize, Default)]
pub struct Borehole {
    pub id: Option<String>,
    pub name: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub site: Option<Site>,
}

#[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize, Default)]
pub struct Customer {
    pub id: Option<String>,
    pub name: Option<String>,
}

#[serde_with::skip_serializing_none]
#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
pub struct Device {
    pub hostname: String,
    pub username: String,
    pub operating_system: Option<String>,
    pub domain_name: Option<String>,
    pub language: Option<String>,
    pub locale: Option<String>,
    pub ip_addresses: Option<Vec<std::net::Ipv4Addr>>,
}

#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
pub struct LoggingEquipment {
    #[serde(rename = "type")]
    pub type_name: LoggingEquipmentType,
    pub manufacturer: String,
    pub model: String,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub serial: Option<String>,
}

#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
#[serde(rename = "Error")]
pub struct WebError {
    pub status: u32,
    pub title: String,
    pub detail: Option<String>,
    pub source: Option<ErrorSource>,
}

impl Display for WebError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "{} {}", self.status, self.title)?;

        if let Some(detail) = &self.detail {
            write!(f, ": {}", detail)?;
        }
        if let Some(source) = &self.source {
            write!(f, " ({})", source)?;
        }

        Ok(())
    }
}

#[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize)]
pub struct GeneratedApiKey {
    pub id: Uuid,
    pub access_key: String,
    pub secret: String,
}

// #[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize)]
// pub struct GeoJsonPoint {}

// #[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize)]
// pub struct JsonWebToken {}

#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
pub struct Label {
    pub name: String,
    pub bounds: [f64; 2],
    pub units: Option<String>,
    pub transform: Option<PolynomialTransform>,
}

#[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize, Default)]
pub struct Organisation {
    id: Option<String>,
    name: Option<String>,
}

#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
pub struct OrganisationLink {
    id: String,
    application: Application,
    device: Device,
}

#[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize)]
pub struct PaginationMetadata {
    pub page: u32,
    pub size: u32,
    pub pages: u32,
    pub total: u32,
    pub links: PaginationMetadataLinks,
}

#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
#[serde(rename = "polynomial", tag = "type")]
pub struct PolynomialTransform {
    pub coefficients: Vec<f64>,
}

#[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize)]
pub struct Project {
    pub id: Option<String>,
    pub name: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub customer: Option<Customer>,
}

pub struct ReadOnlyApiKey {
    pub id: String,
    pub access_key: String,
    pub created_at: DateTime,
    pub last_used_at: DateTime,
}

#[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize, Default)]
pub struct Site {
    pub id: Option<String>,
    pub name: Option<String>,
}

#[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize, Default)]
pub struct Tag {
    pub id: Option<String>,
    pub name: Option<String>,
}

#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
pub struct Tile {
    pub format: String,
    pub axes: Vec<TileAxis>,
    pub label: Option<Label>,
    pub uri: ArrayUriReference,
}

#[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize)]
pub struct Upload {
    pub id: String,
    pub parts: Vec<UploadPart>,
}

#[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize)]
pub struct UploadPart {
    pub number: i32,
    pub size: u64,
    pub checksums: UploadPartChecksums,
}

#[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize)]
pub struct User {
    pub id: Uuid,
    pub email: String,
    pub admin: bool,
    pub access: bool,
}

#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
#[serde(rename_all = "snake_case")]
pub enum LoggingEquipmentType {
    Winch,
    Tool,
}

#[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize)]
pub struct PaginationMetadataLinks {
    pub first: String,
    pub last: String,
    #[serde(rename = "self")]
    pub current: String,
    pub next: String,
    pub prev: String,
}

#[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize)]
pub struct UploadPartChecksums {
    pub sha256: String,
    pub sha512: String,
}

#[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize)]
pub enum ErrorSource {
    Pointer(String),
    Parameter(String),
    Header(String),
}

impl Display for ErrorSource {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Self::Pointer(pointer) => write!(f, "pointer {}", pointer)?,
            Self::Parameter(parameter) => write!(f, "parameter {}", parameter)?,
            Self::Header(header) => write!(f, "header {}", header)?,
        }

        Ok(())
    }
}