use async_trait::async_trait;
use serde_json::Value;
use std::collections::HashMap;
use std::fs::File;
use std::io::Read;
use std::path::Path;
use crate::{CuriesError, Record};
#[async_trait(?Send)]
pub trait PrefixMapSource: Send + Sync {
async fn fetch(self) -> Result<HashMap<String, Value>, CuriesError>;
}
#[async_trait(?Send)]
impl PrefixMapSource for &str {
async fn fetch(self) -> Result<HashMap<String, Value>, CuriesError> {
Ok(serde_json::from_str(&fetch_if_url(self).await?)?)
}
}
#[async_trait(?Send)]
impl PrefixMapSource for &Path {
async fn fetch(self) -> Result<HashMap<String, Value>, CuriesError> {
Ok(serde_json::from_str(&fetch_file(self).await?)?)
}
}
#[async_trait(?Send)]
impl PrefixMapSource for HashMap<String, String> {
async fn fetch(self) -> Result<HashMap<String, Value>, CuriesError> {
Ok(self
.into_iter()
.map(|(key, value)| (key, Value::String(value)))
.collect())
}
}
#[async_trait(?Send)]
impl PrefixMapSource for HashMap<String, Value> {
async fn fetch(self) -> Result<HashMap<String, Value>, CuriesError> {
Ok(self)
}
}
#[async_trait(?Send)]
pub trait ExtendedPrefixMapSource: Send + Sync {
async fn fetch(self) -> Result<Vec<Record>, CuriesError>;
}
#[async_trait(?Send)]
impl ExtendedPrefixMapSource for Vec<Record> {
async fn fetch(self) -> Result<Vec<Record>, CuriesError> {
Ok(self)
}
}
#[async_trait(?Send)]
impl ExtendedPrefixMapSource for &str {
async fn fetch(self) -> Result<Vec<Record>, CuriesError> {
Ok(serde_json::from_str(&fetch_if_url(self).await?)?)
}
}
#[async_trait(?Send)]
impl ExtendedPrefixMapSource for &Path {
async fn fetch(self) -> Result<Vec<Record>, CuriesError> {
Ok(serde_json::from_str(&fetch_file(self).await?)?)
}
}
#[async_trait(?Send)]
pub trait ShaclSource: Send + Sync {
async fn fetch(self) -> Result<String, CuriesError>;
}
#[async_trait(?Send)]
impl ShaclSource for &str {
async fn fetch(self) -> Result<String, CuriesError> {
fetch_if_url(self).await
}
}
#[async_trait(?Send)]
impl ShaclSource for &Path {
async fn fetch(self) -> Result<String, CuriesError> {
fetch_file(self).await
}
}
async fn fetch_if_url(url: &str) -> Result<String, CuriesError> {
if url.starts_with("https://") || url.starts_with("http://") || url.starts_with("ftp://") {
let client = reqwest::Client::new();
Ok(client
.get(url)
.header(reqwest::header::ACCEPT, "application/json")
.send()
.await?
.text()
.await?)
} else {
Ok(url.to_owned())
}
}
async fn fetch_file(path: &Path) -> Result<String, CuriesError> {
let mut file = File::open(path)?;
let mut contents = String::new();
file.read_to_string(&mut contents)?;
Ok(contents)
}