use super::{AccessionIds, AvailableReturnFormats, DataReturnFormats, EBI_DBFETCH_ENDPOINT};
use crate::core::{self, EbioticClient, EbioticHttpClient, Service};
use crate::errors::EbioticError;
use bio::io::fasta::Record;
use std::fmt::{Display, Formatter};
pub mod dbfetchdbs;
#[derive(Debug, Clone)]
pub struct Dbfetch {
pub(crate) client: EbioticClient,
db: dbfetchdbs::DbfetchDbs,
return_format: DataReturnFormats,
style: DbfetchStyle,
}
#[derive(Debug, Clone)]
pub struct DbfetchResult {
data: String,
}
#[derive(Debug, Clone)]
pub enum DbfetchStyle {
Raw,
Html,
}
impl Display for DbfetchStyle {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
DbfetchStyle::Raw => write!(f, "raw"),
DbfetchStyle::Html => write!(f, "html"),
}
}
}
impl Default for Dbfetch {
fn default() -> Self {
Dbfetch {
client: EbioticClient::default(),
db: dbfetchdbs::DbfetchDbs::EnaSequence,
return_format: DataReturnFormats::Fasta,
style: DbfetchStyle::Raw,
}
}
}
impl DbfetchResult {
fn new(data: String) -> DbfetchResult {
DbfetchResult { data }
}
pub fn into_records(self) -> Result<Vec<Record>, EbioticError> {
core::parse_fa_from_bufread(&self.data)
}
pub fn data(self) -> String {
self.data
}
}
impl Dbfetch {
pub fn new(
client: EbioticClient,
db: dbfetchdbs::DbfetchDbs,
return_format: DataReturnFormats,
style: DbfetchStyle,
) -> Dbfetch {
Dbfetch {
client,
db,
return_format,
style,
}
}
pub fn set_db(&mut self, db: dbfetchdbs::DbfetchDbs) {
self.db = db;
}
pub fn set_return_format(&mut self, format: DataReturnFormats) {
self.return_format = format;
}
pub fn set_style(&mut self, style: DbfetchStyle) {
self.style = style;
}
pub fn db(&self) -> &dbfetchdbs::DbfetchDbs {
&self.db
}
pub fn format(&self) -> &DataReturnFormats {
&self.return_format
}
pub fn style(&self) -> &DbfetchStyle {
&self.style
}
}
impl Service for Dbfetch {
type ResultType = DbfetchResult;
type InputType = AccessionIds;
async fn run(&self, input: Self::InputType) -> Result<Self::ResultType, EbioticError> {
if !self
.db
.available_return_formats()
.iter()
.any(|x| x == &self.return_format)
{
return Err(EbioticError::ReturnFormatNotAvailable(
self.return_format.to_string(),
self.db.to_string(),
));
}
log::info!("Submitting DBfetch request");
let res = self
.client
.get(&format!(
"{}?db={}&format={}&style={}&id={}",
EBI_DBFETCH_ENDPOINT, self.db, self.return_format, self.style, input
))
.await?;
Ok(DbfetchResult::new(res))
}
}