#[cfg(any(feature = "url", feature = "aws"))]
use crate::error::Error;
use crate::error::Result;
#[cfg(feature = "experimental")]
use crate::storage::c4gh::C4GHKeys;
use crate::storage::file::File;
#[cfg(feature = "url")]
use crate::storage::json_path::JsonPath;
#[cfg(feature = "aws")]
use crate::storage::s3::S3;
#[cfg(feature = "url")]
use crate::storage::url::Url;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};
#[cfg(feature = "experimental")]
pub mod c4gh;
pub mod file;
#[cfg(feature = "url")]
pub mod json_path;
#[cfg(feature = "aws")]
pub mod s3;
#[cfg(feature = "url")]
pub mod url;
#[derive(Debug)]
pub struct ResolvedId(String);
impl ResolvedId {
pub fn new(resolved_id: String) -> Self {
Self(resolved_id)
}
pub fn into_inner(self) -> String {
self.0
}
}
#[derive(JsonSchema, Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
#[serde(tag = "kind", deny_unknown_fields)]
#[non_exhaustive]
pub enum Backend {
#[serde(alias = "file", alias = "FILE")]
File(File),
#[cfg(feature = "aws")]
#[serde(alias = "s3")]
S3(S3),
#[cfg(feature = "url")]
#[serde(alias = "url", alias = "URL")]
Url(Box<Url>),
#[cfg(feature = "url")]
#[serde(alias = "json_path", alias = "JSON_PATH")]
JsonPath(Box<JsonPath>),
}
impl Backend {
pub fn as_file(&self) -> Result<&File> {
match self {
Backend::File(file) => Ok(file),
#[cfg(feature = "aws")]
Backend::S3(_) => Err(Error::ParseError("not a `File` variant".to_string())),
#[cfg(feature = "url")]
Backend::Url(_) => Err(Error::ParseError("not a `File` variant".to_string())),
#[cfg(feature = "url")]
Backend::JsonPath(_) => Err(Error::ParseError("not a `File` variant".to_string())),
}
}
pub fn add_ticket_header(&mut self, header: String) {
match self {
Backend::File(file) => {
file.add_ticket_header(header);
}
#[cfg(feature = "aws")]
Backend::S3(_) => {}
#[cfg(feature = "url")]
Backend::Url(_) => {}
#[cfg(feature = "url")]
Backend::JsonPath(_) => {}
}
}
pub fn ticket_headers(&self) -> Option<&[String]> {
match self {
Backend::File(file) => Some(file.ticket_headers()),
#[cfg(feature = "aws")]
Backend::S3(_) => None,
#[cfg(feature = "url")]
Backend::Url(_) => None,
#[cfg(feature = "url")]
Backend::JsonPath(_) => None,
}
}
pub fn is_defaulted(&self) -> bool {
match self {
Backend::File(file) => file.is_defaulted,
#[cfg(feature = "aws")]
Backend::S3(s3) => s3.is_defaulted,
#[cfg(feature = "url")]
Backend::Url(url) => url.is_defaulted,
#[cfg(feature = "url")]
Backend::JsonPath(json_path) => json_path.is_defaulted,
}
}
#[cfg(feature = "aws")]
pub fn as_s3(&self) -> Result<&S3> {
if let Backend::S3(s3) = self {
Ok(s3)
} else {
Err(Error::ParseError("not a `S3` variant".to_string()))
}
}
#[cfg(feature = "url")]
pub fn as_url(&self) -> Result<&Url> {
if let Backend::Url(url) = self {
Ok(url)
} else {
Err(Error::ParseError("not a `Url` variant".to_string()))
}
}
#[cfg(feature = "url")]
pub fn as_url_mut(&mut self) -> Result<&mut Url> {
if let Backend::Url(url) = self {
Ok(url)
} else {
Err(Error::ParseError("not a `Url` variant".to_string()))
}
}
#[cfg(feature = "url")]
pub fn as_json_path(&self) -> Result<&JsonPath> {
if let Backend::JsonPath(json_path) = self {
Ok(json_path)
} else {
Err(Error::ParseError("not a `JsonPath` variant".to_string()))
}
}
#[cfg(feature = "url")]
pub fn as_json_path_mut(&mut self) -> Result<&mut JsonPath> {
if let Backend::JsonPath(json_path) = self {
Ok(json_path)
} else {
Err(Error::ParseError("not a `JsonPath` variant".to_string()))
}
}
#[cfg(feature = "experimental")]
pub fn set_keys(&mut self, keys: Option<C4GHKeys>) {
match self {
Backend::File(file) => file.set_keys(keys),
#[cfg(feature = "aws")]
Backend::S3(s3) => s3.set_keys(keys),
#[cfg(feature = "url")]
Backend::Url(url) => url.set_keys(keys),
#[cfg(feature = "url")]
Backend::JsonPath(json_path) => json_path.set_keys(keys),
}
}
}
impl Default for Backend {
fn default() -> Self {
Self::File(Default::default())
}
}
#[cfg(test)]
pub(crate) mod tests {
use crate::config::tests::{test_config_from_env, test_config_from_file};
use crate::storage::Backend;
#[test]
fn config_storage_tagged_local_file() {
test_config_from_file(
r#"
[[locations]]
regex = "regex"
backend.kind = "File"
"#,
|config| {
assert!(matches!(
config.locations().first().unwrap().backend(),
Backend::File { .. }
));
},
);
}
#[test]
fn config_storage_tagged_local_env() {
test_config_from_env(
vec![("HTSGET_LOCATIONS", "[{backend={ kind=File }}]")],
|config| {
assert!(matches!(
config.locations().first().unwrap().backend(),
Backend::File { .. }
));
},
);
}
#[cfg(feature = "aws")]
#[test]
fn config_storage_tagged_s3_file() {
test_config_from_file(
r#"
[[locations]]
regex = "regex"
backend.kind = "S3"
"#,
|config| {
assert!(matches!(
config.locations().first().unwrap().backend(),
Backend::S3(..)
));
},
);
}
#[cfg(feature = "aws")]
#[test]
fn config_storage_tagged_s3_env() {
test_config_from_env(
vec![("HTSGET_LOCATIONS", "[{backend={ kind=S3 }}]")],
|config| {
assert!(matches!(
config.locations().first().unwrap().backend(),
Backend::S3(..)
));
},
);
}
}