Skip to main content

ephemeris_forge_forgejo/api/http/
branch_rules.rs

1use ephemeris_forge::{RepoRef, TransportError, encode, path_segment};
2use reqwest::Method;
3
4use crate::api::HttpApi;
5use crate::api::error::ForgeError;
6use crate::api::model::BranchProtection;
7use crate::api::operations::BranchRulesApi;
8use crate::api::request::{CreateBranchProtectionOption, EditBranchProtectionOption};
9
10impl BranchRulesApi for HttpApi {
11    async fn branch_protections(
12        &self,
13        repo: &RepoRef,
14    ) -> Result<Vec<BranchProtection>, ForgeError> {
15        let path = repo.path("branch_protections");
16        Ok(self.http.json(Method::GET, &path, None).await?)
17    }
18
19    async fn branch_protection(
20        &self,
21        repo: &RepoRef,
22        rule: &str,
23    ) -> Result<Option<BranchProtection>, ForgeError> {
24        let segment = path_segment(rule);
25        let path = repo.path(&format!("branch_protections/{segment}"));
26        Ok(self.http.json_optional(Method::GET, &path, None).await?)
27    }
28
29    async fn create_branch_protection(
30        &self,
31        repo: &RepoRef,
32        body: &CreateBranchProtectionOption,
33    ) -> Result<(), ForgeError> {
34        let path = repo.path("branch_protections");
35        let rule_name = body.rule_name.clone();
36        let body = encode(body);
37        match self.send_write(Method::POST, &path, Some(&body)).await {
38            Ok(()) => Ok(()),
39            // Forgejo answers 403 when the rule exists. A token without
40            // admin rights gets the same status, so the rule is read back.
41            Err(ForgeError::Transport(TransportError::Rejected {
42                status: 403,
43                request,
44                body,
45            })) => match self.branch_protection(repo, &rule_name).await? {
46                Some(_) => Err(ForgeError::RuleExists { name: rule_name }),
47                None => Err(ForgeError::Transport(TransportError::Rejected {
48                    status: 403,
49                    request,
50                    body,
51                })),
52            },
53            Err(error) => Err(error),
54        }
55    }
56
57    async fn patch_branch_protection(
58        &self,
59        repo: &RepoRef,
60        rule: &str,
61        body: &EditBranchProtectionOption,
62    ) -> Result<(), ForgeError> {
63        let rule = path_segment(rule);
64        let path = repo.path(&format!("branch_protections/{rule}"));
65        let body = encode(body);
66        self.send_write(Method::PATCH, &path, Some(&body)).await
67    }
68
69    async fn delete_branch_protection(&self, repo: &RepoRef, rule: &str) -> Result<(), ForgeError> {
70        let rule = path_segment(rule);
71        let path = repo.path(&format!("branch_protections/{rule}"));
72        self.send_write(Method::DELETE, &path, None).await
73    }
74}