use std::borrow::Cow;
use std::io::Read;
use std::path::Path;
use std::ffi::OsStr;
use std::fs::read_to_string;
use reqwest::Method;
use super::{ Request, RequestBody };
use crate::{
settings::Settings,
multipart::FormFile,
job::{ JobId, JobStatus },
error::Result,
};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct SubmitId {
#[serde(rename = "pdbName")]
pub pdb_id: String,
#[serde(flatten, default)]
pub settings: Settings,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct SubmitStructure {
#[serde(rename = "file")]
pub pdb_structure: FormFile,
#[serde(rename = "fileName", default, skip_serializing_if = "Option::is_none")]
pub file_name: Option<String>,
#[serde(flatten, default)]
pub settings: Settings,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SubmitResponse {
#[serde(rename = "jobid")]
pub job_id: JobId,
pub status: JobStatus,
}
impl SubmitId {
pub fn with_pdb_id<T: Into<String>>(pdb_id: T) -> Self {
SubmitId {
pdb_id: pdb_id.into(),
settings: Settings::default(),
}
}
}
impl SubmitStructure {
pub fn with_pdb_structure<T: Into<String>>(pdb_structure: T) -> Self {
SubmitStructure {
pdb_structure: FormFile::with_contents_and_file_name(
pdb_structure.into(),
String::from("rust_ring_api_dummy.pdb"),
),
file_name: None,
settings: Settings::default(),
}
}
pub fn with_reader<R: Read>(mut reader: R) -> Result<Self> {
let mut structure = String::new();
reader.read_to_string(&mut structure)?;
Ok(Self::with_pdb_structure(structure))
}
pub fn with_pdb_file<P: AsRef<Path>>(file: P) -> Result<Self> {
let path = file.as_ref();
let maybe_file_name = path
.file_name()
.and_then(OsStr::to_str)
.map(Into::into);
let structure = read_to_string(path)?;
Ok(SubmitStructure {
pdb_structure: FormFile::with_contents_and_file_name(
structure,
maybe_file_name.clone().unwrap_or_else(
|| String::from("rust_ring_api_dummy.pdb")
)
),
file_name: maybe_file_name,
settings: Settings::default(),
})
}
pub fn file_name<T: Into<String>>(mut self, file_name: T) -> Self {
let file_name = file_name.into();
self.file_name.replace(file_name.clone());
self.pdb_structure.set_file_name(file_name);
self
}
pub fn or_file_name<T: Into<String>>(self, file_name: T) -> Self {
if self.file_name.is_none() {
self.file_name(file_name)
} else {
self
}
}
pub fn settings(self, settings: Settings) -> Self {
SubmitStructure { settings, ..self }
}
}
impl Request for SubmitId {
type Body = Self;
type Response = SubmitResponse;
const METHOD: Method = Method::POST;
fn endpoint(&self) -> Cow<str> {
Cow::from("/submit")
}
fn body(&self) -> RequestBody<&Self::Body> {
RequestBody::Json(self)
}
}
impl Request for SubmitStructure {
type Body = Self;
type Response = SubmitResponse;
const METHOD: Method = Method::POST;
fn endpoint(&self) -> Cow<str> {
Cow::from("/submit")
}
fn body(&self) -> RequestBody<&Self::Body> {
RequestBody::Multipart(self)
}
}