boreholeio 0.1.0

A library for interacting with borehole.io, a subsurface data management, delivery and visualisation platform
Documentation
use super::{AbsoluteUri, Authority, Fragment, Query, Scheme};
use iri_string::types::{UriStr, UriString};
use std::path::{Path, PathBuf};

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Uri(pub(super) UriString);

impl Uri {
    pub fn as_str(&self) -> &str {
        self.0.as_str()
    }

    pub fn to_absolute_and_fragment(&self) -> (AbsoluteUri, Option<Fragment>) {
        let (absolute, fragment) = self.0.to_absolute_and_fragment();
        (absolute.into(), fragment.map(Fragment::from))
    }

    pub fn scheme(&self) -> Scheme {
        Scheme(self.0.scheme_str())
    }

    pub fn authority(&self) -> Option<Authority> {
        self.0.authority_str().map(Authority)
    }

    pub fn query(&self) -> Option<Query> {
        self.0.query().map(Query::from)
    }

    pub fn fragment(&self) -> Option<Fragment> {
        self.0.fragment().map(Fragment::from)
    }
}

impl From<&UriStr> for Uri {
    fn from(value: &UriStr) -> Self {
        Self(value.to_owned())
    }
}

impl From<&AbsoluteUri> for Uri {
    fn from(value: &AbsoluteUri) -> Self {
        Self(value.0.to_owned().into())
    }
}

impl TryFrom<&Path> for Uri {
    type Error = String;

    fn try_from(value: &Path) -> Result<Self, Self::Error> {
        let absolute_uri: AbsoluteUri = value.try_into()?;
        Ok((&absolute_uri).into())
    }
}

impl TryFrom<&Uri> for PathBuf {
    type Error = String;

    fn try_from(value: &Uri) -> Result<Self, Self::Error> {
        #[allow(clippy::collapsible_else_if)]
        if value.fragment().is_some() {
            Err(format!(
                "Can't convert URI with a fragment {value:?} into a path."
            ))
        } else if value.query().is_some() {
            Err(format!(
                "Can't convert URI with a query {value:?} into a path."
            ))
        } else if !value.authority().unwrap_or(Authority::EMPTY).is_empty() {
            Err(format!(
                "Can't convert URI with a non-empty authority {value:?} into a path."
            ))
        } else if value.scheme() != Scheme::FILE {
            Err(format!(
                "Can't convert URI with a scheme other than 'file' {value:?} into a path."
            ))
        } else {
            if cfg!(unix) {
                // Leave the leading slash on the path string, as it's the root directory.
                Ok(value.0.path_str().into())
            } else if cfg!(windows) {
                // Strip the leading slash off the path string.
                Ok((&value.0.path_str()[1..]).into())
            } else {
                Err(format!(
                    "Unsure of operating system path semantics, so cannot convert URI {value:?} to a path."),
                )
            }
        }
    }
}