extern crate derive_builder;
pub mod api;
pub mod config;
pub mod consts;
pub mod doctor;
pub mod environment;
pub mod errors;
pub mod fetch;
pub mod io;
pub mod ontology;
pub mod options;
pub mod policy;
pub mod progress;
#[macro_use]
pub mod util;
pub mod transform;
use crate::ontology::GraphIdentifier;
use chrono::prelude::*;
use oxigraph::model::NamedNode;
use std::fmt::{self, Display};
use std::path::{Path, PathBuf};
fn pretty_bytes(bytes: u64) -> String {
const UNITS: [&str; 6] = ["B", "KiB", "MiB", "GiB", "TiB", "PiB"];
let mut value = bytes as f64;
let mut unit = 0;
while value >= 1024.0 && unit < UNITS.len() - 1 {
value /= 1024.0;
unit += 1;
}
if unit == 0 {
format!("{bytes} {}", UNITS[unit])
} else {
format!("{value:.2} {}", UNITS[unit])
}
}
pub trait ToUriString {
fn to_uri_string(&self) -> String;
}
impl ToUriString for NamedNode {
fn to_uri_string(&self) -> String {
self.as_str().to_string()
}
}
impl ToUriString for &NamedNode {
fn to_uri_string(&self) -> String {
self.as_str().to_string()
}
}
impl ToUriString for GraphIdentifier {
fn to_uri_string(&self) -> String {
self.name().as_str().to_string()
}
}
impl ToUriString for &GraphIdentifier {
fn to_uri_string(&self) -> String {
self.name().as_str().to_string()
}
}
pub struct FailedImport {
ontology: GraphIdentifier,
error: String,
}
impl FailedImport {
pub fn new(ontology: GraphIdentifier, error: String) -> Self {
Self { ontology, error }
}
}
impl Display for FailedImport {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"Failed to import ontology {}: {}",
self.ontology.to_uri_string(),
self.error
)
}
}
pub struct EnvironmentStatus {
exists: bool,
ontoenv_path: Option<PathBuf>,
num_ontologies: usize,
last_updated: Option<DateTime<Utc>>,
store_size: u64,
missing_imports: Vec<NamedNode>,
}
impl EnvironmentStatus {
pub fn exists(&self) -> bool {
self.exists
}
pub fn ontoenv_path(&self) -> Option<&Path> {
self.ontoenv_path.as_deref()
}
pub fn num_ontologies(&self) -> usize {
self.num_ontologies
}
pub fn last_updated(&self) -> Option<&DateTime<Utc>> {
self.last_updated.as_ref()
}
pub fn store_size(&self) -> u64 {
self.store_size
}
pub fn missing_imports(&self) -> &[NamedNode] {
&self.missing_imports
}
}
impl std::fmt::Display for EnvironmentStatus {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
if !self.exists {
return write!(f, "No environment found");
}
let last_updated = match self.last_updated {
Some(last_updated) => last_updated
.with_timezone(&Local)
.format("%Y-%m-%d %H:%M:%S %Z")
.to_string(),
None => "N/A".to_string(),
};
let ontoenv_path = self
.ontoenv_path
.as_ref()
.map(|path| path.display().to_string())
.unwrap_or_else(|| "N/A".to_string());
write!(
f,
"Environment Path: {}\n\
Number of Ontologies: {}\n\
Last Updated: {}\n\
Store Size: {}",
ontoenv_path,
self.num_ontologies,
last_updated,
pretty_bytes(self.store_size),
)?;
if !self.missing_imports.is_empty() {
write!(f, "\n\nMissing Imports:")?;
for import in &self.missing_imports {
write!(f, "\n - {}", import.to_uri_string())?;
}
}
Ok(())
}
}