Skip to main content

im_core/content/
service.rs

1use crate::internal::auth::session::{AsyncSessionProvider, SessionProvider};
2use crate::internal::transport::{AsyncAuthenticatedRpcTransport, AuthenticatedRpcTransport};
3
4pub struct ContentService<'a> {
5    client: &'a crate::core::ImClient,
6}
7
8impl<'a> ContentService<'a> {
9    pub(crate) fn new(client: &'a crate::core::ImClient) -> Self {
10        Self { client }
11    }
12
13    pub fn create_page(&self, draft: super::PageDraft) -> crate::ImResult<super::PageDocument> {
14        ContentRuntime::new(
15            crate::internal::auth::session::FileSessionProvider::new(self.client),
16            crate::internal::transport::CoreHttpTransport::new(self.client),
17        )
18        .create_page(draft)
19    }
20
21    pub async fn create_page_async(
22        &self,
23        draft: super::PageDraft,
24    ) -> crate::ImResult<super::PageDocument> {
25        ContentRuntime::new(
26            crate::internal::auth::session::FileSessionProvider::new(self.client),
27            crate::internal::transport::CoreHttpTransport::new(self.client),
28        )
29        .create_page_async(draft)
30        .await
31    }
32
33    pub fn list_pages(
34        &self,
35        query: super::ContentPageQuery,
36    ) -> crate::ImResult<crate::ids::Page<super::PageDocument>> {
37        ContentRuntime::new(
38            crate::internal::auth::session::FileSessionProvider::new(self.client),
39            crate::internal::transport::CoreHttpTransport::new(self.client),
40        )
41        .list_pages(query)
42    }
43
44    pub async fn list_pages_async(
45        &self,
46        query: super::ContentPageQuery,
47    ) -> crate::ImResult<crate::ids::Page<super::PageDocument>> {
48        ContentRuntime::new(
49            crate::internal::auth::session::FileSessionProvider::new(self.client),
50            crate::internal::transport::CoreHttpTransport::new(self.client),
51        )
52        .list_pages_async(query)
53        .await
54    }
55
56    pub fn get_page(&self, page: super::PageRef) -> crate::ImResult<super::PageDocument> {
57        ContentRuntime::new(
58            crate::internal::auth::session::FileSessionProvider::new(self.client),
59            crate::internal::transport::CoreHttpTransport::new(self.client),
60        )
61        .get_page(page)
62    }
63
64    pub async fn get_page_async(
65        &self,
66        page: super::PageRef,
67    ) -> crate::ImResult<super::PageDocument> {
68        ContentRuntime::new(
69            crate::internal::auth::session::FileSessionProvider::new(self.client),
70            crate::internal::transport::CoreHttpTransport::new(self.client),
71        )
72        .get_page_async(page)
73        .await
74    }
75
76    pub fn update_page(
77        &self,
78        page: super::PageRef,
79        patch: super::PageUpdate,
80    ) -> crate::ImResult<super::PageDocument> {
81        ContentRuntime::new(
82            crate::internal::auth::session::FileSessionProvider::new(self.client),
83            crate::internal::transport::CoreHttpTransport::new(self.client),
84        )
85        .update_page(page, patch)
86    }
87
88    pub async fn update_page_async(
89        &self,
90        page: super::PageRef,
91        patch: super::PageUpdate,
92    ) -> crate::ImResult<super::PageDocument> {
93        ContentRuntime::new(
94            crate::internal::auth::session::FileSessionProvider::new(self.client),
95            crate::internal::transport::CoreHttpTransport::new(self.client),
96        )
97        .update_page_async(page, patch)
98        .await
99    }
100
101    pub fn rename_page(
102        &self,
103        page: super::PageRef,
104        target: super::PageSlug,
105    ) -> crate::ImResult<super::PageDocument> {
106        ContentRuntime::new(
107            crate::internal::auth::session::FileSessionProvider::new(self.client),
108            crate::internal::transport::CoreHttpTransport::new(self.client),
109        )
110        .rename_page(page, target)
111    }
112
113    pub async fn rename_page_async(
114        &self,
115        page: super::PageRef,
116        target: super::PageSlug,
117    ) -> crate::ImResult<super::PageDocument> {
118        ContentRuntime::new(
119            crate::internal::auth::session::FileSessionProvider::new(self.client),
120            crate::internal::transport::CoreHttpTransport::new(self.client),
121        )
122        .rename_page_async(page, target)
123        .await
124    }
125
126    pub fn delete_page(&self, page: super::PageRef) -> crate::ImResult<super::PageDeleteResult> {
127        ContentRuntime::new(
128            crate::internal::auth::session::FileSessionProvider::new(self.client),
129            crate::internal::transport::CoreHttpTransport::new(self.client),
130        )
131        .delete_page(page)
132    }
133
134    pub async fn delete_page_async(
135        &self,
136        page: super::PageRef,
137    ) -> crate::ImResult<super::PageDeleteResult> {
138        ContentRuntime::new(
139            crate::internal::auth::session::FileSessionProvider::new(self.client),
140            crate::internal::transport::CoreHttpTransport::new(self.client),
141        )
142        .delete_page_async(page)
143        .await
144    }
145}
146
147pub(crate) struct ContentRuntime<P, T> {
148    session_provider: P,
149    transport: T,
150}
151
152impl<P, T> ContentRuntime<P, T> {
153    pub(crate) fn new(session_provider: P, transport: T) -> Self {
154        Self {
155            session_provider,
156            transport,
157        }
158    }
159}
160
161impl<P, T> ContentRuntime<P, T>
162where
163    P: SessionProvider,
164    T: AuthenticatedRpcTransport,
165{
166    pub(crate) fn create_page(
167        mut self,
168        draft: super::PageDraft,
169    ) -> crate::ImResult<super::PageDocument> {
170        self.ensure_session()?;
171        let fallback_slug = draft.slug.clone();
172        let call = super::wire::build_create_page_rpc_call(draft)?;
173        let raw = self.call(call)?;
174        super::wire::normalize_page(raw, Some(&fallback_slug))
175    }
176
177    pub(crate) fn list_pages(
178        mut self,
179        query: super::ContentPageQuery,
180    ) -> crate::ImResult<crate::ids::Page<super::PageDocument>> {
181        self.ensure_session()?;
182        let call = super::wire::build_list_pages_rpc_call(query);
183        let raw = self.call(call)?;
184        super::wire::normalize_page_list(raw)
185    }
186
187    pub(crate) fn get_page(mut self, page: super::PageRef) -> crate::ImResult<super::PageDocument> {
188        self.ensure_session()?;
189        let fallback_slug = page.slug.clone();
190        let call = super::wire::build_get_page_rpc_call(page);
191        let raw = self.call(call)?;
192        super::wire::normalize_page(raw, Some(&fallback_slug))
193    }
194
195    pub(crate) fn update_page(
196        mut self,
197        page: super::PageRef,
198        patch: super::PageUpdate,
199    ) -> crate::ImResult<super::PageDocument> {
200        self.ensure_session()?;
201        let fallback_slug = page.slug.clone();
202        let call = super::wire::build_update_page_rpc_call(page, patch)?;
203        let raw = self.call(call)?;
204        super::wire::normalize_page(raw, Some(&fallback_slug))
205    }
206
207    pub(crate) fn rename_page(
208        mut self,
209        page: super::PageRef,
210        target: super::PageSlug,
211    ) -> crate::ImResult<super::PageDocument> {
212        self.ensure_session()?;
213        let fallback_slug = target.clone();
214        let call = super::wire::build_rename_page_rpc_call(page, target);
215        let raw = self.call(call)?;
216        super::wire::normalize_page(raw, Some(&fallback_slug))
217    }
218
219    pub(crate) fn delete_page(
220        mut self,
221        page: super::PageRef,
222    ) -> crate::ImResult<super::PageDeleteResult> {
223        self.ensure_session()?;
224        let call = super::wire::build_delete_page_rpc_call(page);
225        let raw = self.call(call)?;
226        Ok(super::wire::normalize_delete(raw))
227    }
228
229    fn ensure_session(&self) -> crate::ImResult<crate::auth::SessionBundle> {
230        self.session_provider
231            .ensure_session(crate::auth::AuthScope::Messaging)
232    }
233
234    fn call(&mut self, call: super::wire::RpcCall) -> crate::ImResult<serde_json::Value> {
235        self.transport
236            .authenticated_rpc(call.endpoint, call.method, call.params)
237    }
238}
239
240impl<P, T> ContentRuntime<P, T>
241where
242    P: AsyncSessionProvider,
243    T: AsyncAuthenticatedRpcTransport,
244{
245    pub(crate) async fn create_page_async(
246        mut self,
247        draft: super::PageDraft,
248    ) -> crate::ImResult<super::PageDocument> {
249        self.ensure_session_async().await?;
250        let fallback_slug = draft.slug.clone();
251        let call = super::wire::build_create_page_rpc_call(draft)?;
252        let raw = self.call_async(call).await?;
253        super::wire::normalize_page(raw, Some(&fallback_slug))
254    }
255
256    pub(crate) async fn list_pages_async(
257        mut self,
258        query: super::ContentPageQuery,
259    ) -> crate::ImResult<crate::ids::Page<super::PageDocument>> {
260        self.ensure_session_async().await?;
261        let call = super::wire::build_list_pages_rpc_call(query);
262        let raw = self.call_async(call).await?;
263        super::wire::normalize_page_list(raw)
264    }
265
266    pub(crate) async fn get_page_async(
267        mut self,
268        page: super::PageRef,
269    ) -> crate::ImResult<super::PageDocument> {
270        self.ensure_session_async().await?;
271        let fallback_slug = page.slug.clone();
272        let call = super::wire::build_get_page_rpc_call(page);
273        let raw = self.call_async(call).await?;
274        super::wire::normalize_page(raw, Some(&fallback_slug))
275    }
276
277    pub(crate) async fn update_page_async(
278        mut self,
279        page: super::PageRef,
280        patch: super::PageUpdate,
281    ) -> crate::ImResult<super::PageDocument> {
282        self.ensure_session_async().await?;
283        let fallback_slug = page.slug.clone();
284        let call = super::wire::build_update_page_rpc_call(page, patch)?;
285        let raw = self.call_async(call).await?;
286        super::wire::normalize_page(raw, Some(&fallback_slug))
287    }
288
289    pub(crate) async fn rename_page_async(
290        mut self,
291        page: super::PageRef,
292        target: super::PageSlug,
293    ) -> crate::ImResult<super::PageDocument> {
294        self.ensure_session_async().await?;
295        let fallback_slug = target.clone();
296        let call = super::wire::build_rename_page_rpc_call(page, target);
297        let raw = self.call_async(call).await?;
298        super::wire::normalize_page(raw, Some(&fallback_slug))
299    }
300
301    pub(crate) async fn delete_page_async(
302        mut self,
303        page: super::PageRef,
304    ) -> crate::ImResult<super::PageDeleteResult> {
305        self.ensure_session_async().await?;
306        let call = super::wire::build_delete_page_rpc_call(page);
307        let raw = self.call_async(call).await?;
308        Ok(super::wire::normalize_delete(raw))
309    }
310
311    async fn ensure_session_async(&self) -> crate::ImResult<crate::auth::SessionBundle> {
312        self.session_provider
313            .ensure_session(crate::auth::AuthScope::Messaging)
314            .await
315    }
316
317    async fn call_async(
318        &mut self,
319        call: super::wire::RpcCall,
320    ) -> crate::ImResult<serde_json::Value> {
321        self.transport
322            .authenticated_rpc(call.endpoint, call.method, call.params)
323            .await
324    }
325}