htsget_http/
service_info.rs1use htsget_config::config;
2use htsget_config::types::Format;
3use htsget_search::HtsGet;
4use serde::{Deserialize, Serialize};
5use serde_json::Value;
6use std::collections::HashMap;
7use tracing::debug;
8use tracing::instrument;
9
10use crate::Endpoint;
11
12const READS_FORMATS: [&str; 2] = ["BAM", "CRAM"];
13const VARIANTS_FORMATS: [&str; 2] = ["VCF", "BCF"];
14
15const HTSGET_GROUP: &str = "org.ga4gh";
16const HTSGET_ARTIFACT: &str = "htsget";
17const HTSGET_VERSION: &str = "1.3.0";
18
19#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Default)]
21#[serde(rename_all = "camelCase")]
22pub struct ServiceInfo {
23 #[serde(flatten)]
24 pub fields: HashMap<String, Value>,
25 #[serde(rename = "type")]
26 pub service_type: Type,
27 pub htsget: Htsget,
28}
29
30#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
31#[serde(rename_all = "camelCase")]
32pub struct Type {
33 pub group: String,
34 pub artifact: String,
35 pub version: String,
36}
37
38impl Default for Type {
39 fn default() -> Self {
40 Self {
41 group: HTSGET_GROUP.to_string(),
42 artifact: HTSGET_ARTIFACT.to_string(),
43 version: HTSGET_VERSION.to_string(),
44 }
45 }
46}
47
48#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Default)]
49#[serde(rename_all = "camelCase")]
50pub struct Htsget {
51 pub datatype: String,
52 pub formats: Vec<String>,
53 pub fields_parameters_effective: bool,
54 pub tags_parameters_effective: bool,
55}
56
57impl ServiceInfo {
58 pub fn new(
59 endpoint: Endpoint,
60 supported_formats: &[Format],
61 fields_effective: bool,
62 tags_effective: bool,
63 fields: HashMap<String, Value>,
64 ) -> Self {
65 let htsget_info = Htsget {
66 datatype: match endpoint {
67 Endpoint::Reads => "reads",
68 Endpoint::Variants => "variants",
69 }
70 .to_string(),
71 formats: supported_formats
72 .iter()
73 .map(|format| format.to_string())
74 .filter(|format| match endpoint {
75 Endpoint::Reads => READS_FORMATS.contains(&format.as_str()),
76 Endpoint::Variants => VARIANTS_FORMATS.contains(&format.as_str()),
77 })
78 .collect(),
79 fields_parameters_effective: fields_effective,
80 tags_parameters_effective: tags_effective,
81 };
82
83 Self {
84 fields,
85 service_type: Default::default(),
86 htsget: htsget_info,
87 }
88 }
89}
90
91#[instrument(level = "debug", skip_all)]
92pub fn get_service_info_json(
93 endpoint: Endpoint,
94 searcher: impl HtsGet + Send + Sync + 'static,
95 config: config::service_info::ServiceInfo,
96) -> ServiceInfo {
97 debug!(endpoint = ?endpoint,"getting service-info response for endpoint");
98 ServiceInfo::new(
99 endpoint,
100 &searcher.get_supported_formats(),
101 searcher.are_field_parameters_effective(),
102 searcher.are_tag_parameters_effective(),
103 config.into_inner(),
104 )
105}