thunkmetrc_wrapper/services/
strains_service.rs1use thunkmetrc_client::MetrcClient;
2use serde_json::Value;
3use std::error::Error;
4use std::sync::Arc;
5#[allow(unused_imports)]
6use futures::Stream;
7use crate::ratelimiter::MetrcRateLimiter;
8#[allow(unused_imports)]
9use crate::utils::iterate_pages;
10#[allow(unused_imports)]
11use crate::models::*;
12
13pub struct StrainsService {
14 client: MetrcClient,
15 rate_limiter: Arc<MetrcRateLimiter>,
16}
17
18impl StrainsService {
19 pub fn new(client: MetrcClient, rate_limiter: Arc<MetrcRateLimiter>) -> Self {
20 Self {
21 client,
22 rate_limiter,
23 }
24 }
25
26 pub async fn create_strains(&self, license_number: Option<String>, body: Option<Vec<CreateStrainsRequestItem>>) -> std::result::Result<Option<WriteResponse>, Box<dyn Error + Send + Sync>> {
34 let body_val = if let Some(b) = body { Some(serde_json::to_value(b)?) } else { None };
35 let client = self.client.clone();
36
37 let body_val = body_val.clone();
38
39 let resp_val = self.rate_limiter.execute(None,false,
40 move || {
41 let client = client.clone();
42 let license_number = license_number.clone();
43 let body_val = body_val.clone();
44
45 async move {
46 client.strains().create_strains(license_number, body_val.as_ref()
47 ).await.map_err(|e| e as Box<dyn Error + Send + Sync>)
48 }
49 }
50 ).await?;
51
52 if let Some(v) = resp_val {
53 let typed: WriteResponse = serde_json::from_value(v)?;
54 Ok(Some(typed))
55 } else {
56 Ok(None)
57 }
58 }
59
60 pub async fn delete_strains_by_id(&self, id: &str, license_number: Option<String>, body: Option<&Value>) -> std::result::Result<Option<serde_json::Value>, Box<dyn Error + Send + Sync>> {
68 let body_val = if let Some(b) = body { Some(serde_json::to_value(b)?) } else { None };
69 let id = id.to_string();
70 let client = self.client.clone();
71
72 let body_val = body_val.clone();
73
74 let resp_val = self.rate_limiter.execute(None,false,
75 move || {
76 let client = client.clone();
77 let id = id.clone();
78 let license_number = license_number.clone();
79 let body_val = body_val.clone();
80
81 async move {
82 client.strains().delete_strains_by_id(&id, license_number, body_val.as_ref()
83 ).await.map_err(|e| e as Box<dyn Error + Send + Sync>)
84 }
85 }
86 ).await?;
87
88 if let Some(v) = resp_val {
89 let typed: serde_json::Value = serde_json::from_value(v)?;
90 Ok(Some(typed))
91 } else {
92 Ok(None)
93 }
94 }
95
96 pub async fn get_active_strains(&self, last_modified_end: Option<String>, last_modified_start: Option<String>, license_number: Option<String>, page_number: Option<String>, page_size: Option<String>, body: Option<&Value>) -> std::result::Result<Option<PaginatedResponse<Strain>>, Box<dyn Error + Send + Sync>> {
107 let body_val = if let Some(b) = body { Some(serde_json::to_value(b)?) } else { None };
108 let client = self.client.clone();
109
110 let body_val = body_val.clone();
111
112 let resp_val = self.rate_limiter.execute(None,true,
113 move || {
114 let client = client.clone();
115 let last_modified_end = last_modified_end.clone();
116 let last_modified_start = last_modified_start.clone();
117 let license_number = license_number.clone();
118 let page_number = page_number.clone();
119 let page_size = page_size.clone();
120 let body_val = body_val.clone();
121
122 async move {
123 client.strains().get_active_strains(last_modified_end, last_modified_start, license_number, page_number, page_size, body_val.as_ref()
124 ).await.map_err(|e| e as Box<dyn Error + Send + Sync>)
125 }
126 }
127 ).await?;
128
129 if let Some(v) = resp_val {
130 let typed: PaginatedResponse<Strain> = serde_json::from_value(v)?;
131 Ok(Some(typed))
132 } else {
133 Ok(None)
134 }
135 }
136
137 pub async fn get_inactive_strains(&self, license_number: Option<String>, page_number: Option<String>, page_size: Option<String>, body: Option<&Value>) -> std::result::Result<Option<PaginatedResponse<Strain>>, Box<dyn Error + Send + Sync>> {
146 let body_val = if let Some(b) = body { Some(serde_json::to_value(b)?) } else { None };
147 let client = self.client.clone();
148
149 let body_val = body_val.clone();
150
151 let resp_val = self.rate_limiter.execute(None,true,
152 move || {
153 let client = client.clone();
154 let license_number = license_number.clone();
155 let page_number = page_number.clone();
156 let page_size = page_size.clone();
157 let body_val = body_val.clone();
158
159 async move {
160 client.strains().get_inactive_strains(license_number, page_number, page_size, body_val.as_ref()
161 ).await.map_err(|e| e as Box<dyn Error + Send + Sync>)
162 }
163 }
164 ).await?;
165
166 if let Some(v) = resp_val {
167 let typed: PaginatedResponse<Strain> = serde_json::from_value(v)?;
168 Ok(Some(typed))
169 } else {
170 Ok(None)
171 }
172 }
173
174 pub async fn get_strains_by_id(&self, id: &str, license_number: Option<String>, body: Option<&Value>) -> std::result::Result<Option<Strain>, Box<dyn Error + Send + Sync>> {
182 let body_val = if let Some(b) = body { Some(serde_json::to_value(b)?) } else { None };
183 let id = id.to_string();
184 let client = self.client.clone();
185
186 let body_val = body_val.clone();
187
188 let resp_val = self.rate_limiter.execute(None,true,
189 move || {
190 let client = client.clone();
191 let id = id.clone();
192 let license_number = license_number.clone();
193 let body_val = body_val.clone();
194
195 async move {
196 client.strains().get_strains_by_id(&id, license_number, body_val.as_ref()
197 ).await.map_err(|e| e as Box<dyn Error + Send + Sync>)
198 }
199 }
200 ).await?;
201
202 if let Some(v) = resp_val {
203 let typed: Strain = serde_json::from_value(v)?;
204 Ok(Some(typed))
205 } else {
206 Ok(None)
207 }
208 }
209
210 pub async fn update_strains(&self, license_number: Option<String>, body: Option<Vec<UpdateStrainsRequestItem>>) -> std::result::Result<Option<WriteResponse>, Box<dyn Error + Send + Sync>> {
218 let body_val = if let Some(b) = body { Some(serde_json::to_value(b)?) } else { None };
219 let client = self.client.clone();
220
221 let body_val = body_val.clone();
222
223 let resp_val = self.rate_limiter.execute(None,false,
224 move || {
225 let client = client.clone();
226 let license_number = license_number.clone();
227 let body_val = body_val.clone();
228
229 async move {
230 client.strains().update_strains(license_number, body_val.as_ref()
231 ).await.map_err(|e| e as Box<dyn Error + Send + Sync>)
232 }
233 }
234 ).await?;
235
236 if let Some(v) = resp_val {
237 let typed: WriteResponse = serde_json::from_value(v)?;
238 Ok(Some(typed))
239 } else {
240 Ok(None)
241 }
242 }
243}
244