use rocket::request::FromParam;
use semsimian::enums::{DirectionalityEnum, MetricEnum, SearchTypeEnum};
use semsimian::{Predicate, RustSemsimian, TermID};
use std::collections::HashSet;
use std::path::PathBuf;
use std::sync::Mutex;
pub fn get_rss_instance() -> RustSemsimian {
let mut db_path = PathBuf::new();
if let Some(phenio_path) = std::env::var_os("PHENIO_PATH") {
db_path.push(phenio_path);
} else if let Some(home) = std::env::var_os("HOME") {
db_path.push(home);
db_path.push(".data/oaklib/phenio.db");
} else {
panic!("Failed to get home directory");
}
let db = Some(db_path.to_str().expect("Failed to convert path to string"));
let predicates: Option<Vec<Predicate>> = Some(vec!["rdfs:subClassOf".to_string()]);
let assoc_predicate: HashSet<TermID> = HashSet::from(["biolink:has_phenotype".to_string()]);
let rss = Mutex::new(Some(RustSemsimian::new(None, predicates, None, db, None)));
{
let mut locked_rss = rss.lock().unwrap();
if let Some(rss_instance) = locked_rss.as_mut() {
rss_instance.pregenerate_cache(&assoc_predicate, &SearchTypeEnum::Flat);
}
}
let mut guard = rss.lock().unwrap();
let rss_instance: Option<RustSemsimian> = guard.take();
rss_instance.unwrap()
}
pub struct MetricEnumWrapper(pub MetricEnum);
impl<'a> FromParam<'a> for MetricEnumWrapper {
type Error = &'a str;
fn from_param(param: &'a str) -> Result<Self, Self::Error> {
match param {
"jaccard_similarity" => Ok(MetricEnumWrapper(MetricEnum::JaccardSimilarity)),
"phenodigm_score" => Ok(MetricEnumWrapper(MetricEnum::PhenodigmScore)),
"cosine_similarity" => Ok(MetricEnumWrapper(MetricEnum::CosineSimilarity)),
_ => Ok(MetricEnumWrapper(MetricEnum::AncestorInformationContent)),
}
}
}
pub struct DirectionalityEnumWrapper(pub DirectionalityEnum);
impl<'a> FromParam<'a> for DirectionalityEnumWrapper {
type Error = &'a str;
fn from_param(param: &'a str) -> Result<Self, Self::Error> {
match param {
"bidirectional" => Ok(DirectionalityEnumWrapper(DirectionalityEnum::Bidirectional)),
"subject_to_object" => Ok(DirectionalityEnumWrapper(
DirectionalityEnum::SubjectToObject,
)),
"object_to_subject" => Ok(DirectionalityEnumWrapper(
DirectionalityEnum::ObjectToSubject,
)),
_ => Ok(DirectionalityEnumWrapper(DirectionalityEnum::Bidirectional)),
}
}
}
use std::ops::Deref;
impl Deref for MetricEnumWrapper {
type Target = MetricEnum;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl Deref for DirectionalityEnumWrapper {
type Target = DirectionalityEnum;
fn deref(&self) -> &Self::Target {
&self.0
}
}