1use htsget_config::types::{Query, Request};
2use serde::{Deserialize, Serialize};
3use tracing::instrument;
4
5use crate::{Endpoint, QueryBuilder, Result, match_format, set_query_builder};
6
7#[derive(Serialize, Deserialize, Debug, Default)]
11pub struct PostRequest {
12 pub format: Option<String>,
13 pub class: Option<String>,
14 pub fields: Option<Vec<String>>,
15 pub tags: Option<Vec<String>>,
16 pub notags: Option<Vec<String>>,
17 pub regions: Option<Vec<Region>>,
18 #[serde(rename = "encryptionScheme")]
19 pub encryption_scheme: Option<String>,
20}
21
22#[derive(Serialize, Deserialize, Debug)]
25pub struct Region {
26 #[serde(rename = "referenceName")]
27 pub reference_name: String,
28 pub start: Option<u32>,
29 pub end: Option<u32>,
30}
31
32impl PostRequest {
33 #[instrument(level = "trace", skip_all, ret)]
35 pub(crate) fn get_queries(self, request: Request, endpoint: &Endpoint) -> Result<Vec<Query>> {
36 let format = match_format(endpoint, self.format.clone())?;
37
38 if let Some(ref regions) = self.regions {
39 regions
40 .iter()
41 .map(|region| {
42 set_query_builder(
43 QueryBuilder::new(request.clone(), format),
44 self.class.clone(),
45 Some(region.reference_name.clone()),
46 Self::join_vec(self.fields.clone()),
47 (
48 Self::join_vec(self.tags.clone()),
49 Self::join_vec(self.notags.clone()),
50 ),
51 (
52 region.start.map(|start| start.to_string()),
53 region.end.map(|end| end.to_string()),
54 ),
55 self.encryption_scheme.clone(),
56 )
57 })
58 .collect::<Result<Vec<Query>>>()
59 } else {
60 Ok(vec![set_query_builder(
61 QueryBuilder::new(request, format),
62 self.class,
63 None::<String>,
64 Self::join_vec(self.fields),
65 (Self::join_vec(self.tags), Self::join_vec(self.notags)),
66 (None::<String>, None::<String>),
67 self.encryption_scheme,
68 )?])
69 }
70 }
71
72 fn join_vec(fields: Option<Vec<String>>) -> Option<String> {
73 fields.map(|fields| fields.join(","))
74 }
75}
76
77#[cfg(test)]
78mod tests {
79 use htsget_config::types::{Class, Format};
80
81 use super::*;
82
83 #[test]
84 fn post_request_without_regions() {
85 let request = Request::new_with_id("id".to_string());
86
87 assert_eq!(
88 PostRequest {
89 format: Some("VCF".to_string()),
90 class: Some("header".to_string()),
91 fields: None,
92 tags: None,
93 notags: None,
94 regions: None,
95 encryption_scheme: None,
96 }
97 .get_queries(request.clone(), &Endpoint::Variants)
98 .unwrap(),
99 vec![Query::new("id", Format::Vcf, request).with_class(Class::Header)]
100 );
101 }
102
103 #[test]
104 fn post_request_with_one_region() {
105 let request = Request::new_with_id("id".to_string());
106
107 assert_eq!(
108 PostRequest {
109 format: Some("VCF".to_string()),
110 class: Some("header".to_string()),
111 fields: None,
112 tags: None,
113 notags: None,
114 regions: Some(vec![Region {
115 reference_name: "20".to_string(),
116 start: Some(150),
117 end: Some(153),
118 }]),
119 encryption_scheme: None,
120 }
121 .get_queries(request.clone(), &Endpoint::Variants)
122 .unwrap(),
123 vec![
124 Query::new("id", Format::Vcf, request)
125 .with_class(Class::Header)
126 .with_reference_name("20".to_string())
127 .with_start(150)
128 .with_end(153)
129 ]
130 );
131 }
132
133 #[test]
134 fn post_request_with_regions() {
135 let request = Request::new_with_id("id".to_string());
136
137 assert_eq!(
138 PostRequest {
139 format: Some("VCF".to_string()),
140 class: Some("header".to_string()),
141 fields: None,
142 tags: None,
143 notags: None,
144 regions: Some(vec![
145 Region {
146 reference_name: "20".to_string(),
147 start: Some(150),
148 end: Some(153),
149 },
150 Region {
151 reference_name: "11".to_string(),
152 start: Some(152),
153 end: Some(154),
154 }
155 ]),
156 encryption_scheme: None,
157 }
158 .get_queries(request.clone(), &Endpoint::Variants)
159 .unwrap(),
160 vec![
161 Query::new("id", Format::Vcf, request.clone())
162 .with_class(Class::Header)
163 .with_reference_name("20".to_string())
164 .with_start(150)
165 .with_end(153),
166 Query::new("id", Format::Vcf, request)
167 .with_class(Class::Header)
168 .with_reference_name("11".to_string())
169 .with_start(152)
170 .with_end(154)
171 ]
172 );
173 }
174}