boreholeio 0.1.0

A library for interacting with borehole.io, a subsurface data management, delivery and visualisation platform
Documentation
#![allow(unused)]
// Putting off robust error handling for now

use serde::{
    de::{self, DeserializeOwned},
    Deserialize,
};
use serde_json::{Map, Value};

use crate::schema::WebError;

pub(crate) enum ApiResponse<T: DeserializeOwned> {
    Success(SuccessResponse<T>),
    Error(ErrorResponse),
}

// Taken from https://github.com/serde-rs/serde/issues/880#issuecomment-294315051
impl<'de, T: DeserializeOwned> Deserialize<'de> for ApiResponse<T> {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let mut map = Map::deserialize(deserializer)?;

        let success = map
            .remove("success")
            .ok_or_else(|| de::Error::missing_field("success"))
            .map(Deserialize::deserialize)?
            .map_err(de::Error::custom)?;

        let rest = Value::Object(map);

        if success {
            SuccessResponse::deserialize(rest)
                .map(ApiResponse::Success)
                .map_err(de::Error::custom)
        } else {
            ErrorResponse::deserialize(rest)
                .map(ApiResponse::Error)
                .map_err(de::Error::custom)
        }
    }
}

impl<T: DeserializeOwned> ApiResponse<T> {
    pub(crate) fn success(&self) -> bool {
        match self {
            ApiResponse::Success(_) => true,
            ApiResponse::Error(_) => false,
        }
    }
}

#[derive(Deserialize)]
#[serde(bound = "T: DeserializeOwned")]
pub(crate) struct SuccessResponse<T: DeserializeOwned> {
    pub(crate) data: Option<T>,
    pub(crate) pagination: Option<()>,
}

#[derive(Deserialize)]
pub(crate) struct ErrorResponse {
    pub(crate) errors: Vec<WebError>,
}