dinio_sdk/api/sinkhole_links.rs
1//! `/api/v1/sinkhole-links` (`../core/src/api/sinkhole_links.ts`). A link is keyed by its
2//! client identity and list; it cannot be changed, only deleted.
3
4use reqwest::Method;
5use serde::Serialize;
6use serde_json::json;
7use uuid::Uuid;
8
9use crate::client::Client;
10use crate::error::Result;
11use crate::models::SinkholeLink;
12
13/// Optional filters for [`SinkholeLinks::list`].
14#[derive(Debug, Clone, Default, Serialize)]
15pub struct SinkholeLinkFilter {
16 /// Only links of this client identity.
17 #[serde(rename = "client_identify_id", skip_serializing_if = "Option::is_none")]
18 pub client_identity_id: Option<Uuid>,
19 /// Only links to this sinkhole list.
20 #[serde(rename = "sinkholelist_id", skip_serializing_if = "Option::is_none")]
21 pub list_id: Option<Uuid>,
22}
23
24/// Sinkhole link routes, from [`Client::sinkhole_links`]: which lists apply to which
25/// client identities.
26///
27/// Links belong to the client identity's owner: you see and manage the links of your own
28/// identities (all of them as an Admin), not other users' links to your shared list.
29pub struct SinkholeLinks<'a> {
30 client: &'a Client,
31}
32
33impl<'a> SinkholeLinks<'a> {
34 pub(crate) fn new(client: &'a Client) -> Self {
35 Self { client }
36 }
37
38 /// Links of the caller's client identities, all at once (Core does not paginate them).
39 ///
40 /// `GET /api/v1/sinkhole-links`
41 pub async fn list(&self, filter: &SinkholeLinkFilter) -> Result<Vec<SinkholeLink>> {
42 let request = self
43 .client
44 .request(Method::GET, &["sinkhole-links"])?
45 .query(filter);
46 Ok(self.client.send(request).await?.0)
47 }
48
49 /// Applies a list to a client identity; Relay starts filtering that client's queries
50 /// by it. You must own the identity, and the list must be yours or shared.
51 ///
52 /// `POST /api/v1/sinkhole-links`
53 ///
54 /// # Errors
55 ///
56 /// * [`ErrorCode::NotFound`](crate::ErrorCode::NotFound) if the identity or the list
57 /// does not exist.
58 /// * [`ErrorCode::Forbidden`](crate::ErrorCode::Forbidden) if the identity is not yours,
59 /// or the list is neither yours nor shared.
60 /// * [`ErrorCode::Suspended`](crate::ErrorCode::Suspended) if the identity or its
61 /// owner is suspended.
62 /// * [`ErrorCode::Conflict`](crate::ErrorCode::Conflict) if the link exists.
63 pub async fn create(&self, client_identity_id: Uuid, list_id: Uuid) -> Result<SinkholeLink> {
64 let request = self
65 .client
66 .request(Method::POST, &["sinkhole-links"])?
67 .json(&json!({
68 "client_identify_id": client_identity_id,
69 "sinkholelist_id": list_id,
70 }));
71 Ok(self.client.send(request).await?.0)
72 }
73
74 /// Stops applying a list to a client identity. The identity's owner or an Admin only,
75 /// not the list's owner.
76 ///
77 /// `DELETE /api/v1/sinkhole-links/:client_identify_id/:sinkholelist_id`
78 ///
79 /// # Errors
80 ///
81 /// * [`ErrorCode::NotFound`](crate::ErrorCode::NotFound) if there is no such link.
82 /// * [`ErrorCode::Forbidden`](crate::ErrorCode::Forbidden) if the identity is not yours.
83 /// * [`ErrorCode::Suspended`](crate::ErrorCode::Suspended) if the identity or its
84 /// owner is suspended.
85 pub async fn delete(&self, client_identity_id: Uuid, list_id: Uuid) -> Result<()> {
86 let request = self.client.request(
87 Method::DELETE,
88 &[
89 "sinkhole-links",
90 &client_identity_id.to_string(),
91 &list_id.to_string(),
92 ],
93 )?;
94 self.client.send_empty(request).await
95 }
96}