1use std::fmt;
2use std::sync::Arc;
3
4use reqwest::Method;
5
6use crate::{Config, Result, list_opts::ListOptions};
7use crate::{list_opts::ListResponse, types::Segment};
8
9use self::types::CreateSegmentResponse;
10
11#[derive(Clone)]
13pub struct SegmentsSvc(pub(crate) Arc<Config>);
14
15impl SegmentsSvc {
16 #[maybe_async::maybe_async]
22 pub async fn create(&self, name: &str) -> Result<CreateSegmentResponse> {
23 let segment = types::CreateSegmentRequest {
24 name: name.to_owned(),
25 };
26
27 let request = self.0.build(Method::POST, "/segments");
28 let response = self.0.send(request.json(&segment)).await?;
29 let content = response.json::<CreateSegmentResponse>().await?;
30
31 Ok(content)
32 }
33
34 #[maybe_async::maybe_async]
38 pub async fn get(&self, id: &str) -> Result<Segment> {
39 let path = format!("/segments/{id}");
40
41 let request = self.0.build(Method::GET, &path);
42 let response = self.0.send(request).await?;
43 let content = response.json::<Segment>().await?;
44
45 Ok(content)
46 }
47
48 #[maybe_async::maybe_async]
52 #[allow(clippy::needless_pass_by_value)]
53 pub async fn delete(&self, id: &str) -> Result<bool> {
54 let path = format!("/segments/{id}");
55
56 let request = self.0.build(Method::DELETE, &path);
57 let response = self.0.send(request).await?;
58 let content = response.json::<types::RemoveSegmentResponse>().await?;
59
60 Ok(content.deleted)
61 }
62
63 #[maybe_async::maybe_async]
69 #[allow(clippy::needless_pass_by_value)]
70 pub async fn list<T>(&self, list_opts: ListOptions<T>) -> Result<ListResponse<Segment>> {
71 let request = self.0.build(Method::GET, "/segments").query(&list_opts);
72 let response = self.0.send(request).await?;
73 let content = response.json::<ListResponse<Segment>>().await?;
74
75 Ok(content)
76 }
77}
78
79impl fmt::Debug for SegmentsSvc {
80 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
81 fmt::Debug::fmt(&self.0, f)
82 }
83}
84
85#[allow(unreachable_pub)]
86pub mod types {
87 use serde::{Deserialize, Serialize};
88
89 crate::define_id_type!(SegmentId);
90
91 #[must_use]
92 #[derive(Debug, Clone, Serialize)]
93 pub struct CreateSegmentRequest {
94 pub name: String,
96 }
97
98 #[derive(Debug, Clone, Deserialize)]
99 pub struct CreateSegmentResponse {
100 pub id: SegmentId,
102 pub name: String,
104 }
105
106 #[must_use]
108 #[derive(Debug, Clone, Deserialize)]
109 pub struct Segment {
110 pub id: SegmentId,
112 pub name: String,
116 pub created_at: String,
118 }
119
120 #[derive(Debug, Clone, Deserialize)]
121 pub struct RemoveSegmentResponse {
122 #[allow(dead_code)]
124 pub id: SegmentId,
125 pub deleted: bool,
127 }
128}
129
130#[cfg(test)]
131#[allow(clippy::needless_return)]
132mod test {
133 use crate::list_opts::ListOptions;
134 use crate::test::{CLIENT, DebugResult};
135
136 #[tokio_shared_rt::test(shared = true)]
137 #[cfg(not(feature = "blocking"))]
138 async fn all() -> DebugResult<()> {
139 let resend = &*CLIENT;
140 let segment = "test_segments";
141
142 let created = resend.segments.create(segment).await?;
144 let id = created.id;
145 std::thread::sleep(std::time::Duration::from_secs(2));
146
147 let data = resend.segments.get(&id).await?;
149 assert_eq!(data.name.as_str(), segment);
150
151 let segments = resend.segments.list(ListOptions::default()).await?;
153 let segments_before = segments.len();
154 assert!(segments_before > 1);
155
156 let deleted = resend.segments.delete(&id).await?;
158 assert!(deleted);
159
160 Ok(())
161 }
162}