Skip to main content

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}