hey_sdk/services/
clearances.rs1use std::str::FromStr;
8
9use crate::error::{Error, ErrorCode};
10use crate::generated::types::{
11 BulkUpdateClearancesRequestContent, Clearance, ClearanceListResponse, ClearanceSummary,
12 UpdateClearanceRequestContent, UpdateMyClearanceRequestContent,
13};
14use crate::pagination::Page;
15
16pub use crate::generated::services::clearances::*;
17
18#[derive(Debug, Clone, Copy, PartialEq, Eq)]
20pub enum ClearanceStatus {
21 Approved,
23 Denied,
25}
26
27#[derive(Debug, Clone, Default, PartialEq, Eq)]
30pub struct ScreenOptions {
31 pub designation_box_id: Option<i64>,
33 pub spam: bool,
35 pub mark_topics_as_seen: bool,
37}
38
39impl ClearanceStatus {
40 pub fn as_str(&self) -> &'static str {
42 match self {
43 ClearanceStatus::Approved => "approved",
44 ClearanceStatus::Denied => "denied",
45 }
46 }
47}
48
49impl Clearances<'_> {
50 pub async fn pending_count(&self) -> Result<i32, Error> {
55 Ok(self
56 .summary()
57 .await?
58 .pending_clearances_count
59 .unwrap_or_default())
60 }
61
62 pub async fn summary(&self) -> Result<ClearanceSummary, Error> {
66 self.get(&GetClearancesParams::default())
67 .await
68 .map(Page::into_inner)
69 }
70
71 pub async fn pending(&self, page: Option<&str>) -> Result<ClearanceSummary, Error> {
76 self.pending_page(page).await.map(Page::into_inner)
77 }
78
79 pub async fn pending_page(&self, page: Option<&str>) -> Result<Page<ClearanceSummary>, Error> {
82 let params = GetClearancesParams {
83 include_clearances: Some(true),
84 page: page.map(str::to_string),
85 };
86 self.get(¶ms).await
87 }
88
89 pub async fn screen(
91 &self,
92 clearance_id: i64,
93 status: ClearanceStatus,
94 options: &ScreenOptions,
95 ) -> Result<Clearance, Error> {
96 let body = UpdateClearanceRequestContent {
97 status: status.as_str().to_string(),
98 designation_box_id: options.designation_box_id,
99 spam: flag(options.spam),
100 mark_topics_as_seen: flag(options.mark_topics_as_seen),
101 };
102 self.update(clearance_id, &body).await
103 }
104
105 pub async fn screen_many(
110 &self,
111 clearance_ids: &[i64],
112 status: ClearanceStatus,
113 spam: bool,
114 ) -> Result<Vec<Clearance>, Error> {
115 if clearance_ids.is_empty() {
116 return Err(Error::usage("at least one clearance is required"));
117 }
118
119 let body = BulkUpdateClearancesRequestContent {
120 ids: join_ids(clearance_ids),
121 status: status.as_str().to_string(),
122 spam: flag(spam),
123 };
124 Ok(self
125 .bulk_update(&body)
126 .await?
127 .clearances
128 .unwrap_or_default())
129 }
130
131 pub async fn screened(&self, page: Option<&str>) -> Result<Vec<Clearance>, Error> {
133 Ok(self
134 .screened_page(page)
135 .await?
136 .into_inner()
137 .clearances
138 .unwrap_or_default())
139 }
140
141 pub async fn screened_page(
144 &self,
145 page: Option<&str>,
146 ) -> Result<Page<ClearanceListResponse>, Error> {
147 let params = GetMyClearancesParams {
148 page: page.map(str::to_string),
149 };
150 self.get_my(¶ms).await
151 }
152
153 pub async fn rescreen(
158 &self,
159 clearance_id: i64,
160 status: ClearanceStatus,
161 ) -> Result<Clearance, Error> {
162 let body = UpdateMyClearanceRequestContent {
163 status: status.as_str().to_string(),
164 };
165 self.update_my(clearance_id, &body).await
166 }
167}
168
169fn flag(value: bool) -> Option<bool> {
170 if value { Some(true) } else { None }
171}
172
173fn join_ids(ids: &[i64]) -> String {
174 ids.iter()
175 .map(i64::to_string)
176 .collect::<Vec<String>>()
177 .join(",")
178}
179
180impl FromStr for ClearanceStatus {
181 type Err = Error;
182
183 fn from_str(source: &str) -> Result<ClearanceStatus, Error> {
184 match source {
185 "approved" => Ok(ClearanceStatus::Approved),
186 "denied" => Ok(ClearanceStatus::Denied),
187 _ => Err(Error::new(
188 ErrorCode::Validation,
189 format!("clearance status must be \"approved\" or \"denied\", got {source:?}"),
190 )),
191 }
192 }
193}