contentstack_api_client_rs/client/delivery/entries.rs
1use reqwest_middleware::ClientWithMiddleware;
2use serde::Deserialize;
3
4use crate::client::entries::{EntriesResponse, EntryResponse};
5use crate::client::params::{
6 GetManyParams, GetOneParams, SerializedGetManyParams, SerializedGetOneParams,
7};
8use crate::error::Result;
9
10pub use crate::client::entries::Entry;
11
12/// Sub-client for the Entries endpoint.
13///
14/// Obtained via [`crate::Delivery::entries`] - never constructed directly.
15pub struct Entries<'a> {
16 pub(super) client: &'a ClientWithMiddleware,
17 pub(super) base_url: &'a str,
18}
19
20impl<'a> Entries<'a> {
21 /// Builds the entries URL for a given content type, with an optional entry UID.
22 fn build_url(&self, content_type: &str, uid: Option<&str>) -> String {
23 let base_url = self.base_url.trim_end_matches('/');
24 match uid {
25 Some(u) => format!("{}/content_types/{}/entries/{}", base_url, content_type, u),
26 None => format!("{}/content_types/{}/entries", base_url, content_type),
27 }
28 }
29
30 /// Fetches multiple entries for a given content type.
31 ///
32 /// # Arguments
33 ///
34 /// * `content_type` - The content type UID (e.g. `"blog_post"`)
35 /// * `params` - Optional query parameters (filters, pagination, locale)
36 ///
37 /// # Example
38 ///
39 /// ```no_run
40 /// use serde::Deserialize;
41 /// use contentstack_api_client_rs::{Delivery, GetManyParams};
42 ///
43 /// #[derive(Deserialize)]
44 /// struct BlogPost { body: String }
45 ///
46 /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
47 /// let client = Delivery::new("api_key", "token", "production", None);
48 /// let response = client.entries()
49 /// .get_many::<BlogPost>("blog_post", None)
50 /// .await?;
51 ///
52 /// println!("Total: {}", response.entries.len());
53 /// # Ok(())
54 /// # }
55 /// ```
56 pub async fn get_many<T>(
57 &self,
58 content_type: &str,
59 params: Option<GetManyParams>,
60 ) -> Result<EntriesResponse<T>>
61 where
62 T: for<'de> Deserialize<'de>,
63 {
64 let request = self.client.get(self.build_url(content_type, None));
65
66 let request = if let Some(p) = params {
67 let serialized: SerializedGetManyParams = p.into();
68 request.query(&serialized)
69 } else {
70 request
71 };
72
73 Ok(request.send().await?.json::<EntriesResponse<T>>().await?)
74 }
75
76 /// Fetches a single entry by UID for a given content type.
77 ///
78 /// # Arguments
79 ///
80 /// * `content_type` - The content type UID (e.g. `"blog_post"`)
81 /// * `uid` - The entry UID to fetch
82 /// * `params` - Optional query parameters (locale, query filter)
83 ///
84 /// # Example
85 ///
86 /// ```no_run
87 /// use serde::Deserialize;
88 /// use contentstack_api_client_rs::{Delivery, GetOneParams};
89 ///
90 /// #[derive(Deserialize)]
91 /// struct BlogPost { body: String }
92 ///
93 /// # async fn example() -> Result<(), Box<dyn std::error::Error>> {
94 /// let client = Delivery::new("api_key", "token", "production", None);
95 /// let response = client.entries()
96 /// .get_one::<BlogPost>("blog_post", "entry_uid_123", None)
97 /// .await?;
98 ///
99 /// println!("Title: {}", response.entry.title);
100 /// # Ok(())
101 /// # }
102 /// ```
103 pub async fn get_one<T>(
104 &self,
105 content_type: &str,
106 uid: &str,
107 params: Option<GetOneParams>,
108 ) -> Result<EntryResponse<T>>
109 where
110 T: for<'de> Deserialize<'de>,
111 {
112 let request = self.client.get(self.build_url(content_type, Some(uid)));
113
114 let request = if let Some(p) = params {
115 let serialized: SerializedGetOneParams = p.into();
116 request.query(&serialized)
117 } else {
118 request
119 };
120
121 Ok(request.send().await?.json::<EntryResponse<T>>().await?)
122 }
123}