paddle_rust_sdk/
addresses.rs

1//! Builders for making requests to the Paddle API for customer addresses.
2//!
3//! See the [Paddle API](https://developer.paddle.com/api-reference/addresses/overview) documentation for more information.
4
5use std::collections::HashMap;
6
7use reqwest::Method;
8use serde::Serialize;
9use serde_with::skip_serializing_none;
10
11use crate::entities::Address;
12use crate::enums::{CountryCodeSupported, Status};
13use crate::ids::{AddressID, CustomerID};
14use crate::paginated::Paginated;
15use crate::{Paddle, Result};
16
17/// Request builder for fetching addresses from Paddle API.
18#[skip_serializing_none]
19#[derive(Serialize)]
20pub struct AddressesList<'a> {
21    #[serde(skip)]
22    client: &'a Paddle,
23    #[serde(skip)]
24    customer_id: CustomerID,
25    after: Option<AddressID>,
26    #[serde(serialize_with = "crate::comma_separated")]
27    id: Option<Vec<AddressID>>,
28    order_by: Option<String>,
29    per_page: Option<usize>,
30    search: Option<String>,
31    status: Option<Status>,
32}
33
34impl<'a> AddressesList<'a> {
35    pub fn new(client: &'a Paddle, customer_id: impl Into<CustomerID>) -> Self {
36        Self {
37            client,
38            customer_id: customer_id.into(),
39            after: None,
40            id: None,
41            order_by: None,
42            per_page: None,
43            search: None,
44            status: None,
45        }
46    }
47
48    /// Return entities after the specified Paddle ID when working with paginated endpoints. Used in the `meta.pagination.next` URL in responses for list operations.
49    pub fn after(&mut self, address_id: impl Into<AddressID>) -> &mut Self {
50        self.after = Some(address_id.into());
51        self
52    }
53
54    /// Return only the IDs specified.
55    pub fn ids(
56        &mut self,
57        address_ids: impl IntoIterator<Item = impl Into<AddressID>>,
58    ) -> &mut Self {
59        self.id = Some(address_ids.into_iter().map(Into::into).collect());
60        self
61    }
62
63    /// Order returned entities by the specified field. Valid fields for ordering: id
64    pub fn order_by_asc(&mut self, field: &str) -> &mut Self {
65        self.order_by = Some(format!("{}[ASC]", field));
66        self
67    }
68
69    /// Order returned entities by the specified field. Valid fields for ordering: id
70    pub fn order_by_desc(&mut self, field: &str) -> &mut Self {
71        self.order_by = Some(format!("{}[DESC]", field));
72        self
73    }
74
75    /// Set how many entities are returned per page. Paddle returns the maximum number of results if a number greater than the maximum is requested.
76    /// Check `meta.pagination.per_page` in the response to see how many were returned.
77    ///
78    /// Default: `50`; Maximum: `200`.
79    pub fn per_page(&mut self, entities_per_page: usize) -> &mut Self {
80        self.per_page = Some(entities_per_page);
81        self
82    }
83
84    /// Return entities that match a search query. Searches `status`, `created_at`, and `updated_at`.
85    pub fn search(&mut self, term: impl Into<String>) -> &mut Self {
86        self.search = Some(term.into());
87        self
88    }
89
90    /// Return only prices with the specified status.
91    pub fn status(&mut self, status: Status) -> &mut Self {
92        self.status = Some(status);
93        self
94    }
95
96    /// Send the request to Paddle and return the response.
97    pub fn send(&self) -> Paginated<Vec<Address>> {
98        let url = format!("/customers/{}/addresses", self.customer_id.as_ref());
99
100        Paginated::new(self.client, &url, self)
101    }
102}
103
104/// Request builder for creating customer addresses in Paddle API.
105#[skip_serializing_none]
106#[derive(Serialize)]
107pub struct AddressCreate<'a> {
108    #[serde(skip)]
109    client: &'a Paddle,
110    #[serde(skip)]
111    customer_id: CustomerID,
112    country_code: CountryCodeSupported,
113    description: Option<String>,
114    first_line: Option<String>,
115    second_line: Option<String>,
116    city: Option<String>,
117    postal_code: Option<String>,
118    region: Option<String>,
119    custom_data: Option<HashMap<String, String>>,
120}
121
122impl<'a> AddressCreate<'a> {
123    pub fn new(
124        client: &'a Paddle,
125        customer_id: impl Into<CustomerID>,
126        country_code: CountryCodeSupported,
127    ) -> Self {
128        Self {
129            client,
130            customer_id: customer_id.into(),
131            country_code,
132            description: None,
133            first_line: None,
134            second_line: None,
135            city: None,
136            postal_code: None,
137            region: None,
138            custom_data: None,
139        }
140    }
141
142    /// Memorable description for this address.
143    pub fn description(&mut self, description: impl Into<String>) -> &mut Self {
144        self.description = Some(description.into());
145        self
146    }
147
148    /// First line of the address.
149    pub fn first_line(&mut self, first_line: impl Into<String>) -> &mut Self {
150        self.first_line = Some(first_line.into());
151        self
152    }
153
154    /// Second line of the address.
155    pub fn second_line(&mut self, second_line: impl Into<String>) -> &mut Self {
156        self.second_line = Some(second_line.into());
157        self
158    }
159
160    /// City name.
161    pub fn city(&mut self, city: impl Into<String>) -> &mut Self {
162        self.city = Some(city.into());
163        self
164    }
165
166    /// Postal code. Required for US addresses
167    pub fn postal_code(&mut self, postal_code: impl Into<String>) -> &mut Self {
168        self.postal_code = Some(postal_code.into());
169        self
170    }
171
172    /// Region name.
173    pub fn region(&mut self, region: impl Into<String>) -> &mut Self {
174        self.region = Some(region.into());
175        self
176    }
177
178    /// Custom data to be stored with this address.
179    pub fn custom_data(&mut self, custom_data: HashMap<String, String>) -> &mut Self {
180        self.custom_data = Some(custom_data);
181        self
182    }
183
184    /// Send the request to Paddle and return the response.
185    pub async fn send(&self) -> Result<Address> {
186        self.client
187            .send(
188                self,
189                Method::POST,
190                &format!("/customers/{}/addresses", self.customer_id.as_ref()),
191            )
192            .await
193    }
194}
195
196/// Request builder for fetching a single address from Paddle API.
197#[skip_serializing_none]
198#[derive(Serialize)]
199pub struct AddressGet<'a> {
200    #[serde(skip)]
201    client: &'a Paddle,
202    #[serde(skip)]
203    customer_id: CustomerID,
204    #[serde(skip)]
205    address_id: AddressID,
206}
207
208impl<'a> AddressGet<'a> {
209    pub fn new(
210        client: &'a Paddle,
211        customer_id: impl Into<CustomerID>,
212        address_id: impl Into<AddressID>,
213    ) -> Self {
214        Self {
215            client,
216            customer_id: customer_id.into(),
217            address_id: address_id.into(),
218        }
219    }
220
221    /// Send the request to Paddle and return the response.
222    pub async fn send(&self) -> Result<Address> {
223        self.client
224            .send(
225                self,
226                Method::GET,
227                &format!(
228                    "/customers/{}/addresses/{}",
229                    self.customer_id.as_ref(),
230                    self.address_id.as_ref()
231                ),
232            )
233            .await
234    }
235}
236
237/// Request builder for updating an address in Paddle API.
238#[skip_serializing_none]
239#[derive(Serialize)]
240pub struct AddressUpdate<'a> {
241    #[serde(skip)]
242    client: &'a Paddle,
243    #[serde(skip)]
244    customer_id: CustomerID,
245    #[serde(skip)]
246    address_id: AddressID,
247    description: Option<String>,
248    first_line: Option<String>,
249    second_line: Option<String>,
250    city: Option<String>,
251    postal_code: Option<String>,
252    region: Option<String>,
253    country_code: Option<CountryCodeSupported>,
254    custom_data: Option<HashMap<String, String>>,
255    status: Option<Status>,
256}
257
258impl<'a> AddressUpdate<'a> {
259    pub fn new(
260        client: &'a Paddle,
261        customer_id: impl Into<CustomerID>,
262        address_id: impl Into<AddressID>,
263    ) -> Self {
264        Self {
265            client,
266            customer_id: customer_id.into(),
267            address_id: address_id.into(),
268            description: None,
269            first_line: None,
270            second_line: None,
271            city: None,
272            postal_code: None,
273            region: None,
274            country_code: None,
275            custom_data: None,
276            status: None,
277        }
278    }
279
280    /// Memorable description for this address.
281    pub fn description(&mut self, description: impl Into<String>) -> &mut Self {
282        self.description = Some(description.into());
283        self
284    }
285
286    /// First line of the address.
287    pub fn first_line(&mut self, first_line: impl Into<String>) -> &mut Self {
288        self.first_line = Some(first_line.into());
289        self
290    }
291
292    /// Second line of the address.
293    pub fn second_line(&mut self, second_line: impl Into<String>) -> &mut Self {
294        self.second_line = Some(second_line.into());
295        self
296    }
297
298    /// City name.
299    pub fn city(&mut self, city: impl Into<String>) -> &mut Self {
300        self.city = Some(city.into());
301        self
302    }
303
304    /// Postal code. Required for US addresses
305    pub fn postal_code(&mut self, postal_code: impl Into<String>) -> &mut Self {
306        self.postal_code = Some(postal_code.into());
307        self
308    }
309
310    /// Region name.
311    pub fn region(&mut self, region: impl Into<String>) -> &mut Self {
312        self.region = Some(region.into());
313        self
314    }
315
316    /// Country code.
317    pub fn country_code(&mut self, country_code: CountryCodeSupported) -> &mut Self {
318        self.country_code = Some(country_code);
319        self
320    }
321
322    /// Custom data to be stored with this address.
323    pub fn custom_data(&mut self, custom_data: HashMap<String, String>) -> &mut Self {
324        self.custom_data = Some(custom_data);
325        self
326    }
327
328    /// Status of the address.
329    pub fn status(&mut self, status: Status) -> &mut Self {
330        self.status = Some(status);
331        self
332    }
333
334    /// Send the request to Paddle and return the response.
335    pub async fn send(&self) -> Result<Address> {
336        self.client
337            .send(
338                self,
339                Method::PATCH,
340                &format!(
341                    "/customers/{}/addresses/{}",
342                    self.customer_id.as_ref(),
343                    self.address_id.as_ref()
344                ),
345            )
346            .await
347    }
348}