zammad_api/api/
organizations.rs1use async_stream::try_stream;
2use futures_core::stream::BoxStream;
3use reqwest::Method;
4use serde::Serialize;
5use serde_json::{Map, Value};
6
7use crate::client::Client;
8use crate::error::{Error, Result};
9use crate::models::{NewOrganization, Organization};
10
11const PATH: &str = "api/v1/organizations";
12
13#[derive(Debug)]
15pub struct OrganizationsApi<'a> {
16 client: &'a Client,
17}
18
19impl<'a> OrganizationsApi<'a> {
20 pub(crate) fn new(client: &'a Client) -> Self {
21 Self { client }
22 }
23
24 pub async fn get(&self, id: u64) -> Result<Organization> {
26 let req = self.client.request(Method::GET, &format!("{PATH}/{id}"));
27 self.client.send_json(req).await
28 }
29
30 pub fn list(&self) -> ListOrganizations<'a> {
32 ListOrganizations {
33 client: self.client,
34 per_page: 100,
35 }
36 }
37
38 pub fn search(&self, query: impl Into<String>) -> SearchOrganizations<'a> {
40 SearchOrganizations {
41 client: self.client,
42 query: query.into(),
43 per_page: 100,
44 }
45 }
46
47 pub async fn create(&self, org: &NewOrganization) -> Result<Organization> {
49 let req = self.client.request(Method::POST, PATH).json(org);
50 self.client.send_json(req).await
51 }
52
53 pub async fn update<P: Serialize + ?Sized>(&self, id: u64, patch: &P) -> Result<Organization> {
55 let req = self
56 .client
57 .request(Method::PUT, &format!("{PATH}/{id}"))
58 .json(patch);
59 self.client.send_json(req).await
60 }
61
62 pub async fn set_field(
65 &self,
66 id: u64,
67 field: &str,
68 value: impl Into<Value>,
69 ) -> Result<Organization> {
70 let value: Value = value.into();
71 let mut body = Map::new();
72 body.insert(field.to_string(), value.clone());
73 let updated = self.update(id, &Value::Object(body)).await?;
74 let actual = updated.extra.get(field).cloned();
75 if actual.as_ref() != Some(&value) {
76 return Err(Error::WriteVerificationFailed {
77 field: field.into(),
78 actual,
79 });
80 }
81 Ok(updated)
82 }
83
84 pub async fn delete(&self, id: u64) -> Result<()> {
86 let req = self.client.request(Method::DELETE, &format!("{PATH}/{id}"));
87 self.client.send_unit(req).await
88 }
89}
90
91#[derive(Debug)]
93pub struct ListOrganizations<'a> {
94 client: &'a Client,
95 per_page: u32,
96}
97
98impl<'a> ListOrganizations<'a> {
99 pub fn per_page(mut self, n: u32) -> Self {
101 self.per_page = n;
102 self
103 }
104
105 pub async fn page(&self, page: u32) -> Result<Vec<Organization>> {
107 let req = self.client.request(Method::GET, PATH).query(&[
108 ("page", page.to_string()),
109 ("per_page", self.per_page.to_string()),
110 ]);
111 self.client.send_json(req).await
112 }
113
114 pub fn stream(self) -> BoxStream<'a, Result<Organization>> {
116 let client = self.client;
117 let per_page = self.per_page;
118 Box::pin(try_stream! {
119 let mut page = 1u32;
120 loop {
121 let req = client.request(Method::GET, PATH).query(&[
122 ("page", page.to_string()),
123 ("per_page", per_page.to_string()),
124 ]);
125 let chunk: Vec<Organization> = client.send_json(req).await?;
126 let len = chunk.len() as u32;
127 for o in chunk { yield o; }
128 if len < per_page { break; }
129 page += 1;
130 }
131 })
132 }
133}
134
135#[derive(Debug)]
137pub struct SearchOrganizations<'a> {
138 client: &'a Client,
139 query: String,
140 per_page: u32,
141}
142
143impl<'a> SearchOrganizations<'a> {
144 pub fn per_page(mut self, n: u32) -> Self {
146 self.per_page = n;
147 self
148 }
149
150 pub async fn page(&self, page: u32) -> Result<Vec<Organization>> {
152 let req = self
153 .client
154 .request(Method::GET, &format!("{PATH}/search"))
155 .query(&[
156 ("query", self.query.clone()),
157 ("page", page.to_string()),
158 ("per_page", self.per_page.to_string()),
159 ]);
160 self.client.send_json(req).await
161 }
162
163 pub fn stream(self) -> BoxStream<'a, Result<Organization>> {
165 let client = self.client;
166 let per_page = self.per_page;
167 let query = self.query;
168 Box::pin(try_stream! {
169 let mut page = 1u32;
170 loop {
171 let req = client
172 .request(Method::GET, &format!("{PATH}/search"))
173 .query(&[
174 ("query", query.clone()),
175 ("page", page.to_string()),
176 ("per_page", per_page.to_string()),
177 ]);
178 let chunk: Vec<Organization> = client.send_json(req).await?;
179 let len = chunk.len() as u32;
180 for o in chunk { yield o; }
181 if len < per_page { break; }
182 page += 1;
183 }
184 })
185 }
186}