ambient_package_semantic 0.3.1

Semantic analysis for the Ambient package manifests
Documentation
use std::path::Path;

use thiserror::Error;
use url::Url;

#[derive(Error, Debug)]
pub enum RetrieveError {
    #[error("file reading is not supported on web")]
    FileReadingNotSupportedOnWeb,
    #[error("failed to read path {file_path:?}")]
    FailedToReadPath { file_path: String },
    #[error("failed to get URL {url:?}")]
    FailedToGetUrl { url: Url },
    #[error("invalid file path for URL {url:?}")]
    InvalidFilePathForUrl { url: Url },
    #[error("failed to get text from URL {url:?}")]
    FailedToGetTextFromUrl { url: Url },
}

pub fn retrieve_file(path: &Path) -> Result<String, RetrieveError> {
    #[cfg(target_os = "unknown")]
    return Err(RetrieveError::FileReadingNotSupportedOnWeb);

    #[cfg(not(target_os = "unknown"))]
    return std::fs::read_to_string(path).map_err(|_| RetrieveError::FailedToReadPath {
        file_path: path.to_string_lossy().to_string(),
    });
}

pub async fn retrieve_url(url: &Url) -> Result<String, RetrieveError> {
    if url.scheme() == "file" {
        #[cfg(target_os = "unknown")]
        return Err(RetrieveError::FileReadingNotSupportedOnWeb);

        #[cfg(not(target_os = "unknown"))]
        return retrieve_file(
            &url.to_file_path()
                .map_err(|_| RetrieveError::InvalidFilePathForUrl { url: url.clone() })?,
        );
    }

    reqwest::get(url.clone())
        .await
        .map_err(|_| RetrieveError::FailedToGetUrl { url: url.clone() })?
        .text()
        .await
        .map_err(|_| RetrieveError::FailedToGetTextFromUrl { url: url.clone() })
}