resend_rs/client.rs
1use std::sync::Arc;
2use std::{env, fmt};
3
4#[cfg(not(feature = "blocking"))]
5use reqwest::Client as ReqwestClient;
6#[cfg(feature = "blocking")]
7use reqwest::blocking::Client as ReqwestClient;
8
9use crate::{batch::BatchSvc, config::Config, services::ReceivingSvc, webhooks::WebhookSvc};
10use crate::{
11 services::{
12 ApiKeysSvc, BroadcastsSvc, ContactsSvc, DomainsSvc, EmailsSvc, SegmentsSvc, TemplateSvc,
13 },
14 topics::TopicsSvc,
15};
16
17#[cfg(doc)]
18use crate::ConfigBuilder;
19
20/// The [Resend](https://resend.com) client.
21#[must_use]
22#[derive(Clone)]
23pub struct Resend {
24 /// `Resend` APIs for `/emails` endpoints.
25 pub emails: EmailsSvc,
26 /// `Resend` APIs for the batch `/emails` endpoints.
27 pub batch: BatchSvc,
28 /// `Resend` APIs for `/api-keys` endpoints.
29 pub api_keys: ApiKeysSvc,
30 /// `Resend` APIs for `/audiences` endpoints.
31 pub segments: SegmentsSvc,
32 /// `Resend` APIs for `/audiences/:id/contacts` endpoints.
33 pub contacts: ContactsSvc,
34 /// `Resend` APIs for `/domains` endpoints.
35 pub domains: DomainsSvc,
36 /// `Resend` APIs for `/broadcasts` endpoints.
37 pub broadcasts: BroadcastsSvc,
38 /// `Resend` APIs for `/templates` endpoints.
39 pub templates: TemplateSvc,
40 /// `Resend` APIs for `/topics` endpoints.
41 pub topics: TopicsSvc,
42 /// `Resend` APIs for `/emails/receiving` endpoints.
43 pub receiving: ReceivingSvc,
44 /// `Resend` APIs for `/webhooks` endpoints.
45 pub webhooks: WebhookSvc,
46}
47
48impl Resend {
49 /// Creates a new [`Resend`] client.
50 ///
51 /// ### Panics
52 ///
53 /// - Panics if the environment variable `RESEND_BASE_URL` is set but is not a valid `URL`.
54 ///
55 /// [`Resend`]: https://resend.com
56 pub fn new(api_key: &str) -> Self {
57 Self::with_client(api_key, ReqwestClient::default())
58 }
59
60 /// Creates a new [`Resend`] client with a provided [`reqwest::Client`].
61 ///
62 /// ### Panics
63 ///
64 /// - Panics if the environment variable `RESEND_BASE_URL` is set but is not a valid `URL`.
65 ///
66 /// [`Resend`]: https://resend.com
67 /// [`reqwest::Client`]: ReqwestClient
68 pub fn with_client(api_key: &str, client: ReqwestClient) -> Self {
69 let config = Config::new(api_key.to_owned(), client, None);
70 Self::with_config(config)
71 }
72
73 /// Creates a new [`Resend`] client with a provided [`Config`].
74 ///
75 /// Use [`ConfigBuilder::new`] to construct a [`Config`] instance.
76 ///
77 /// ### Panics
78 ///
79 /// - Panics if the base url has not been set with [`ConfigBuilder::base_url`]
80 /// and the environment variable `RESEND_BASE_URL` _is_ set but is not a valid `URL`.
81 ///
82 /// [`Resend`]: https://resend.com
83 /// [`reqwest::Client`]: ReqwestClient
84 pub fn with_config(config: Config) -> Self {
85 let inner = Arc::new(config);
86 Self {
87 api_keys: ApiKeysSvc(Arc::clone(&inner)),
88 segments: SegmentsSvc(Arc::clone(&inner)),
89 contacts: ContactsSvc(Arc::clone(&inner)),
90 domains: DomainsSvc(Arc::clone(&inner)),
91 emails: EmailsSvc(Arc::clone(&inner)),
92 batch: BatchSvc(Arc::clone(&inner)),
93 broadcasts: BroadcastsSvc(Arc::clone(&inner)),
94 templates: TemplateSvc(Arc::clone(&inner)),
95 topics: TopicsSvc(Arc::clone(&inner)),
96 receiving: ReceivingSvc(Arc::clone(&inner)),
97 webhooks: WebhookSvc(inner),
98 }
99 }
100
101 /// Returns the reference to the used `User-Agent` header value.
102 #[inline]
103 #[must_use]
104 pub fn user_agent(&self) -> &str {
105 self.config().user_agent.as_str()
106 }
107
108 /// Returns the reference to the provided `API key`.
109 #[inline]
110 #[must_use]
111 pub fn api_key(&self) -> &str {
112 self.config().api_key.as_ref()
113 }
114
115 /// Returns the reference to the used `base URL`.
116 ///
117 /// ### Notes
118 ///
119 /// Use the `RESEND_BASE_URL` environment variable to override.
120 #[inline]
121 #[must_use]
122 pub fn base_url(&self) -> &str {
123 self.config().base_url.as_str()
124 }
125
126 /// Returns the underlying [`reqwest::Client`].
127 ///
128 /// [`reqwest::Client`]: ReqwestClient
129 #[inline]
130 #[must_use]
131 pub fn client(&self) -> ReqwestClient {
132 self.config().client.clone()
133 }
134
135 #[allow(clippy::missing_const_for_fn)]
136 /// Returns the reference to the inner [`Config`].
137 #[inline]
138 fn config(&self) -> &Config {
139 &self.emails.0
140 }
141}
142
143impl Default for Resend {
144 /// Creates a new [`Resend`] client from the `RESEND_API_KEY` environment variable .
145 ///
146 /// ### Panics
147 ///
148 /// - Panics if the environment variable `RESEND_API_KEY` is not set.
149 /// - Panics if the environment variable `RESEND_BASE_URL` is set but is not a valid `URL`.
150 fn default() -> Self {
151 let api_key = env::var("RESEND_API_KEY")
152 .expect("env variable `RESEND_API_KEY` should be a valid API key");
153
154 Self::new(api_key.as_str())
155 }
156}
157
158impl fmt::Debug for Resend {
159 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
160 fmt::Debug::fmt(&self.emails, f)
161 }
162}