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