sendry/resources/
suppression.rs1use reqwest::Method;
4use serde::{Deserialize, Serialize};
5
6use crate::{client::Sendry, error::Error, DeleteResponse, Page, PaginationParams};
7
8#[derive(Debug, Clone)]
10pub struct Suppression {
11 client: Sendry,
12}
13
14impl Suppression {
15 pub(crate) fn new(client: Sendry) -> Self {
16 Self { client }
17 }
18
19 pub async fn list(&self, params: PaginationParams) -> Result<Page<SuppressionEntry>, Error> {
21 let q = params.to_query();
22 self.client
23 .request(
24 self.client
25 .build::<()>(Method::GET, "/v1/suppression", &q, None),
26 )
27 .await
28 }
29
30 pub async fn add(&self, params: AddSuppression) -> Result<SuppressionEntry, Error> {
32 self.client
33 .request(
34 self.client
35 .build(Method::POST, "/v1/suppression", &[], Some(¶ms)),
36 )
37 .await
38 }
39
40 pub async fn remove(&self, email: &str) -> Result<DeleteResponse, Error> {
42 let encoded = urlencode(email);
43 self.client
44 .request(self.client.build::<()>(
45 Method::DELETE,
46 &format!("/v1/suppression/{encoded}"),
47 &[],
48 None,
49 ))
50 .await
51 }
52}
53
54#[derive(Debug, Clone, Serialize)]
56pub struct AddSuppression {
57 pub email: String,
59 #[serde(skip_serializing_if = "Option::is_none")]
61 pub reason: Option<String>,
62}
63
64#[derive(Debug, Clone, Deserialize)]
66pub struct SuppressionEntry {
67 pub email: String,
69 pub reason: String,
71 pub created_at: String,
73}
74
75fn urlencode(s: &str) -> String {
76 let mut out = String::with_capacity(s.len());
77 for b in s.bytes() {
78 match b {
79 b'A'..=b'Z' | b'a'..=b'z' | b'0'..=b'9' | b'-' | b'_' | b'.' | b'~' => {
80 out.push(b as char);
81 }
82 _ => out.push_str(&format!("%{b:02X}")),
83 }
84 }
85 out
86}