Skip to main content

akribes_sdk/sub/
scripts.rs

1use std::sync::Arc;
2
3use crate::client::{AkribesClient, Inner};
4use crate::error::Result;
5use crate::models::*;
6
7/// Sub-client for script management. Obtained via `AkribesClient::project(id).scripts()`.
8#[derive(Clone, Debug)]
9pub struct ScriptsClient {
10    pub(crate) inner: Arc<Inner>,
11    pub(crate) project_id: i64,
12}
13
14impl ScriptsClient {
15    pub(crate) fn new(inner: Arc<Inner>, project_id: i64) -> Self {
16        Self { inner, project_id }
17    }
18
19    fn c(&self) -> AkribesClient {
20        AkribesClient {
21            inner: Arc::clone(&self.inner),
22        }
23    }
24
25    fn project_url(&self) -> String {
26        format!("{}/projects/{}", self.inner.base_url, self.project_id)
27    }
28
29    fn script_url(&self, name: &str) -> String {
30        format!(
31            "{}/scripts/{}",
32            self.project_url(),
33            urlencoding::encode(name)
34        )
35    }
36
37    pub async fn list(&self) -> Result<Vec<Script>> {
38        let url = format!("{}/scripts", self.project_url());
39        self.c().get_list(&url).await
40    }
41
42    pub async fn get(&self, name: &str) -> Result<Option<Script>> {
43        self.c().get_opt(&self.script_url(name)).await
44    }
45
46    pub async fn create(&self, name: &str, source: &str) -> Result<Script> {
47        let encoded = urlencoding::encode(name);
48        let url = format!("{}/scripts?name={}", self.project_url(), encoded);
49        self.c().post(&url, &CreateScriptBody { source }).await
50    }
51
52    pub async fn rename(&self, old_name: &str, new_name: &str) -> Result<()> {
53        self.c()
54            .patch_empty(
55                &self.script_url(old_name),
56                &RenameScriptRequest { new_name },
57            )
58            .await
59    }
60
61    /// Look up a script by numeric id (if `id_or_name` parses as `i64`) or by
62    /// exact name. Returns `None` when nothing matches. Ids are resolved by
63    /// listing and filtering — there is no GET-by-id server route.
64    pub async fn resolve(&self, id_or_name: &str) -> Result<Option<Script>> {
65        if let Ok(id) = id_or_name.parse::<i64>() {
66            let list = self.list().await?;
67            return Ok(list.into_iter().find(|s| s.id == id));
68        }
69        self.get(id_or_name).await
70    }
71
72    pub async fn delete(&self, name: &str) -> Result<()> {
73        self.c().delete(&self.script_url(name)).await?;
74        Ok(())
75    }
76
77    /// Duplicate a script within this project. The server picks a copy name
78    /// (e.g. `foo copy`) and returns the new script.
79    pub async fn duplicate(&self, name: &str) -> Result<Script> {
80        let url = format!("{}/duplicate", self.script_url(name));
81        self.c().post(&url, &serde_json::json!({})).await
82    }
83
84    /// Move a script to another project. Returns the moved script (now scoped
85    /// to the target project).
86    pub async fn move_to(&self, name: &str, target_project_id: i64) -> Result<Script> {
87        let url = format!("{}/move", self.script_url(name));
88        self.c()
89            .post(&url, &MoveScriptRequest { target_project_id })
90            .await
91    }
92
93    /// Set the sort order of scripts in this project. `order` is the list of
94    /// script IDs in the desired order.
95    pub async fn reorder(&self, order: Vec<i64>) -> Result<()> {
96        let url = format!("{}/scripts/reorder", self.project_url());
97        self.c().put_empty(&url, &ReorderRequest { order }).await
98    }
99}