summaryrefslogtreecommitdiffstats
path: root/src/generated/methods.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/generated/methods.rs')
-rw-r--r--src/generated/methods.rs8078
1 files changed, 8078 insertions, 0 deletions
diff --git a/src/generated/methods.rs b/src/generated/methods.rs
new file mode 100644
index 0000000..2b23abf
--- /dev/null
+++ b/src/generated/methods.rs
@@ -0,0 +1,8078 @@
+use super::structs::*;
+use crate::ForgejoError;
+use std::collections::BTreeMap;
+
+impl crate::Forgejo {
+ /// Returns the Repository actor for a repo
+ ///
+ /// - `repository-id`: repository ID of the repo
+ pub async fn activitypub_repository(
+ &self,
+ repository_id: u32,
+ ) -> Result<ActivityPub, ForgejoError> {
+ let request = self
+ .get(&format!("activitypub/repository-id/{repository_id}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Send to the inbox
+ ///
+ /// - `repository-id`: repository ID of the repo
+ /// - `body`: See [`ForgeLike`]
+ pub async fn activitypub_repository_inbox(
+ &self,
+ repository_id: u32,
+ body: ForgeLike,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .post(&format!("activitypub/repository-id/{repository_id}/inbox"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Returns the Person actor for a user
+ ///
+ /// - `user-id`: user ID of the user
+ pub async fn activitypub_person(&self, user_id: u32) -> Result<ActivityPub, ForgejoError> {
+ let request = self
+ .get(&format!("activitypub/user-id/{user_id}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Send to the inbox
+ ///
+ /// - `user-id`: user ID of the user
+ pub async fn activitypub_person_inbox(&self, user_id: u32) -> Result<(), ForgejoError> {
+ let request = self
+ .post(&format!("activitypub/user-id/{user_id}/inbox"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List cron tasks
+ ///
+ pub async fn admin_cron_list(
+ &self,
+ query: AdminCronListQuery,
+ ) -> Result<Vec<Cron>, ForgejoError> {
+ let request = self.get(&format!("admin/cron?{query}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Run cron task
+ ///
+ /// - `task`: task to run
+ pub async fn admin_cron_run(&self, task: &str) -> Result<(), ForgejoError> {
+ let request = self.post(&format!("admin/cron/{task}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List all emails
+ ///
+ pub async fn admin_get_all_emails(
+ &self,
+ query: AdminGetAllEmailsQuery,
+ ) -> Result<Vec<Email>, ForgejoError> {
+ let request = self.get(&format!("admin/emails?{query}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Search all emails
+ ///
+ pub async fn admin_search_emails(
+ &self,
+ query: AdminSearchEmailsQuery,
+ ) -> Result<Vec<Email>, ForgejoError> {
+ let request = self.get(&format!("admin/emails/search?{query}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List system's webhooks
+ ///
+ pub async fn admin_list_hooks(
+ &self,
+ query: AdminListHooksQuery,
+ ) -> Result<Vec<Hook>, ForgejoError> {
+ let request = self.get(&format!("admin/hooks?{query}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Create a hook
+ ///
+ /// - `body`: See [`CreateHookOption`]
+ pub async fn admin_create_hook(&self, body: CreateHookOption) -> Result<Hook, ForgejoError> {
+ let request = self.post("admin/hooks").json(&body).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get a hook
+ ///
+ /// - `id`: id of the hook to get
+ pub async fn admin_get_hook(&self, id: u64) -> Result<Hook, ForgejoError> {
+ let request = self.get(&format!("admin/hooks/{id}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete a hook
+ ///
+ /// - `id`: id of the hook to delete
+ pub async fn admin_delete_hook(&self, id: u64) -> Result<(), ForgejoError> {
+ let request = self.delete(&format!("admin/hooks/{id}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Update a hook
+ ///
+ /// - `id`: id of the hook to update
+ /// - `body`: See [`EditHookOption`]
+ pub async fn admin_edit_hook(
+ &self,
+ id: u64,
+ body: EditHookOption,
+ ) -> Result<Hook, ForgejoError> {
+ let request = self
+ .patch(&format!("admin/hooks/{id}"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List all organizations
+ ///
+ pub async fn admin_get_all_orgs(
+ &self,
+ query: AdminGetAllOrgsQuery,
+ ) -> Result<Vec<Organization>, ForgejoError> {
+ let request = self.get(&format!("admin/orgs?{query}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get an global actions runner registration token
+ pub async fn admin_get_runner_registration_token(
+ &self,
+ ) -> Result<RegistrationTokenHeaders, ForgejoError> {
+ let request = self.get("admin/runners/registration-token").build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.headers().try_into()?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List unadopted repositories
+ ///
+ pub async fn admin_unadopted_list(
+ &self,
+ query: AdminUnadoptedListQuery,
+ ) -> Result<Vec<String>, ForgejoError> {
+ let request = self.get(&format!("admin/unadopted?{query}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Adopt unadopted files as a repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn admin_adopt_repository(
+ &self,
+ owner: &str,
+ repo: &str,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .post(&format!("admin/unadopted/{owner}/{repo}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete unadopted files
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn admin_delete_unadopted_repository(
+ &self,
+ owner: &str,
+ repo: &str,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!("admin/unadopted/{owner}/{repo}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Search users according filter conditions
+ ///
+ pub async fn admin_search_users(
+ &self,
+ query: AdminSearchUsersQuery,
+ ) -> Result<Vec<User>, ForgejoError> {
+ let request = self.get(&format!("admin/users?{query}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Create a user
+ ///
+ /// - `body`: See [`CreateUserOption`]
+ pub async fn admin_create_user(&self, body: CreateUserOption) -> Result<User, ForgejoError> {
+ let request = self.post("admin/users").json(&body).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete a user
+ ///
+ /// - `username`: username of user to delete
+ pub async fn admin_delete_user(
+ &self,
+ username: &str,
+ query: AdminDeleteUserQuery,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!("admin/users/{username}?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Edit an existing user
+ ///
+ /// - `username`: username of user to edit
+ /// - `body`: See [`EditUserOption`]
+ pub async fn admin_edit_user(
+ &self,
+ username: &str,
+ body: EditUserOption,
+ ) -> Result<User, ForgejoError> {
+ let request = self
+ .patch(&format!("admin/users/{username}"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Add a public key on behalf of a user
+ ///
+ /// - `username`: username of the user
+ /// - `key`: See [`CreateKeyOption`]
+ pub async fn admin_create_public_key(
+ &self,
+ username: &str,
+ key: CreateKeyOption,
+ ) -> Result<PublicKey, ForgejoError> {
+ let request = self
+ .post(&format!("admin/users/{username}/keys"))
+ .json(&key)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete a user's public key
+ ///
+ /// - `username`: username of user
+ /// - `id`: id of the key to delete
+ pub async fn admin_delete_user_public_key(
+ &self,
+ username: &str,
+ id: u64,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!("admin/users/{username}/keys/{id}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Create an organization
+ ///
+ /// - `username`: username of the user that will own the created organization
+ /// - `organization`: See [`CreateOrgOption`]
+ pub async fn admin_create_org(
+ &self,
+ username: &str,
+ organization: CreateOrgOption,
+ ) -> Result<Organization, ForgejoError> {
+ let request = self
+ .post(&format!("admin/users/{username}/orgs"))
+ .json(&organization)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Rename a user
+ ///
+ /// - `username`: existing username of user
+ /// - `body`: See [`RenameUserOption`]
+ pub async fn admin_rename_user(
+ &self,
+ username: &str,
+ body: RenameUserOption,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .post(&format!("admin/users/{username}/rename"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Create a repository on behalf of a user
+ ///
+ /// - `username`: username of the user. This user will own the created repository
+ /// - `repository`: See [`CreateRepoOption`]
+ pub async fn admin_create_repo(
+ &self,
+ username: &str,
+ repository: CreateRepoOption,
+ ) -> Result<Repository, ForgejoError> {
+ let request = self
+ .post(&format!("admin/users/{username}/repos"))
+ .json(&repository)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Returns a list of all gitignore templates
+ pub async fn list_gitignores_templates(&self) -> Result<Vec<String>, ForgejoError> {
+ let request = self.get("gitignore/templates").build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Returns information about a gitignore template
+ ///
+ /// - `name`: name of the template
+ pub async fn get_gitignore_template_info(
+ &self,
+ name: &str,
+ ) -> Result<GitignoreTemplateInfo, ForgejoError> {
+ let request = self.get(&format!("gitignore/templates/{name}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Returns a list of all label templates
+ pub async fn list_label_templates(&self) -> Result<Vec<String>, ForgejoError> {
+ let request = self.get("label/templates").build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Returns all labels in a template
+ ///
+ /// - `name`: name of the template
+ pub async fn get_label_template_info(
+ &self,
+ name: &str,
+ ) -> Result<Vec<LabelTemplate>, ForgejoError> {
+ let request = self.get(&format!("label/templates/{name}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Returns a list of all license templates
+ pub async fn list_license_templates(
+ &self,
+ ) -> Result<Vec<LicensesTemplateListEntry>, ForgejoError> {
+ let request = self.get("licenses").build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Returns information about a license template
+ ///
+ /// - `name`: name of the license
+ pub async fn get_license_template_info(
+ &self,
+ name: &str,
+ ) -> Result<LicenseTemplateInfo, ForgejoError> {
+ let request = self.get(&format!("licenses/{name}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Render a markdown document as HTML
+ ///
+ /// - `body`: See [`MarkdownOption`]
+ pub async fn render_markdown(&self, body: MarkdownOption) -> Result<String, ForgejoError> {
+ let request = self.post("markdown").json(&body).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.text().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Render raw markdown as HTML
+ ///
+ /// - `body`: Request body to render
+
+ /// See [`String`]
+ pub async fn render_markdown_raw(&self, body: String) -> Result<String, ForgejoError> {
+ let request = self.post("markdown/raw").body(body).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.text().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Render a markup document as HTML
+ ///
+ /// - `body`: See [`MarkupOption`]
+ pub async fn render_markup(&self, body: MarkupOption) -> Result<String, ForgejoError> {
+ let request = self.post("markup").json(&body).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.text().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Returns the nodeinfo of the Forgejo application
+ pub async fn get_node_info(&self) -> Result<NodeInfo, ForgejoError> {
+ let request = self.get("nodeinfo").build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List users's notification threads
+ ///
+ pub async fn notify_get_list(
+ &self,
+ query: NotifyGetListQuery,
+ ) -> Result<Vec<NotificationThread>, ForgejoError> {
+ let request = self.get(&format!("notifications?{query}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Mark notification threads as read, pinned or unread
+ ///
+ pub async fn notify_read_list(
+ &self,
+ query: NotifyReadListQuery,
+ ) -> Result<Vec<NotificationThread>, ForgejoError> {
+ let request = self.put(&format!("notifications?{query}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 205 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Check if unread notifications exist
+ pub async fn notify_new_available(&self) -> Result<NotificationCount, ForgejoError> {
+ let request = self.get("notifications/new").build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get notification thread by ID
+ ///
+ /// - `id`: id of notification thread
+ pub async fn notify_get_thread(&self, id: &str) -> Result<NotificationThread, ForgejoError> {
+ let request = self.get(&format!("notifications/threads/{id}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Mark notification thread as read by ID
+ ///
+ /// - `id`: id of notification thread
+ pub async fn notify_read_thread(
+ &self,
+ id: &str,
+ query: NotifyReadThreadQuery,
+ ) -> Result<NotificationThread, ForgejoError> {
+ let request = self
+ .patch(&format!("notifications/threads/{id}?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 205 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Create a repository in an organization
+ ///
+ /// - `org`: name of organization
+ /// - `body`: See [`CreateRepoOption`]
+ pub async fn create_org_repo_deprecated(
+ &self,
+ org: &str,
+ body: CreateRepoOption,
+ ) -> Result<Repository, ForgejoError> {
+ let request = self.post(&format!("org/{org}/repos")).json(&body).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get list of organizations
+ ///
+ pub async fn org_get_all(
+ &self,
+ query: OrgGetAllQuery,
+ ) -> Result<Vec<Organization>, ForgejoError> {
+ let request = self.get(&format!("orgs?{query}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Create an organization
+ ///
+ /// - `organization`: See [`CreateOrgOption`]
+ pub async fn org_create(
+ &self,
+ organization: CreateOrgOption,
+ ) -> Result<Organization, ForgejoError> {
+ let request = self.post("orgs").json(&organization).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get an organization
+ ///
+ /// - `org`: name of the organization to get
+ pub async fn org_get(&self, org: &str) -> Result<Organization, ForgejoError> {
+ let request = self.get(&format!("orgs/{org}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete an organization
+ ///
+ /// - `org`: organization that is to be deleted
+ pub async fn org_delete(&self, org: &str) -> Result<(), ForgejoError> {
+ let request = self.delete(&format!("orgs/{org}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Edit an organization
+ ///
+ /// - `org`: name of the organization to edit
+ /// - `body`: See [`EditOrgOption`]
+ pub async fn org_edit(
+ &self,
+ org: &str,
+ body: EditOrgOption,
+ ) -> Result<Organization, ForgejoError> {
+ let request = self.patch(&format!("orgs/{org}")).json(&body).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get an organization's actions runner registration token
+ ///
+ /// - `org`: name of the organization
+ pub async fn org_get_runner_registration_token(
+ &self,
+ org: &str,
+ ) -> Result<RegistrationTokenHeaders, ForgejoError> {
+ let request = self
+ .get(&format!("orgs/{org}/actions/runners/registration-token"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.headers().try_into()?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List an organization's actions secrets
+ ///
+ /// - `org`: name of the organization
+ pub async fn org_list_actions_secrets(
+ &self,
+ org: &str,
+ query: OrgListActionsSecretsQuery,
+ ) -> Result<Vec<Secret>, ForgejoError> {
+ let request = self
+ .get(&format!("orgs/{org}/actions/secrets?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Create or Update a secret value in an organization
+ ///
+ /// - `org`: name of organization
+ /// - `secretname`: name of the secret
+ /// - `body`: See [`CreateOrUpdateSecretOption`]
+ pub async fn update_org_secret(
+ &self,
+ org: &str,
+ secretname: &str,
+ body: CreateOrUpdateSecretOption,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .put(&format!("orgs/{org}/actions/secrets/{secretname}"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(()),
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete a secret in an organization
+ ///
+ /// - `org`: name of organization
+ /// - `secretname`: name of the secret
+ pub async fn delete_org_secret(&self, org: &str, secretname: &str) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!("orgs/{org}/actions/secrets/{secretname}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get an org-level variables list
+ ///
+ /// - `org`: name of the organization
+ pub async fn get_org_variables_list(
+ &self,
+ org: &str,
+ query: GetOrgVariablesListQuery,
+ ) -> Result<Vec<ActionVariable>, ForgejoError> {
+ let request = self
+ .get(&format!("orgs/{org}/actions/variables?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get an org-level variable
+ ///
+ /// - `org`: name of the organization
+ /// - `variablename`: name of the variable
+ pub async fn get_org_variable(
+ &self,
+ org: &str,
+ variablename: &str,
+ ) -> Result<ActionVariable, ForgejoError> {
+ let request = self
+ .get(&format!("orgs/{org}/actions/variables/{variablename}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Update an org-level variable
+ ///
+ /// - `org`: name of the organization
+ /// - `variablename`: name of the variable
+ /// - `body`: See [`UpdateVariableOption`]
+ pub async fn update_org_variable(
+ &self,
+ org: &str,
+ variablename: &str,
+ body: UpdateVariableOption,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .put(&format!("orgs/{org}/actions/variables/{variablename}"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(()),
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Create an org-level variable
+ ///
+ /// - `org`: name of the organization
+ /// - `variablename`: name of the variable
+ /// - `body`: See [`CreateVariableOption`]
+ pub async fn create_org_variable(
+ &self,
+ org: &str,
+ variablename: &str,
+ body: CreateVariableOption,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .post(&format!("orgs/{org}/actions/variables/{variablename}"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(()),
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete an org-level variable
+ ///
+ /// - `org`: name of the organization
+ /// - `variablename`: name of the variable
+ pub async fn delete_org_variable(
+ &self,
+ org: &str,
+ variablename: &str,
+ ) -> Result<Option<ActionVariable>, ForgejoError> {
+ let request = self
+ .delete(&format!("orgs/{org}/actions/variables/{variablename}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(Some(response.json().await?)),
+ 201 => Ok(None),
+ 204 => Ok(None),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List an organization's activity feeds
+ ///
+ /// - `org`: name of the org
+ pub async fn org_list_activity_feeds(
+ &self,
+ org: &str,
+ query: OrgListActivityFeedsQuery,
+ ) -> Result<Vec<Activity>, ForgejoError> {
+ let request = self
+ .get(&format!("orgs/{org}/activities/feeds?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Update Avatar
+ ///
+ /// - `org`: name of the organization
+ /// - `body`: See [`UpdateUserAvatarOption`]
+ pub async fn org_update_avatar(
+ &self,
+ org: &str,
+ body: UpdateUserAvatarOption,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .post(&format!("orgs/{org}/avatar"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete Avatar
+ ///
+ /// - `org`: name of the organization
+ pub async fn org_delete_avatar(&self, org: &str) -> Result<(), ForgejoError> {
+ let request = self.delete(&format!("orgs/{org}/avatar")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Blocks a user from the organization
+ ///
+ /// - `org`: name of the org
+ /// - `username`: username of the user
+ pub async fn org_block_user(&self, org: &str, username: &str) -> Result<(), ForgejoError> {
+ let request = self.put(&format!("orgs/{org}/block/{username}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List an organization's webhooks
+ ///
+ /// - `org`: name of the organization
+ pub async fn org_list_hooks(
+ &self,
+ org: &str,
+ query: OrgListHooksQuery,
+ ) -> Result<Vec<Hook>, ForgejoError> {
+ let request = self.get(&format!("orgs/{org}/hooks?{query}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Create a hook
+ ///
+ /// - `org`: name of the organization
+ /// - `body`: See [`CreateHookOption`]
+ pub async fn org_create_hook(
+ &self,
+ org: &str,
+ body: CreateHookOption,
+ ) -> Result<Hook, ForgejoError> {
+ let request = self
+ .post(&format!("orgs/{org}/hooks"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get a hook
+ ///
+ /// - `org`: name of the organization
+ /// - `id`: id of the hook to get
+ pub async fn org_get_hook(&self, org: &str, id: u64) -> Result<Hook, ForgejoError> {
+ let request = self.get(&format!("orgs/{org}/hooks/{id}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete a hook
+ ///
+ /// - `org`: name of the organization
+ /// - `id`: id of the hook to delete
+ pub async fn org_delete_hook(&self, org: &str, id: u64) -> Result<(), ForgejoError> {
+ let request = self.delete(&format!("orgs/{org}/hooks/{id}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Update a hook
+ ///
+ /// - `org`: name of the organization
+ /// - `id`: id of the hook to update
+ /// - `body`: See [`EditHookOption`]
+ pub async fn org_edit_hook(
+ &self,
+ org: &str,
+ id: u64,
+ body: EditHookOption,
+ ) -> Result<Hook, ForgejoError> {
+ let request = self
+ .patch(&format!("orgs/{org}/hooks/{id}"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List an organization's labels
+ ///
+ /// - `org`: name of the organization
+ pub async fn org_list_labels(
+ &self,
+ org: &str,
+ query: OrgListLabelsQuery,
+ ) -> Result<Vec<Label>, ForgejoError> {
+ let request = self.get(&format!("orgs/{org}/labels?{query}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Create a label for an organization
+ ///
+ /// - `org`: name of the organization
+ /// - `body`: See [`CreateLabelOption`]
+ pub async fn org_create_label(
+ &self,
+ org: &str,
+ body: CreateLabelOption,
+ ) -> Result<Label, ForgejoError> {
+ let request = self
+ .post(&format!("orgs/{org}/labels"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get a single label
+ ///
+ /// - `org`: name of the organization
+ /// - `id`: id of the label to get
+ pub async fn org_get_label(&self, org: &str, id: u64) -> Result<Label, ForgejoError> {
+ let request = self.get(&format!("orgs/{org}/labels/{id}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete a label
+ ///
+ /// - `org`: name of the organization
+ /// - `id`: id of the label to delete
+ pub async fn org_delete_label(&self, org: &str, id: u64) -> Result<(), ForgejoError> {
+ let request = self.delete(&format!("orgs/{org}/labels/{id}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Update a label
+ ///
+ /// - `org`: name of the organization
+ /// - `id`: id of the label to edit
+ /// - `body`: See [`EditLabelOption`]
+ pub async fn org_edit_label(
+ &self,
+ org: &str,
+ id: u64,
+ body: EditLabelOption,
+ ) -> Result<Label, ForgejoError> {
+ let request = self
+ .patch(&format!("orgs/{org}/labels/{id}"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List the organization's blocked users
+ ///
+ /// - `org`: name of the org
+ pub async fn org_list_blocked_users(
+ &self,
+ org: &str,
+ query: OrgListBlockedUsersQuery,
+ ) -> Result<Vec<BlockedUser>, ForgejoError> {
+ let request = self
+ .get(&format!("orgs/{org}/list_blocked?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List an organization's members
+ ///
+ /// - `org`: name of the organization
+ pub async fn org_list_members(
+ &self,
+ org: &str,
+ query: OrgListMembersQuery,
+ ) -> Result<Vec<User>, ForgejoError> {
+ let request = self.get(&format!("orgs/{org}/members?{query}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Check if a user is a member of an organization
+ ///
+ /// - `org`: name of the organization
+ /// - `username`: username of the user
+ pub async fn org_is_member(&self, org: &str, username: &str) -> Result<(), ForgejoError> {
+ let request = self
+ .get(&format!("orgs/{org}/members/{username}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Remove a member from an organization
+ ///
+ /// - `org`: name of the organization
+ /// - `username`: username of the user
+ pub async fn org_delete_member(&self, org: &str, username: &str) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!("orgs/{org}/members/{username}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List an organization's public members
+ ///
+ /// - `org`: name of the organization
+ pub async fn org_list_public_members(
+ &self,
+ org: &str,
+ query: OrgListPublicMembersQuery,
+ ) -> Result<Vec<User>, ForgejoError> {
+ let request = self
+ .get(&format!("orgs/{org}/public_members?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Check if a user is a public member of an organization
+ ///
+ /// - `org`: name of the organization
+ /// - `username`: username of the user
+ pub async fn org_is_public_member(
+ &self,
+ org: &str,
+ username: &str,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .get(&format!("orgs/{org}/public_members/{username}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Publicize a user's membership
+ ///
+ /// - `org`: name of the organization
+ /// - `username`: username of the user
+ pub async fn org_publicize_member(
+ &self,
+ org: &str,
+ username: &str,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .put(&format!("orgs/{org}/public_members/{username}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Conceal a user's membership
+ ///
+ /// - `org`: name of the organization
+ /// - `username`: username of the user
+ pub async fn org_conceal_member(&self, org: &str, username: &str) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!("orgs/{org}/public_members/{username}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List an organization's repos
+ ///
+ /// - `org`: name of the organization
+ pub async fn org_list_repos(
+ &self,
+ org: &str,
+ query: OrgListReposQuery,
+ ) -> Result<Vec<Repository>, ForgejoError> {
+ let request = self.get(&format!("orgs/{org}/repos?{query}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Create a repository in an organization
+ ///
+ /// - `org`: name of organization
+ /// - `body`: See [`CreateRepoOption`]
+ pub async fn create_org_repo(
+ &self,
+ org: &str,
+ body: CreateRepoOption,
+ ) -> Result<Repository, ForgejoError> {
+ let request = self
+ .post(&format!("orgs/{org}/repos"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List an organization's teams
+ ///
+ /// - `org`: name of the organization
+ pub async fn org_list_teams(
+ &self,
+ org: &str,
+ query: OrgListTeamsQuery,
+ ) -> Result<Vec<Team>, ForgejoError> {
+ let request = self.get(&format!("orgs/{org}/teams?{query}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Create a team
+ ///
+ /// - `org`: name of the organization
+ /// - `body`: See [`CreateTeamOption`]
+ pub async fn org_create_team(
+ &self,
+ org: &str,
+ body: CreateTeamOption,
+ ) -> Result<Team, ForgejoError> {
+ let request = self
+ .post(&format!("orgs/{org}/teams"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Search for teams within an organization
+ ///
+ /// - `org`: name of the organization
+ pub async fn team_search(
+ &self,
+ org: &str,
+ query: TeamSearchQuery,
+ ) -> Result<TeamSearchResponse, ForgejoError> {
+ let request = self
+ .get(&format!("orgs/{org}/teams/search?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Unblock a user from the organization
+ ///
+ /// - `org`: name of the org
+ /// - `username`: username of the user
+ pub async fn org_unblock_user(&self, org: &str, username: &str) -> Result<(), ForgejoError> {
+ let request = self
+ .put(&format!("orgs/{org}/unblock/{username}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Gets all packages of an owner
+ ///
+ /// - `owner`: owner of the packages
+ pub async fn list_packages(
+ &self,
+ owner: &str,
+ query: ListPackagesQuery,
+ ) -> Result<Vec<Package>, ForgejoError> {
+ let request = self.get(&format!("packages/{owner}?{query}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Gets a package
+ ///
+ /// - `owner`: owner of the package
+ /// - `type`: type of the package
+ /// - `name`: name of the package
+ /// - `version`: version of the package
+ pub async fn get_package(
+ &self,
+ owner: &str,
+ r#type: &str,
+ name: &str,
+ version: &str,
+ ) -> Result<Package, ForgejoError> {
+ let request = self
+ .get(&format!("packages/{owner}/{type}/{name}/{version}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete a package
+ ///
+ /// - `owner`: owner of the package
+ /// - `type`: type of the package
+ /// - `name`: name of the package
+ /// - `version`: version of the package
+ pub async fn delete_package(
+ &self,
+ owner: &str,
+ r#type: &str,
+ name: &str,
+ version: &str,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!("packages/{owner}/{type}/{name}/{version}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Gets all files of a package
+ ///
+ /// - `owner`: owner of the package
+ /// - `type`: type of the package
+ /// - `name`: name of the package
+ /// - `version`: version of the package
+ pub async fn list_package_files(
+ &self,
+ owner: &str,
+ r#type: &str,
+ name: &str,
+ version: &str,
+ ) -> Result<Vec<PackageFile>, ForgejoError> {
+ let request = self
+ .get(&format!("packages/{owner}/{type}/{name}/{version}/files"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Search for issues across the repositories that the user has access to
+ ///
+ pub async fn issue_search_issues(
+ &self,
+ query: IssueSearchIssuesQuery,
+ ) -> Result<Vec<Issue>, ForgejoError> {
+ let request = self.get(&format!("repos/issues/search?{query}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Migrate a remote git repository
+ ///
+ /// - `body`: See [`MigrateRepoOptions`]
+ pub async fn repo_migrate(&self, body: MigrateRepoOptions) -> Result<Repository, ForgejoError> {
+ let request = self.post("repos/migrate").json(&body).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Search for repositories
+ ///
+ pub async fn repo_search(&self, query: RepoSearchQuery) -> Result<SearchResults, ForgejoError> {
+ let request = self.get(&format!("repos/search?{query}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get a repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn repo_get(&self, owner: &str, repo: &str) -> Result<Repository, ForgejoError> {
+ let request = self.get(&format!("repos/{owner}/{repo}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete a repository
+ ///
+ /// - `owner`: owner of the repo to delete
+ /// - `repo`: name of the repo to delete
+ pub async fn repo_delete(&self, owner: &str, repo: &str) -> Result<(), ForgejoError> {
+ let request = self.delete(&format!("repos/{owner}/{repo}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Edit a repository's properties. Only fields that are set will be changed.
+ ///
+ /// - `owner`: owner of the repo to edit
+ /// - `repo`: name of the repo to edit
+ /// - `body`: Properties of a repo that you can edit
+
+ /// See [`EditRepoOption`]
+ pub async fn repo_edit(
+ &self,
+ owner: &str,
+ repo: &str,
+ body: EditRepoOption,
+ ) -> Result<Repository, ForgejoError> {
+ let request = self
+ .patch(&format!("repos/{owner}/{repo}"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List an repo's actions secrets
+ ///
+ /// - `owner`: owner of the repository
+ /// - `repo`: name of the repository
+ pub async fn repo_list_actions_secrets(
+ &self,
+ owner: &str,
+ repo: &str,
+ query: RepoListActionsSecretsQuery,
+ ) -> Result<Vec<Secret>, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/actions/secrets?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Create or Update a secret value in a repository
+ ///
+ /// - `owner`: owner of the repository
+ /// - `repo`: name of the repository
+ /// - `secretname`: name of the secret
+ /// - `body`: See [`CreateOrUpdateSecretOption`]
+ pub async fn update_repo_secret(
+ &self,
+ owner: &str,
+ repo: &str,
+ secretname: &str,
+ body: CreateOrUpdateSecretOption,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .put(&format!(
+ "repos/{owner}/{repo}/actions/secrets/{secretname}"
+ ))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(()),
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete a secret in a repository
+ ///
+ /// - `owner`: owner of the repository
+ /// - `repo`: name of the repository
+ /// - `secretname`: name of the secret
+ pub async fn delete_repo_secret(
+ &self,
+ owner: &str,
+ repo: &str,
+ secretname: &str,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!(
+ "repos/{owner}/{repo}/actions/secrets/{secretname}"
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List a repository's action tasks
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn list_action_tasks(
+ &self,
+ owner: &str,
+ repo: &str,
+ query: ListActionTasksQuery,
+ ) -> Result<ActionTaskResponse, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/actions/tasks?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get repo-level variables list
+ ///
+ /// - `owner`: name of the owner
+ /// - `repo`: name of the repository
+ pub async fn get_repo_variables_list(
+ &self,
+ owner: &str,
+ repo: &str,
+ query: GetRepoVariablesListQuery,
+ ) -> Result<Vec<ActionVariable>, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/actions/variables?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get a repo-level variable
+ ///
+ /// - `owner`: name of the owner
+ /// - `repo`: name of the repository
+ /// - `variablename`: name of the variable
+ pub async fn get_repo_variable(
+ &self,
+ owner: &str,
+ repo: &str,
+ variablename: &str,
+ ) -> Result<ActionVariable, ForgejoError> {
+ let request = self
+ .get(&format!(
+ "repos/{owner}/{repo}/actions/variables/{variablename}"
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Update a repo-level variable
+ ///
+ /// - `owner`: name of the owner
+ /// - `repo`: name of the repository
+ /// - `variablename`: name of the variable
+ /// - `body`: See [`UpdateVariableOption`]
+ pub async fn update_repo_variable(
+ &self,
+ owner: &str,
+ repo: &str,
+ variablename: &str,
+ body: UpdateVariableOption,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .put(&format!(
+ "repos/{owner}/{repo}/actions/variables/{variablename}"
+ ))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(()),
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Create a repo-level variable
+ ///
+ /// - `owner`: name of the owner
+ /// - `repo`: name of the repository
+ /// - `variablename`: name of the variable
+ /// - `body`: See [`CreateVariableOption`]
+ pub async fn create_repo_variable(
+ &self,
+ owner: &str,
+ repo: &str,
+ variablename: &str,
+ body: CreateVariableOption,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .post(&format!(
+ "repos/{owner}/{repo}/actions/variables/{variablename}"
+ ))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(()),
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete a repo-level variable
+ ///
+ /// - `owner`: name of the owner
+ /// - `repo`: name of the repository
+ /// - `variablename`: name of the variable
+ pub async fn delete_repo_variable(
+ &self,
+ owner: &str,
+ repo: &str,
+ variablename: &str,
+ ) -> Result<Option<ActionVariable>, ForgejoError> {
+ let request = self
+ .delete(&format!(
+ "repos/{owner}/{repo}/actions/variables/{variablename}"
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(Some(response.json().await?)),
+ 201 => Ok(None),
+ 204 => Ok(None),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Dispatches a workflow
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `workflowname`: name of the workflow
+ /// - `body`: See [`DispatchWorkflowOption`]
+ pub async fn dispatch_workflow(
+ &self,
+ owner: &str,
+ repo: &str,
+ workflowname: &str,
+ body: DispatchWorkflowOption,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .post(&format!(
+ "repos/{owner}/{repo}/actions/workflows/{workflowname}/dispatches"
+ ))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List a repository's activity feeds
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn repo_list_activity_feeds(
+ &self,
+ owner: &str,
+ repo: &str,
+ query: RepoListActivityFeedsQuery,
+ ) -> Result<Vec<Activity>, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/activities/feeds?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get an archive of a repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `archive`: the git reference for download with attached archive format (e.g. master.zip)
+ pub async fn repo_get_archive(
+ &self,
+ owner: &str,
+ repo: &str,
+ archive: &str,
+ ) -> Result<Vec<u8>, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/archive/{archive}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.bytes().await?[..].to_vec()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Return all users that have write access and can be assigned to issues
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn repo_get_assignees(
+ &self,
+ owner: &str,
+ repo: &str,
+ ) -> Result<Vec<User>, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/assignees"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Update avatar
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `body`: See [`UpdateRepoAvatarOption`]
+ pub async fn repo_update_avatar(
+ &self,
+ owner: &str,
+ repo: &str,
+ body: UpdateRepoAvatarOption,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .post(&format!("repos/{owner}/{repo}/avatar"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete avatar
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn repo_delete_avatar(&self, owner: &str, repo: &str) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!("repos/{owner}/{repo}/avatar"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List branch protections for a repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn repo_list_branch_protection(
+ &self,
+ owner: &str,
+ repo: &str,
+ ) -> Result<Vec<BranchProtection>, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/branch_protections"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Create a branch protections for a repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `body`: See [`CreateBranchProtectionOption`]
+ pub async fn repo_create_branch_protection(
+ &self,
+ owner: &str,
+ repo: &str,
+ body: CreateBranchProtectionOption,
+ ) -> Result<BranchProtection, ForgejoError> {
+ let request = self
+ .post(&format!("repos/{owner}/{repo}/branch_protections"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get a specific branch protection for the repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `name`: name of protected branch
+ pub async fn repo_get_branch_protection(
+ &self,
+ owner: &str,
+ repo: &str,
+ name: &str,
+ ) -> Result<BranchProtection, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/branch_protections/{name}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete a specific branch protection for the repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `name`: name of protected branch
+ pub async fn repo_delete_branch_protection(
+ &self,
+ owner: &str,
+ repo: &str,
+ name: &str,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!("repos/{owner}/{repo}/branch_protections/{name}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Edit a branch protections for a repository. Only fields that are set will be changed
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `name`: name of protected branch
+ /// - `body`: See [`EditBranchProtectionOption`]
+ pub async fn repo_edit_branch_protection(
+ &self,
+ owner: &str,
+ repo: &str,
+ name: &str,
+ body: EditBranchProtectionOption,
+ ) -> Result<BranchProtection, ForgejoError> {
+ let request = self
+ .patch(&format!("repos/{owner}/{repo}/branch_protections/{name}"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List a repository's branches
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn repo_list_branches(
+ &self,
+ owner: &str,
+ repo: &str,
+ query: RepoListBranchesQuery,
+ ) -> Result<Vec<Branch>, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/branches?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Create a branch
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `body`: See [`CreateBranchRepoOption`]
+ pub async fn repo_create_branch(
+ &self,
+ owner: &str,
+ repo: &str,
+ body: CreateBranchRepoOption,
+ ) -> Result<Branch, ForgejoError> {
+ let request = self
+ .post(&format!("repos/{owner}/{repo}/branches"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Retrieve a specific branch from a repository, including its effective branch protection
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `branch`: branch to get
+ pub async fn repo_get_branch(
+ &self,
+ owner: &str,
+ repo: &str,
+ branch: &str,
+ ) -> Result<Branch, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/branches/{branch}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete a specific branch from a repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `branch`: branch to delete
+ pub async fn repo_delete_branch(
+ &self,
+ owner: &str,
+ repo: &str,
+ branch: &str,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!("repos/{owner}/{repo}/branches/{branch}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List a repository's collaborators
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn repo_list_collaborators(
+ &self,
+ owner: &str,
+ repo: &str,
+ query: RepoListCollaboratorsQuery,
+ ) -> Result<Vec<User>, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/collaborators?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Check if a user is a collaborator of a repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `collaborator`: username of the collaborator
+ pub async fn repo_check_collaborator(
+ &self,
+ owner: &str,
+ repo: &str,
+ collaborator: &str,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .get(&format!(
+ "repos/{owner}/{repo}/collaborators/{collaborator}"
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Add a collaborator to a repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `collaborator`: username of the collaborator to add
+ /// - `body`: See [`AddCollaboratorOption`]
+ pub async fn repo_add_collaborator(
+ &self,
+ owner: &str,
+ repo: &str,
+ collaborator: &str,
+ body: AddCollaboratorOption,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .put(&format!(
+ "repos/{owner}/{repo}/collaborators/{collaborator}"
+ ))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete a collaborator from a repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `collaborator`: username of the collaborator to delete
+ pub async fn repo_delete_collaborator(
+ &self,
+ owner: &str,
+ repo: &str,
+ collaborator: &str,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!(
+ "repos/{owner}/{repo}/collaborators/{collaborator}"
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get repository permissions for a user
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `collaborator`: username of the collaborator
+ pub async fn repo_get_repo_permissions(
+ &self,
+ owner: &str,
+ repo: &str,
+ collaborator: &str,
+ ) -> Result<RepoCollaboratorPermission, ForgejoError> {
+ let request = self
+ .get(&format!(
+ "repos/{owner}/{repo}/collaborators/{collaborator}/permission"
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get a list of all commits from a repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn repo_get_all_commits(
+ &self,
+ owner: &str,
+ repo: &str,
+ query: RepoGetAllCommitsQuery,
+ ) -> Result<(CommitListHeaders, Vec<Commit>), ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/commits?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok((response.headers().try_into()?, response.json().await?)),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get a commit's combined status, by branch/tag/commit reference
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `ref`: name of branch/tag/commit
+ pub async fn repo_get_combined_status_by_ref(
+ &self,
+ owner: &str,
+ repo: &str,
+ r#ref: &str,
+ query: RepoGetCombinedStatusByRefQuery,
+ ) -> Result<CombinedStatus, ForgejoError> {
+ let request = self
+ .get(&format!(
+ "repos/{owner}/{repo}/commits/{ref}/status?{query}"
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get a commit's statuses, by branch/tag/commit reference
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `ref`: name of branch/tag/commit
+ pub async fn repo_list_statuses_by_ref(
+ &self,
+ owner: &str,
+ repo: &str,
+ r#ref: &str,
+ query: RepoListStatusesByRefQuery,
+ ) -> Result<Vec<CommitStatus>, ForgejoError> {
+ let request = self
+ .get(&format!(
+ "repos/{owner}/{repo}/commits/{ref}/statuses?{query}"
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get the pull request of the commit
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `sha`: SHA of the commit to get
+ pub async fn repo_get_commit_pull_request(
+ &self,
+ owner: &str,
+ repo: &str,
+ sha: &str,
+ ) -> Result<PullRequest, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/commits/{sha}/pull"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get commit comparison information
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `basehead`: compare two branches or commits
+ pub async fn repo_compare_diff(
+ &self,
+ owner: &str,
+ repo: &str,
+ basehead: &str,
+ ) -> Result<Compare, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/compare/{basehead}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Gets the metadata of all the entries of the root dir
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn repo_get_contents_list(
+ &self,
+ owner: &str,
+ repo: &str,
+ query: RepoGetContentsListQuery,
+ ) -> Result<Vec<ContentsResponse>, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/contents?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Modify multiple files in a repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `body`: See [`ChangeFilesOptions`]
+ pub async fn repo_change_files(
+ &self,
+ owner: &str,
+ repo: &str,
+ body: ChangeFilesOptions,
+ ) -> Result<FilesResponse, ForgejoError> {
+ let request = self
+ .post(&format!("repos/{owner}/{repo}/contents"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Gets the metadata and contents (if a file) of an entry in a repository, or a list of entries if a dir
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `filepath`: path of the dir, file, symlink or submodule in the repo
+ pub async fn repo_get_contents(
+ &self,
+ owner: &str,
+ repo: &str,
+ filepath: &str,
+ query: RepoGetContentsQuery,
+ ) -> Result<ContentsResponse, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/contents/{filepath}?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Update a file in a repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `filepath`: path of the file to update
+ /// - `body`: See [`UpdateFileOptions`]
+ pub async fn repo_update_file(
+ &self,
+ owner: &str,
+ repo: &str,
+ filepath: &str,
+ body: UpdateFileOptions,
+ ) -> Result<FileResponse, ForgejoError> {
+ let request = self
+ .put(&format!("repos/{owner}/{repo}/contents/{filepath}"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Create a file in a repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `filepath`: path of the file to create
+ /// - `body`: See [`CreateFileOptions`]
+ pub async fn repo_create_file(
+ &self,
+ owner: &str,
+ repo: &str,
+ filepath: &str,
+ body: CreateFileOptions,
+ ) -> Result<FileResponse, ForgejoError> {
+ let request = self
+ .post(&format!("repos/{owner}/{repo}/contents/{filepath}"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete a file in a repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `filepath`: path of the file to delete
+ /// - `body`: See [`DeleteFileOptions`]
+ pub async fn repo_delete_file(
+ &self,
+ owner: &str,
+ repo: &str,
+ filepath: &str,
+ body: DeleteFileOptions,
+ ) -> Result<FileDeleteResponse, ForgejoError> {
+ let request = self
+ .delete(&format!("repos/{owner}/{repo}/contents/{filepath}"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Apply diff patch to repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `body`: See [`UpdateFileOptions`]
+ pub async fn repo_apply_diff_patch(
+ &self,
+ owner: &str,
+ repo: &str,
+ body: UpdateFileOptions,
+ ) -> Result<FileResponse, ForgejoError> {
+ let request = self
+ .post(&format!("repos/{owner}/{repo}/diffpatch"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get the EditorConfig definitions of a file in a repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `filepath`: filepath of file to get
+ pub async fn repo_get_editor_config(
+ &self,
+ owner: &str,
+ repo: &str,
+ filepath: &str,
+ query: RepoGetEditorConfigQuery,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .get(&format!(
+ "repos/{owner}/{repo}/editorconfig/{filepath}?{query}"
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List a repository's flags
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn repo_list_flags(
+ &self,
+ owner: &str,
+ repo: &str,
+ ) -> Result<Vec<String>, ForgejoError> {
+ let request = self.get(&format!("repos/{owner}/{repo}/flags")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Replace all flags of a repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `body`: See [`ReplaceFlagsOption`]
+ pub async fn repo_replace_all_flags(
+ &self,
+ owner: &str,
+ repo: &str,
+ body: ReplaceFlagsOption,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .put(&format!("repos/{owner}/{repo}/flags"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Remove all flags from a repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn repo_delete_all_flags(&self, owner: &str, repo: &str) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!("repos/{owner}/{repo}/flags"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Check if a repository has a given flag
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `flag`: name of the flag
+ pub async fn repo_check_flag(
+ &self,
+ owner: &str,
+ repo: &str,
+ flag: &str,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/flags/{flag}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Add a flag to a repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `flag`: name of the flag
+ pub async fn repo_add_flag(
+ &self,
+ owner: &str,
+ repo: &str,
+ flag: &str,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .put(&format!("repos/{owner}/{repo}/flags/{flag}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Remove a flag from a repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `flag`: name of the flag
+ pub async fn repo_delete_flag(
+ &self,
+ owner: &str,
+ repo: &str,
+ flag: &str,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!("repos/{owner}/{repo}/flags/{flag}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List a repository's forks
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn list_forks(
+ &self,
+ owner: &str,
+ repo: &str,
+ query: ListForksQuery,
+ ) -> Result<Vec<Repository>, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/forks?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Fork a repository
+ ///
+ /// - `owner`: owner of the repo to fork
+ /// - `repo`: name of the repo to fork
+ /// - `body`: See [`CreateForkOption`]
+ pub async fn create_fork(
+ &self,
+ owner: &str,
+ repo: &str,
+ body: CreateForkOption,
+ ) -> Result<Repository, ForgejoError> {
+ let request = self
+ .post(&format!("repos/{owner}/{repo}/forks"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 202 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Gets the blob of a repository.
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `sha`: sha of the commit
+ pub async fn get_blob(
+ &self,
+ owner: &str,
+ repo: &str,
+ sha: &str,
+ ) -> Result<GitBlobResponse, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/git/blobs/{sha}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get a single commit from a repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `sha`: a git ref or commit sha
+ pub async fn repo_get_single_commit(
+ &self,
+ owner: &str,
+ repo: &str,
+ sha: &str,
+ query: RepoGetSingleCommitQuery,
+ ) -> Result<Commit, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/git/commits/{sha}?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get a commit's diff or patch
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `sha`: SHA of the commit to get
+ /// - `diffType`: whether the output is diff or patch
+ pub async fn repo_download_commit_diff_or_patch(
+ &self,
+ owner: &str,
+ repo: &str,
+ sha: &str,
+ diff_type: &str,
+ ) -> Result<String, ForgejoError> {
+ let request = self
+ .get(&format!(
+ "repos/{owner}/{repo}/git/commits/{sha}.{diff_type}"
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.text().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get a note corresponding to a single commit from a repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `sha`: a git ref or commit sha
+ pub async fn repo_get_note(
+ &self,
+ owner: &str,
+ repo: &str,
+ sha: &str,
+ query: RepoGetNoteQuery,
+ ) -> Result<Note, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/git/notes/{sha}?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get specified ref or filtered repository's refs
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn repo_list_all_git_refs(
+ &self,
+ owner: &str,
+ repo: &str,
+ ) -> Result<Vec<Reference>, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/git/refs"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get specified ref or filtered repository's refs
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `ref`: part or full name of the ref
+ pub async fn repo_list_git_refs(
+ &self,
+ owner: &str,
+ repo: &str,
+ r#ref: &str,
+ ) -> Result<Vec<Reference>, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/git/refs/{ref}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Gets the tag object of an annotated tag (not lightweight tags)
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `sha`: sha of the tag. The Git tags API only supports annotated tag objects, not lightweight tags.
+ pub async fn get_annotated_tag(
+ &self,
+ owner: &str,
+ repo: &str,
+ sha: &str,
+ ) -> Result<AnnotatedTag, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/git/tags/{sha}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Gets the tree of a repository.
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `sha`: sha of the commit
+ pub async fn get_tree(
+ &self,
+ owner: &str,
+ repo: &str,
+ sha: &str,
+ query: GetTreeQuery,
+ ) -> Result<GitTreeResponse, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/git/trees/{sha}?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List the hooks in a repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn repo_list_hooks(
+ &self,
+ owner: &str,
+ repo: &str,
+ query: RepoListHooksQuery,
+ ) -> Result<Vec<Hook>, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/hooks?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Create a hook
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `body`: See [`CreateHookOption`]
+ pub async fn repo_create_hook(
+ &self,
+ owner: &str,
+ repo: &str,
+ body: CreateHookOption,
+ ) -> Result<Hook, ForgejoError> {
+ let request = self
+ .post(&format!("repos/{owner}/{repo}/hooks"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List the Git hooks in a repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn repo_list_git_hooks(
+ &self,
+ owner: &str,
+ repo: &str,
+ ) -> Result<Vec<GitHook>, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/hooks/git"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get a Git hook
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `id`: id of the hook to get
+ pub async fn repo_get_git_hook(
+ &self,
+ owner: &str,
+ repo: &str,
+ id: &str,
+ ) -> Result<GitHook, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/hooks/git/{id}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete a Git hook in a repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `id`: id of the hook to get
+ pub async fn repo_delete_git_hook(
+ &self,
+ owner: &str,
+ repo: &str,
+ id: &str,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!("repos/{owner}/{repo}/hooks/git/{id}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Edit a Git hook in a repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `id`: id of the hook to get
+ /// - `body`: See [`EditGitHookOption`]
+ pub async fn repo_edit_git_hook(
+ &self,
+ owner: &str,
+ repo: &str,
+ id: &str,
+ body: EditGitHookOption,
+ ) -> Result<GitHook, ForgejoError> {
+ let request = self
+ .patch(&format!("repos/{owner}/{repo}/hooks/git/{id}"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get a hook
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `id`: id of the hook to get
+ pub async fn repo_get_hook(
+ &self,
+ owner: &str,
+ repo: &str,
+ id: u64,
+ ) -> Result<Hook, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/hooks/{id}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete a hook in a repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `id`: id of the hook to delete
+ pub async fn repo_delete_hook(
+ &self,
+ owner: &str,
+ repo: &str,
+ id: u64,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!("repos/{owner}/{repo}/hooks/{id}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Edit a hook in a repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `id`: index of the hook
+ /// - `body`: See [`EditHookOption`]
+ pub async fn repo_edit_hook(
+ &self,
+ owner: &str,
+ repo: &str,
+ id: u64,
+ body: EditHookOption,
+ ) -> Result<Hook, ForgejoError> {
+ let request = self
+ .patch(&format!("repos/{owner}/{repo}/hooks/{id}"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Test a push webhook
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `id`: id of the hook to test
+ pub async fn repo_test_hook(
+ &self,
+ owner: &str,
+ repo: &str,
+ id: u64,
+ query: RepoTestHookQuery,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .post(&format!("repos/{owner}/{repo}/hooks/{id}/tests?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Returns the issue config for a repo
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn repo_get_issue_config(
+ &self,
+ owner: &str,
+ repo: &str,
+ ) -> Result<IssueConfig, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/issue_config"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Returns the validation information for a issue config
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn repo_validate_issue_config(
+ &self,
+ owner: &str,
+ repo: &str,
+ ) -> Result<IssueConfigValidation, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/issue_config/validate"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get available issue templates for a repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn repo_get_issue_templates(
+ &self,
+ owner: &str,
+ repo: &str,
+ ) -> Result<Vec<IssueTemplate>, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/issue_templates"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List a repository's issues
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn issue_list_issues(
+ &self,
+ owner: &str,
+ repo: &str,
+ query: IssueListIssuesQuery,
+ ) -> Result<Vec<Issue>, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/issues?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Create an issue. If using deadline only the date will be taken into account, and time of day ignored.
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `body`: See [`CreateIssueOption`]
+ pub async fn issue_create_issue(
+ &self,
+ owner: &str,
+ repo: &str,
+ body: CreateIssueOption,
+ ) -> Result<Issue, ForgejoError> {
+ let request = self
+ .post(&format!("repos/{owner}/{repo}/issues"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List all comments in a repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn issue_get_repo_comments(
+ &self,
+ owner: &str,
+ repo: &str,
+ query: IssueGetRepoCommentsQuery,
+ ) -> Result<Vec<Comment>, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/issues/comments?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get a comment
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `id`: id of the comment
+ pub async fn issue_get_comment(
+ &self,
+ owner: &str,
+ repo: &str,
+ id: u64,
+ ) -> Result<Option<Comment>, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/issues/comments/{id}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(Some(response.json().await?)),
+ 204 => Ok(None),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete a comment
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `id`: id of comment to delete
+ pub async fn issue_delete_comment(
+ &self,
+ owner: &str,
+ repo: &str,
+ id: u64,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!("repos/{owner}/{repo}/issues/comments/{id}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Edit a comment
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `id`: id of the comment to edit
+ /// - `body`: See [`EditIssueCommentOption`]
+ pub async fn issue_edit_comment(
+ &self,
+ owner: &str,
+ repo: &str,
+ id: u64,
+ body: EditIssueCommentOption,
+ ) -> Result<Option<Comment>, ForgejoError> {
+ let request = self
+ .patch(&format!("repos/{owner}/{repo}/issues/comments/{id}"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(Some(response.json().await?)),
+ 204 => Ok(None),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List comment's attachments
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `id`: id of the comment
+ pub async fn issue_list_issue_comment_attachments(
+ &self,
+ owner: &str,
+ repo: &str,
+ id: u64,
+ ) -> Result<Vec<Attachment>, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/issues/comments/{id}/assets"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Create a comment attachment
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `id`: id of the comment
+ /// - `attachment`: attachment to upload
+ pub async fn issue_create_issue_comment_attachment(
+ &self,
+ owner: &str,
+ repo: &str,
+ id: u64,
+ attachment: Vec<u8>,
+ query: IssueCreateIssueCommentAttachmentQuery,
+ ) -> Result<Attachment, ForgejoError> {
+ let request = self
+ .post(&format!(
+ "repos/{owner}/{repo}/issues/comments/{id}/assets?{query}"
+ ))
+ .multipart(
+ reqwest::multipart::Form::new().part(
+ "attachment",
+ reqwest::multipart::Part::bytes(attachment)
+ .file_name("file")
+ .mime_str("*/*")
+ .unwrap(),
+ ),
+ )
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get a comment attachment
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `id`: id of the comment
+ /// - `attachment_id`: id of the attachment to get
+ pub async fn issue_get_issue_comment_attachment(
+ &self,
+ owner: &str,
+ repo: &str,
+ id: u64,
+ attachment_id: u64,
+ ) -> Result<Attachment, ForgejoError> {
+ let request = self
+ .get(&format!(
+ "repos/{owner}/{repo}/issues/comments/{id}/assets/{attachment_id}"
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete a comment attachment
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `id`: id of the comment
+ /// - `attachment_id`: id of the attachment to delete
+ pub async fn issue_delete_issue_comment_attachment(
+ &self,
+ owner: &str,
+ repo: &str,
+ id: u64,
+ attachment_id: u64,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!(
+ "repos/{owner}/{repo}/issues/comments/{id}/assets/{attachment_id}"
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Edit a comment attachment
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `id`: id of the comment
+ /// - `attachment_id`: id of the attachment to edit
+ /// - `body`: See [`EditAttachmentOptions`]
+ pub async fn issue_edit_issue_comment_attachment(
+ &self,
+ owner: &str,
+ repo: &str,
+ id: u64,
+ attachment_id: u64,
+ body: EditAttachmentOptions,
+ ) -> Result<Attachment, ForgejoError> {
+ let request = self
+ .patch(&format!(
+ "repos/{owner}/{repo}/issues/comments/{id}/assets/{attachment_id}"
+ ))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get a list of reactions from a comment of an issue
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `id`: id of the comment to edit
+ pub async fn issue_get_comment_reactions(
+ &self,
+ owner: &str,
+ repo: &str,
+ id: u64,
+ ) -> Result<Vec<Reaction>, ForgejoError> {
+ let request = self
+ .get(&format!(
+ "repos/{owner}/{repo}/issues/comments/{id}/reactions"
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Add a reaction to a comment of an issue
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `id`: id of the comment to edit
+ /// - `content`: See [`EditReactionOption`]
+ pub async fn issue_post_comment_reaction(
+ &self,
+ owner: &str,
+ repo: &str,
+ id: u64,
+ content: EditReactionOption,
+ ) -> Result<Reaction, ForgejoError> {
+ let request = self
+ .post(&format!(
+ "repos/{owner}/{repo}/issues/comments/{id}/reactions"
+ ))
+ .json(&content)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Remove a reaction from a comment of an issue
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `id`: id of the comment to edit
+ /// - `content`: See [`EditReactionOption`]
+ pub async fn issue_delete_comment_reaction(
+ &self,
+ owner: &str,
+ repo: &str,
+ id: u64,
+ content: EditReactionOption,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!(
+ "repos/{owner}/{repo}/issues/comments/{id}/reactions"
+ ))
+ .json(&content)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List a repo's pinned issues
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn repo_list_pinned_issues(
+ &self,
+ owner: &str,
+ repo: &str,
+ ) -> Result<Vec<Issue>, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/issues/pinned"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get an issue
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the issue to get
+ pub async fn issue_get_issue(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ ) -> Result<Issue, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/issues/{index}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete an issue
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of issue to delete
+ pub async fn issue_delete(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!("repos/{owner}/{repo}/issues/{index}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Edit an issue. If using deadline only the date will be taken into account, and time of day ignored.
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the issue to edit
+ /// - `body`: See [`EditIssueOption`]
+ pub async fn issue_edit_issue(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ body: EditIssueOption,
+ ) -> Result<Issue, ForgejoError> {
+ let request = self
+ .patch(&format!("repos/{owner}/{repo}/issues/{index}"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List issue's attachments
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the issue
+ pub async fn issue_list_issue_attachments(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ ) -> Result<Vec<Attachment>, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/issues/{index}/assets"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Create an issue attachment
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the issue
+ /// - `attachment`: attachment to upload
+ pub async fn issue_create_issue_attachment(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ attachment: Vec<u8>,
+ query: IssueCreateIssueAttachmentQuery,
+ ) -> Result<Attachment, ForgejoError> {
+ let request = self
+ .post(&format!(
+ "repos/{owner}/{repo}/issues/{index}/assets?{query}"
+ ))
+ .multipart(
+ reqwest::multipart::Form::new().part(
+ "attachment",
+ reqwest::multipart::Part::bytes(attachment)
+ .file_name("file")
+ .mime_str("*/*")
+ .unwrap(),
+ ),
+ )
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get an issue attachment
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the issue
+ /// - `attachment_id`: id of the attachment to get
+ pub async fn issue_get_issue_attachment(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ attachment_id: u64,
+ ) -> Result<Attachment, ForgejoError> {
+ let request = self
+ .get(&format!(
+ "repos/{owner}/{repo}/issues/{index}/assets/{attachment_id}"
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete an issue attachment
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the issue
+ /// - `attachment_id`: id of the attachment to delete
+ pub async fn issue_delete_issue_attachment(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ attachment_id: u64,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!(
+ "repos/{owner}/{repo}/issues/{index}/assets/{attachment_id}"
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Edit an issue attachment
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the issue
+ /// - `attachment_id`: id of the attachment to edit
+ /// - `body`: See [`EditAttachmentOptions`]
+ pub async fn issue_edit_issue_attachment(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ attachment_id: u64,
+ body: EditAttachmentOptions,
+ ) -> Result<Attachment, ForgejoError> {
+ let request = self
+ .patch(&format!(
+ "repos/{owner}/{repo}/issues/{index}/assets/{attachment_id}"
+ ))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List issues that are blocked by this issue
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the issue
+ pub async fn issue_list_blocks(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: &str,
+ query: IssueListBlocksQuery,
+ ) -> Result<Vec<Issue>, ForgejoError> {
+ let request = self
+ .get(&format!(
+ "repos/{owner}/{repo}/issues/{index}/blocks?{query}"
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Block the issue given in the body by the issue in path
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the issue
+ /// - `body`: See [`IssueMeta`]
+ pub async fn issue_create_issue_blocking(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: &str,
+ body: IssueMeta,
+ ) -> Result<Issue, ForgejoError> {
+ let request = self
+ .post(&format!("repos/{owner}/{repo}/issues/{index}/blocks"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Unblock the issue given in the body by the issue in path
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the issue
+ /// - `body`: See [`IssueMeta`]
+ pub async fn issue_remove_issue_blocking(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: &str,
+ body: IssueMeta,
+ ) -> Result<Issue, ForgejoError> {
+ let request = self
+ .delete(&format!("repos/{owner}/{repo}/issues/{index}/blocks"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List all comments on an issue
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the issue
+ pub async fn issue_get_comments(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ query: IssueGetCommentsQuery,
+ ) -> Result<Vec<Comment>, ForgejoError> {
+ let request = self
+ .get(&format!(
+ "repos/{owner}/{repo}/issues/{index}/comments?{query}"
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Add a comment to an issue
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the issue
+ /// - `body`: See [`CreateIssueCommentOption`]
+ pub async fn issue_create_comment(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ body: CreateIssueCommentOption,
+ ) -> Result<Comment, ForgejoError> {
+ let request = self
+ .post(&format!("repos/{owner}/{repo}/issues/{index}/comments"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete a comment
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: this parameter is ignored
+ /// - `id`: id of comment to delete
+ pub async fn issue_delete_comment_deprecated(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u32,
+ id: u64,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!(
+ "repos/{owner}/{repo}/issues/{index}/comments/{id}"
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Edit a comment
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: this parameter is ignored
+ /// - `id`: id of the comment to edit
+ /// - `body`: See [`EditIssueCommentOption`]
+ pub async fn issue_edit_comment_deprecated(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u32,
+ id: u64,
+ body: EditIssueCommentOption,
+ ) -> Result<Option<Comment>, ForgejoError> {
+ let request = self
+ .patch(&format!(
+ "repos/{owner}/{repo}/issues/{index}/comments/{id}"
+ ))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(Some(response.json().await?)),
+ 204 => Ok(None),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Set an issue deadline. If set to null, the deadline is deleted. If using deadline only the date will be taken into account, and time of day ignored.
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the issue to create or update a deadline on
+ /// - `body`: See [`EditDeadlineOption`]
+ pub async fn issue_edit_issue_deadline(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ body: EditDeadlineOption,
+ ) -> Result<IssueDeadline, ForgejoError> {
+ let request = self
+ .post(&format!("repos/{owner}/{repo}/issues/{index}/deadline"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List an issue's dependencies, i.e all issues that block this issue.
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the issue
+ pub async fn issue_list_issue_dependencies(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: &str,
+ query: IssueListIssueDependenciesQuery,
+ ) -> Result<Vec<Issue>, ForgejoError> {
+ let request = self
+ .get(&format!(
+ "repos/{owner}/{repo}/issues/{index}/dependencies?{query}"
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Make the issue in the url depend on the issue in the form.
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the issue
+ /// - `body`: See [`IssueMeta`]
+ pub async fn issue_create_issue_dependencies(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: &str,
+ body: IssueMeta,
+ ) -> Result<Issue, ForgejoError> {
+ let request = self
+ .post(&format!("repos/{owner}/{repo}/issues/{index}/dependencies"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Remove an issue dependency
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the issue
+ /// - `body`: See [`IssueMeta`]
+ pub async fn issue_remove_issue_dependencies(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: &str,
+ body: IssueMeta,
+ ) -> Result<Issue, ForgejoError> {
+ let request = self
+ .delete(&format!("repos/{owner}/{repo}/issues/{index}/dependencies"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get an issue's labels
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the issue
+ pub async fn issue_get_labels(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ ) -> Result<Vec<Label>, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/issues/{index}/labels"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Replace an issue's labels
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the issue
+ /// - `body`: See [`IssueLabelsOption`]
+ pub async fn issue_replace_labels(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ body: IssueLabelsOption,
+ ) -> Result<Vec<Label>, ForgejoError> {
+ let request = self
+ .put(&format!("repos/{owner}/{repo}/issues/{index}/labels"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Add a label to an issue
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the issue
+ /// - `body`: See [`IssueLabelsOption`]
+ pub async fn issue_add_label(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ body: IssueLabelsOption,
+ ) -> Result<Vec<Label>, ForgejoError> {
+ let request = self
+ .post(&format!("repos/{owner}/{repo}/issues/{index}/labels"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Remove all labels from an issue
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the issue
+ /// - `body`: See [`DeleteLabelsOption`]
+ pub async fn issue_clear_labels(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ body: DeleteLabelsOption,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!("repos/{owner}/{repo}/issues/{index}/labels"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Remove a label from an issue
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the issue
+ /// - `id`: id of the label to remove
+ /// - `body`: See [`DeleteLabelsOption`]
+ pub async fn issue_remove_label(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ id: u64,
+ body: DeleteLabelsOption,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!("repos/{owner}/{repo}/issues/{index}/labels/{id}"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Pin an Issue
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of issue to pin
+ pub async fn pin_issue(&self, owner: &str, repo: &str, index: u64) -> Result<(), ForgejoError> {
+ let request = self
+ .post(&format!("repos/{owner}/{repo}/issues/{index}/pin"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Unpin an Issue
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of issue to unpin
+ pub async fn unpin_issue(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!("repos/{owner}/{repo}/issues/{index}/pin"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Moves the Pin to the given Position
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of issue
+ /// - `position`: the new position
+ pub async fn move_issue_pin(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ position: u64,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .patch(&format!(
+ "repos/{owner}/{repo}/issues/{index}/pin/{position}"
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get a list reactions of an issue
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the issue
+ pub async fn issue_get_issue_reactions(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ query: IssueGetIssueReactionsQuery,
+ ) -> Result<Vec<Reaction>, ForgejoError> {
+ let request = self
+ .get(&format!(
+ "repos/{owner}/{repo}/issues/{index}/reactions?{query}"
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Add a reaction to an issue
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the issue
+ /// - `content`: See [`EditReactionOption`]
+ pub async fn issue_post_issue_reaction(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ content: EditReactionOption,
+ ) -> Result<Reaction, ForgejoError> {
+ let request = self
+ .post(&format!("repos/{owner}/{repo}/issues/{index}/reactions"))
+ .json(&content)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Remove a reaction from an issue
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the issue
+ /// - `content`: See [`EditReactionOption`]
+ pub async fn issue_delete_issue_reaction(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ content: EditReactionOption,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!("repos/{owner}/{repo}/issues/{index}/reactions"))
+ .json(&content)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete an issue's existing stopwatch.
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the issue to stop the stopwatch on
+ pub async fn issue_delete_stop_watch(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!(
+ "repos/{owner}/{repo}/issues/{index}/stopwatch/delete"
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Start stopwatch on an issue.
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the issue to create the stopwatch on
+ pub async fn issue_start_stop_watch(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .post(&format!(
+ "repos/{owner}/{repo}/issues/{index}/stopwatch/start"
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Stop an issue's existing stopwatch.
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the issue to stop the stopwatch on
+ pub async fn issue_stop_stop_watch(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .post(&format!(
+ "repos/{owner}/{repo}/issues/{index}/stopwatch/stop"
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get users who subscribed on an issue.
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the issue
+ pub async fn issue_subscriptions(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ query: IssueSubscriptionsQuery,
+ ) -> Result<Vec<User>, ForgejoError> {
+ let request = self
+ .get(&format!(
+ "repos/{owner}/{repo}/issues/{index}/subscriptions?{query}"
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Check if user is subscribed to an issue
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the issue
+ pub async fn issue_check_subscription(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ ) -> Result<WatchInfo, ForgejoError> {
+ let request = self
+ .get(&format!(
+ "repos/{owner}/{repo}/issues/{index}/subscriptions/check"
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Subscribe user to issue
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the issue
+ /// - `user`: user to subscribe
+ pub async fn issue_add_subscription(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ user: &str,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .put(&format!(
+ "repos/{owner}/{repo}/issues/{index}/subscriptions/{user}"
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(()),
+ 201 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Unsubscribe user from issue
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the issue
+ /// - `user`: user witch unsubscribe
+ pub async fn issue_delete_subscription(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ user: &str,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!(
+ "repos/{owner}/{repo}/issues/{index}/subscriptions/{user}"
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(()),
+ 201 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List all comments and events on an issue
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the issue
+ pub async fn issue_get_comments_and_timeline(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ query: IssueGetCommentsAndTimelineQuery,
+ ) -> Result<Vec<TimelineComment>, ForgejoError> {
+ let request = self
+ .get(&format!(
+ "repos/{owner}/{repo}/issues/{index}/timeline?{query}"
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List an issue's tracked times
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the issue
+ pub async fn issue_tracked_times(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ query: IssueTrackedTimesQuery,
+ ) -> Result<Vec<TrackedTime>, ForgejoError> {
+ let request = self
+ .get(&format!(
+ "repos/{owner}/{repo}/issues/{index}/times?{query}"
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Add tracked time to a issue
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the issue
+ /// - `body`: See [`AddTimeOption`]
+ pub async fn issue_add_time(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ body: AddTimeOption,
+ ) -> Result<TrackedTime, ForgejoError> {
+ let request = self
+ .post(&format!("repos/{owner}/{repo}/issues/{index}/times"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Reset a tracked time of an issue
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the issue to add tracked time to
+ pub async fn issue_reset_time(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!("repos/{owner}/{repo}/issues/{index}/times"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete specific tracked time
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the issue
+ /// - `id`: id of time to delete
+ pub async fn issue_delete_time(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ id: u64,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!("repos/{owner}/{repo}/issues/{index}/times/{id}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List a repository's keys
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn repo_list_keys(
+ &self,
+ owner: &str,
+ repo: &str,
+ query: RepoListKeysQuery,
+ ) -> Result<Vec<DeployKey>, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/keys?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Add a key to a repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `body`: See [`CreateKeyOption`]
+ pub async fn repo_create_key(
+ &self,
+ owner: &str,
+ repo: &str,
+ body: CreateKeyOption,
+ ) -> Result<DeployKey, ForgejoError> {
+ let request = self
+ .post(&format!("repos/{owner}/{repo}/keys"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get a repository's key by id
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `id`: id of the key to get
+ pub async fn repo_get_key(
+ &self,
+ owner: &str,
+ repo: &str,
+ id: u64,
+ ) -> Result<DeployKey, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/keys/{id}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete a key from a repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `id`: id of the key to delete
+ pub async fn repo_delete_key(
+ &self,
+ owner: &str,
+ repo: &str,
+ id: u64,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!("repos/{owner}/{repo}/keys/{id}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get all of a repository's labels
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn issue_list_labels(
+ &self,
+ owner: &str,
+ repo: &str,
+ query: IssueListLabelsQuery,
+ ) -> Result<Vec<Label>, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/labels?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Create a label
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `body`: See [`CreateLabelOption`]
+ pub async fn issue_create_label(
+ &self,
+ owner: &str,
+ repo: &str,
+ body: CreateLabelOption,
+ ) -> Result<Label, ForgejoError> {
+ let request = self
+ .post(&format!("repos/{owner}/{repo}/labels"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get a single label
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `id`: id of the label to get
+ pub async fn issue_get_label(
+ &self,
+ owner: &str,
+ repo: &str,
+ id: u64,
+ ) -> Result<Label, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/labels/{id}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete a label
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `id`: id of the label to delete
+ pub async fn issue_delete_label(
+ &self,
+ owner: &str,
+ repo: &str,
+ id: u64,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!("repos/{owner}/{repo}/labels/{id}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Update a label
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `id`: id of the label to edit
+ /// - `body`: See [`EditLabelOption`]
+ pub async fn issue_edit_label(
+ &self,
+ owner: &str,
+ repo: &str,
+ id: u64,
+ body: EditLabelOption,
+ ) -> Result<Label, ForgejoError> {
+ let request = self
+ .patch(&format!("repos/{owner}/{repo}/labels/{id}"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get languages and number of bytes of code written
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn repo_get_languages(
+ &self,
+ owner: &str,
+ repo: &str,
+ ) -> Result<BTreeMap<String, i64>, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/languages"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get a file or it's LFS object from a repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `filepath`: filepath of the file to get
+ pub async fn repo_get_raw_file_or_lfs(
+ &self,
+ owner: &str,
+ repo: &str,
+ filepath: &str,
+ query: RepoGetRawFileOrLfsQuery,
+ ) -> Result<Vec<u8>, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/media/{filepath}?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.bytes().await?[..].to_vec()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get all of a repository's opened milestones
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn issue_get_milestones_list(
+ &self,
+ owner: &str,
+ repo: &str,
+ query: IssueGetMilestonesListQuery,
+ ) -> Result<Vec<Milestone>, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/milestones?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Create a milestone
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `body`: See [`CreateMilestoneOption`]
+ pub async fn issue_create_milestone(
+ &self,
+ owner: &str,
+ repo: &str,
+ body: CreateMilestoneOption,
+ ) -> Result<Milestone, ForgejoError> {
+ let request = self
+ .post(&format!("repos/{owner}/{repo}/milestones"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get a milestone
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `id`: the milestone to get, identified by ID and if not available by name
+ pub async fn issue_get_milestone(
+ &self,
+ owner: &str,
+ repo: &str,
+ id: &str,
+ ) -> Result<Milestone, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/milestones/{id}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete a milestone
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `id`: the milestone to delete, identified by ID and if not available by name
+ pub async fn issue_delete_milestone(
+ &self,
+ owner: &str,
+ repo: &str,
+ id: &str,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!("repos/{owner}/{repo}/milestones/{id}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Update a milestone
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `id`: the milestone to edit, identified by ID and if not available by name
+ /// - `body`: See [`EditMilestoneOption`]
+ pub async fn issue_edit_milestone(
+ &self,
+ owner: &str,
+ repo: &str,
+ id: &str,
+ body: EditMilestoneOption,
+ ) -> Result<Milestone, ForgejoError> {
+ let request = self
+ .patch(&format!("repos/{owner}/{repo}/milestones/{id}"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Sync a mirrored repository
+ ///
+ /// - `owner`: owner of the repo to sync
+ /// - `repo`: name of the repo to sync
+ pub async fn repo_mirror_sync(&self, owner: &str, repo: &str) -> Result<(), ForgejoError> {
+ let request = self
+ .post(&format!("repos/{owner}/{repo}/mirror-sync"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Returns if new Issue Pins are allowed
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn repo_new_pin_allowed(
+ &self,
+ owner: &str,
+ repo: &str,
+ ) -> Result<NewIssuePinsAllowed, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/new_pin_allowed"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List users's notification threads on a specific repo
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn notify_get_repo_list(
+ &self,
+ owner: &str,
+ repo: &str,
+ query: NotifyGetRepoListQuery,
+ ) -> Result<Vec<NotificationThread>, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/notifications?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Mark notification threads as read, pinned or unread on a specific repo
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn notify_read_repo_list(
+ &self,
+ owner: &str,
+ repo: &str,
+ query: NotifyReadRepoListQuery,
+ ) -> Result<Vec<NotificationThread>, ForgejoError> {
+ let request = self
+ .put(&format!("repos/{owner}/{repo}/notifications?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 205 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List a repo's pull requests
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn repo_list_pull_requests(
+ &self,
+ owner: &str,
+ repo: &str,
+ query: RepoListPullRequestsQuery,
+ ) -> Result<Vec<PullRequest>, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/pulls?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Create a pull request
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `body`: See [`CreatePullRequestOption`]
+ pub async fn repo_create_pull_request(
+ &self,
+ owner: &str,
+ repo: &str,
+ body: CreatePullRequestOption,
+ ) -> Result<PullRequest, ForgejoError> {
+ let request = self
+ .post(&format!("repos/{owner}/{repo}/pulls"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List a repo's pinned pull requests
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn repo_list_pinned_pull_requests(
+ &self,
+ owner: &str,
+ repo: &str,
+ ) -> Result<Vec<PullRequest>, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/pulls/pinned"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get a pull request by base and head
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `base`: base of the pull request to get
+ /// - `head`: head of the pull request to get
+ pub async fn repo_get_pull_request_by_base_head(
+ &self,
+ owner: &str,
+ repo: &str,
+ base: &str,
+ head: &str,
+ ) -> Result<PullRequest, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/pulls/{base}/{head}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get a pull request
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the pull request to get
+ pub async fn repo_get_pull_request(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ ) -> Result<PullRequest, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/pulls/{index}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Update a pull request. If using deadline only the date will be taken into account, and time of day ignored.
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the pull request to edit
+ /// - `body`: See [`EditPullRequestOption`]
+ pub async fn repo_edit_pull_request(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ body: EditPullRequestOption,
+ ) -> Result<PullRequest, ForgejoError> {
+ let request = self
+ .patch(&format!("repos/{owner}/{repo}/pulls/{index}"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get a pull request diff or patch
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the pull request to get
+ /// - `diffType`: whether the output is diff or patch
+ pub async fn repo_download_pull_diff_or_patch(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ diff_type: &str,
+ query: RepoDownloadPullDiffOrPatchQuery,
+ ) -> Result<String, ForgejoError> {
+ let request = self
+ .get(&format!(
+ "repos/{owner}/{repo}/pulls/{index}.{diff_type}?{query}"
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.text().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get commits for a pull request
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the pull request to get
+ pub async fn repo_get_pull_request_commits(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ query: RepoGetPullRequestCommitsQuery,
+ ) -> Result<(CommitListHeaders, Vec<Commit>), ForgejoError> {
+ let request = self
+ .get(&format!(
+ "repos/{owner}/{repo}/pulls/{index}/commits?{query}"
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok((response.headers().try_into()?, response.json().await?)),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get changed files for a pull request
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the pull request to get
+ pub async fn repo_get_pull_request_files(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ query: RepoGetPullRequestFilesQuery,
+ ) -> Result<(ChangedFileListHeaders, Vec<ChangedFile>), ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/pulls/{index}/files?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok((response.headers().try_into()?, response.json().await?)),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Check if a pull request has been merged
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the pull request
+ pub async fn repo_pull_request_is_merged(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/pulls/{index}/merge"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Merge a pull request
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the pull request to merge
+ /// - `body`: See [`MergePullRequestOption`]
+ pub async fn repo_merge_pull_request(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ body: MergePullRequestOption,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .post(&format!("repos/{owner}/{repo}/pulls/{index}/merge"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Cancel the scheduled auto merge for the given pull request
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the pull request to merge
+ pub async fn repo_cancel_scheduled_auto_merge(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!("repos/{owner}/{repo}/pulls/{index}/merge"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// create review requests for a pull request
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the pull request
+ /// - `body`: See [`PullReviewRequestOptions`]
+ pub async fn repo_create_pull_review_requests(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ body: PullReviewRequestOptions,
+ ) -> Result<Vec<PullReview>, ForgejoError> {
+ let request = self
+ .post(&format!(
+ "repos/{owner}/{repo}/pulls/{index}/requested_reviewers"
+ ))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// cancel review requests for a pull request
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the pull request
+ /// - `body`: See [`PullReviewRequestOptions`]
+ pub async fn repo_delete_pull_review_requests(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ body: PullReviewRequestOptions,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!(
+ "repos/{owner}/{repo}/pulls/{index}/requested_reviewers"
+ ))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List all reviews for a pull request
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the pull request
+ pub async fn repo_list_pull_reviews(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ query: RepoListPullReviewsQuery,
+ ) -> Result<Vec<PullReview>, ForgejoError> {
+ let request = self
+ .get(&format!(
+ "repos/{owner}/{repo}/pulls/{index}/reviews?{query}"
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Create a review to an pull request
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the pull request
+ /// - `body`: See [`CreatePullReviewOptions`]
+ pub async fn repo_create_pull_review(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ body: CreatePullReviewOptions,
+ ) -> Result<PullReview, ForgejoError> {
+ let request = self
+ .post(&format!("repos/{owner}/{repo}/pulls/{index}/reviews"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get a specific review for a pull request
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the pull request
+ /// - `id`: id of the review
+ pub async fn repo_get_pull_review(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ id: u64,
+ ) -> Result<PullReview, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/pulls/{index}/reviews/{id}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Submit a pending review to an pull request
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the pull request
+ /// - `id`: id of the review
+ /// - `body`: See [`SubmitPullReviewOptions`]
+ pub async fn repo_submit_pull_review(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ id: u64,
+ body: SubmitPullReviewOptions,
+ ) -> Result<PullReview, ForgejoError> {
+ let request = self
+ .post(&format!("repos/{owner}/{repo}/pulls/{index}/reviews/{id}"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete a specific review from a pull request
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the pull request
+ /// - `id`: id of the review
+ pub async fn repo_delete_pull_review(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ id: u64,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!("repos/{owner}/{repo}/pulls/{index}/reviews/{id}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get a specific review for a pull request
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the pull request
+ /// - `id`: id of the review
+ pub async fn repo_get_pull_review_comments(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ id: u64,
+ ) -> Result<Vec<PullReviewComment>, ForgejoError> {
+ let request = self
+ .get(&format!(
+ "repos/{owner}/{repo}/pulls/{index}/reviews/{id}/comments"
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Add a new comment to a pull request review
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the pull request
+ /// - `id`: id of the review
+ /// - `body`: See [`serde_json::Value`]
+ pub async fn repo_create_pull_review_comment(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ id: u64,
+ body: serde_json::Value,
+ ) -> Result<PullReviewComment, ForgejoError> {
+ let request = self
+ .post(&format!(
+ "repos/{owner}/{repo}/pulls/{index}/reviews/{id}/comments"
+ ))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get a pull review comment
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the pull request
+ /// - `id`: id of the review
+ /// - `comment`: id of the comment
+ pub async fn repo_get_pull_review_comment(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ id: u64,
+ comment: u64,
+ ) -> Result<PullReviewComment, ForgejoError> {
+ let request = self
+ .get(&format!(
+ "repos/{owner}/{repo}/pulls/{index}/reviews/{id}/comments/{comment}"
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete a pull review comment
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the pull request
+ /// - `id`: id of the review
+ /// - `comment`: id of the comment
+ pub async fn repo_delete_pull_review_comment(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ id: u64,
+ comment: u64,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!(
+ "repos/{owner}/{repo}/pulls/{index}/reviews/{id}/comments/{comment}"
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Dismiss a review for a pull request
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the pull request
+ /// - `id`: id of the review
+ /// - `body`: See [`DismissPullReviewOptions`]
+ pub async fn repo_dismiss_pull_review(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ id: u64,
+ body: DismissPullReviewOptions,
+ ) -> Result<PullReview, ForgejoError> {
+ let request = self
+ .post(&format!(
+ "repos/{owner}/{repo}/pulls/{index}/reviews/{id}/dismissals"
+ ))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Cancel to dismiss a review for a pull request
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the pull request
+ /// - `id`: id of the review
+ pub async fn repo_un_dismiss_pull_review(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ id: u64,
+ ) -> Result<PullReview, ForgejoError> {
+ let request = self
+ .post(&format!(
+ "repos/{owner}/{repo}/pulls/{index}/reviews/{id}/undismissals"
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Merge PR's baseBranch into headBranch
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `index`: index of the pull request to get
+ pub async fn repo_update_pull_request(
+ &self,
+ owner: &str,
+ repo: &str,
+ index: u64,
+ query: RepoUpdatePullRequestQuery,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .post(&format!(
+ "repos/{owner}/{repo}/pulls/{index}/update?{query}"
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get all push mirrors of the repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn repo_list_push_mirrors(
+ &self,
+ owner: &str,
+ repo: &str,
+ query: RepoListPushMirrorsQuery,
+ ) -> Result<Vec<PushMirror>, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/push_mirrors?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// add a push mirror to the repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `body`: See [`CreatePushMirrorOption`]
+ pub async fn repo_add_push_mirror(
+ &self,
+ owner: &str,
+ repo: &str,
+ body: CreatePushMirrorOption,
+ ) -> Result<PushMirror, ForgejoError> {
+ let request = self
+ .post(&format!("repos/{owner}/{repo}/push_mirrors"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Sync all push mirrored repository
+ ///
+ /// - `owner`: owner of the repo to sync
+ /// - `repo`: name of the repo to sync
+ pub async fn repo_push_mirror_sync(&self, owner: &str, repo: &str) -> Result<(), ForgejoError> {
+ let request = self
+ .post(&format!("repos/{owner}/{repo}/push_mirrors-sync"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get push mirror of the repository by remoteName
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `name`: remote name of push mirror
+ pub async fn repo_get_push_mirror_by_remote_name(
+ &self,
+ owner: &str,
+ repo: &str,
+ name: &str,
+ ) -> Result<PushMirror, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/push_mirrors/{name}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// deletes a push mirror from a repository by remoteName
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `name`: remote name of the pushMirror
+ pub async fn repo_delete_push_mirror(
+ &self,
+ owner: &str,
+ repo: &str,
+ name: &str,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!("repos/{owner}/{repo}/push_mirrors/{name}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get a file from a repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `filepath`: filepath of the file to get
+ pub async fn repo_get_raw_file(
+ &self,
+ owner: &str,
+ repo: &str,
+ filepath: &str,
+ query: RepoGetRawFileQuery,
+ ) -> Result<Vec<u8>, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/raw/{filepath}?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.bytes().await?[..].to_vec()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List a repo's releases
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn repo_list_releases(
+ &self,
+ owner: &str,
+ repo: &str,
+ query: RepoListReleasesQuery,
+ ) -> Result<Vec<Release>, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/releases?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Create a release
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `body`: See [`CreateReleaseOption`]
+ pub async fn repo_create_release(
+ &self,
+ owner: &str,
+ repo: &str,
+ body: CreateReleaseOption,
+ ) -> Result<Release, ForgejoError> {
+ let request = self
+ .post(&format!("repos/{owner}/{repo}/releases"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Gets the most recent non-prerelease, non-draft release of a repository, sorted by created_at
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn repo_get_latest_release(
+ &self,
+ owner: &str,
+ repo: &str,
+ ) -> Result<Release, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/releases/latest"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get a release by tag name
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `tag`: tag name of the release to get
+ pub async fn repo_get_release_by_tag(
+ &self,
+ owner: &str,
+ repo: &str,
+ tag: &str,
+ ) -> Result<Release, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/releases/tags/{tag}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete a release by tag name
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `tag`: tag name of the release to delete
+ pub async fn repo_delete_release_by_tag(
+ &self,
+ owner: &str,
+ repo: &str,
+ tag: &str,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!("repos/{owner}/{repo}/releases/tags/{tag}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get a release
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `id`: id of the release to get
+ pub async fn repo_get_release(
+ &self,
+ owner: &str,
+ repo: &str,
+ id: u64,
+ ) -> Result<Release, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/releases/{id}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete a release
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `id`: id of the release to delete
+ pub async fn repo_delete_release(
+ &self,
+ owner: &str,
+ repo: &str,
+ id: u64,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!("repos/{owner}/{repo}/releases/{id}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Update a release
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `id`: id of the release to edit
+ /// - `body`: See [`EditReleaseOption`]
+ pub async fn repo_edit_release(
+ &self,
+ owner: &str,
+ repo: &str,
+ id: u64,
+ body: EditReleaseOption,
+ ) -> Result<Release, ForgejoError> {
+ let request = self
+ .patch(&format!("repos/{owner}/{repo}/releases/{id}"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List release's attachments
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `id`: id of the release
+ pub async fn repo_list_release_attachments(
+ &self,
+ owner: &str,
+ repo: &str,
+ id: u64,
+ ) -> Result<Vec<Attachment>, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/releases/{id}/assets"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Create a release attachment
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `id`: id of the release
+ /// - `attachment`: attachment to upload
+ pub async fn repo_create_release_attachment(
+ &self,
+ owner: &str,
+ repo: &str,
+ id: u64,
+ attachment: Vec<u8>,
+ query: RepoCreateReleaseAttachmentQuery,
+ ) -> Result<Attachment, ForgejoError> {
+ let request = self
+ .post(&format!(
+ "repos/{owner}/{repo}/releases/{id}/assets?{query}"
+ ))
+ .multipart(
+ reqwest::multipart::Form::new().part(
+ "attachment",
+ reqwest::multipart::Part::bytes(attachment)
+ .file_name("file")
+ .mime_str("*/*")
+ .unwrap(),
+ ),
+ )
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get a release attachment
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `id`: id of the release
+ /// - `attachment_id`: id of the attachment to get
+ pub async fn repo_get_release_attachment(
+ &self,
+ owner: &str,
+ repo: &str,
+ id: u64,
+ attachment_id: u64,
+ ) -> Result<Attachment, ForgejoError> {
+ let request = self
+ .get(&format!(
+ "repos/{owner}/{repo}/releases/{id}/assets/{attachment_id}"
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete a release attachment
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `id`: id of the release
+ /// - `attachment_id`: id of the attachment to delete
+ pub async fn repo_delete_release_attachment(
+ &self,
+ owner: &str,
+ repo: &str,
+ id: u64,
+ attachment_id: u64,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!(
+ "repos/{owner}/{repo}/releases/{id}/assets/{attachment_id}"
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Edit a release attachment
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `id`: id of the release
+ /// - `attachment_id`: id of the attachment to edit
+ /// - `body`: See [`EditAttachmentOptions`]
+ pub async fn repo_edit_release_attachment(
+ &self,
+ owner: &str,
+ repo: &str,
+ id: u64,
+ attachment_id: u64,
+ body: EditAttachmentOptions,
+ ) -> Result<Attachment, ForgejoError> {
+ let request = self
+ .patch(&format!(
+ "repos/{owner}/{repo}/releases/{id}/assets/{attachment_id}"
+ ))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Return all users that can be requested to review in this repo
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn repo_get_reviewers(
+ &self,
+ owner: &str,
+ repo: &str,
+ ) -> Result<Vec<User>, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/reviewers"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get a repository's actions runner registration token
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn repo_get_runner_registration_token(
+ &self,
+ owner: &str,
+ repo: &str,
+ ) -> Result<RegistrationTokenHeaders, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/runners/registration-token"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.headers().try_into()?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get signing-key.gpg for given repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn repo_signing_key(&self, owner: &str, repo: &str) -> Result<String, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/signing-key.gpg"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.text().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List a repo's stargazers
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn repo_list_stargazers(
+ &self,
+ owner: &str,
+ repo: &str,
+ query: RepoListStargazersQuery,
+ ) -> Result<Vec<User>, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/stargazers?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get a commit's statuses
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `sha`: sha of the commit
+ pub async fn repo_list_statuses(
+ &self,
+ owner: &str,
+ repo: &str,
+ sha: &str,
+ query: RepoListStatusesQuery,
+ ) -> Result<Vec<CommitStatus>, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/statuses/{sha}?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Create a commit status
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `sha`: sha of the commit
+ /// - `body`: See [`CreateStatusOption`]
+ pub async fn repo_create_status(
+ &self,
+ owner: &str,
+ repo: &str,
+ sha: &str,
+ body: CreateStatusOption,
+ ) -> Result<CommitStatus, ForgejoError> {
+ let request = self
+ .post(&format!("repos/{owner}/{repo}/statuses/{sha}"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List a repo's watchers
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn repo_list_subscribers(
+ &self,
+ owner: &str,
+ repo: &str,
+ query: RepoListSubscribersQuery,
+ ) -> Result<Vec<User>, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/subscribers?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Check if the current user is watching a repo
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn user_current_check_subscription(
+ &self,
+ owner: &str,
+ repo: &str,
+ ) -> Result<WatchInfo, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/subscription"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Watch a repo
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn user_current_put_subscription(
+ &self,
+ owner: &str,
+ repo: &str,
+ ) -> Result<WatchInfo, ForgejoError> {
+ let request = self
+ .put(&format!("repos/{owner}/{repo}/subscription"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Unwatch a repo
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn user_current_delete_subscription(
+ &self,
+ owner: &str,
+ repo: &str,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!("repos/{owner}/{repo}/subscription"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List tag protections for a repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn repo_list_tag_protection(
+ &self,
+ owner: &str,
+ repo: &str,
+ ) -> Result<Vec<TagProtection>, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/tag_protections"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Create a tag protections for a repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `body`: See [`CreateTagProtectionOption`]
+ pub async fn repo_create_tag_protection(
+ &self,
+ owner: &str,
+ repo: &str,
+ body: CreateTagProtectionOption,
+ ) -> Result<TagProtection, ForgejoError> {
+ let request = self
+ .post(&format!("repos/{owner}/{repo}/tag_protections"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get a specific tag protection for the repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `id`: id of the tag protect to get
+ pub async fn repo_get_tag_protection(
+ &self,
+ owner: &str,
+ repo: &str,
+ id: u32,
+ ) -> Result<TagProtection, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/tag_protections/{id}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete a specific tag protection for the repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `id`: id of protected tag
+ pub async fn repo_delete_tag_protection(
+ &self,
+ owner: &str,
+ repo: &str,
+ id: u32,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!("repos/{owner}/{repo}/tag_protections/{id}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Edit a tag protections for a repository. Only fields that are set will be changed
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `id`: id of protected tag
+ /// - `body`: See [`EditTagProtectionOption`]
+ pub async fn repo_edit_tag_protection(
+ &self,
+ owner: &str,
+ repo: &str,
+ id: u32,
+ body: EditTagProtectionOption,
+ ) -> Result<TagProtection, ForgejoError> {
+ let request = self
+ .patch(&format!("repos/{owner}/{repo}/tag_protections/{id}"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List a repository's tags
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn repo_list_tags(
+ &self,
+ owner: &str,
+ repo: &str,
+ query: RepoListTagsQuery,
+ ) -> Result<Vec<Tag>, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/tags?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Create a new git tag in a repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `body`: See [`CreateTagOption`]
+ pub async fn repo_create_tag(
+ &self,
+ owner: &str,
+ repo: &str,
+ body: CreateTagOption,
+ ) -> Result<Tag, ForgejoError> {
+ let request = self
+ .post(&format!("repos/{owner}/{repo}/tags"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get the tag of a repository by tag name
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `tag`: name of tag
+ pub async fn repo_get_tag(
+ &self,
+ owner: &str,
+ repo: &str,
+ tag: &str,
+ ) -> Result<Tag, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/tags/{tag}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete a repository's tag by name
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `tag`: name of tag to delete
+ pub async fn repo_delete_tag(
+ &self,
+ owner: &str,
+ repo: &str,
+ tag: &str,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!("repos/{owner}/{repo}/tags/{tag}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List a repository's teams
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn repo_list_teams(
+ &self,
+ owner: &str,
+ repo: &str,
+ ) -> Result<Vec<Team>, ForgejoError> {
+ let request = self.get(&format!("repos/{owner}/{repo}/teams")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Check if a team is assigned to a repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `team`: team name
+ pub async fn repo_check_team(
+ &self,
+ owner: &str,
+ repo: &str,
+ team: &str,
+ ) -> Result<Team, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/teams/{team}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Add a team to a repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `team`: team name
+ pub async fn repo_add_team(
+ &self,
+ owner: &str,
+ repo: &str,
+ team: &str,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .put(&format!("repos/{owner}/{repo}/teams/{team}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete a team from a repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `team`: team name
+ pub async fn repo_delete_team(
+ &self,
+ owner: &str,
+ repo: &str,
+ team: &str,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!("repos/{owner}/{repo}/teams/{team}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List a repo's tracked times
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn repo_tracked_times(
+ &self,
+ owner: &str,
+ repo: &str,
+ query: RepoTrackedTimesQuery,
+ ) -> Result<Vec<TrackedTime>, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/times?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List a user's tracked times in a repo
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `user`: username of user
+ pub async fn user_tracked_times(
+ &self,
+ owner: &str,
+ repo: &str,
+ user: &str,
+ ) -> Result<Vec<TrackedTime>, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/times/{user}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get list of topics that a repository has
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn repo_list_topics(
+ &self,
+ owner: &str,
+ repo: &str,
+ query: RepoListTopicsQuery,
+ ) -> Result<TopicName, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/topics?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Replace list of topics for a repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `body`: See [`RepoTopicOptions`]
+ pub async fn repo_update_topics(
+ &self,
+ owner: &str,
+ repo: &str,
+ body: RepoTopicOptions,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .put(&format!("repos/{owner}/{repo}/topics"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Add a topic to a repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `topic`: name of the topic to add
+ pub async fn repo_add_topic(
+ &self,
+ owner: &str,
+ repo: &str,
+ topic: &str,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .put(&format!("repos/{owner}/{repo}/topics/{topic}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete a topic from a repository
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `topic`: name of the topic to delete
+ pub async fn repo_delete_topic(
+ &self,
+ owner: &str,
+ repo: &str,
+ topic: &str,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!("repos/{owner}/{repo}/topics/{topic}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Transfer a repo ownership
+ ///
+ /// - `owner`: owner of the repo to transfer
+ /// - `repo`: name of the repo to transfer
+ /// - `body`: Transfer Options
+
+ /// See [`TransferRepoOption`]
+ pub async fn repo_transfer(
+ &self,
+ owner: &str,
+ repo: &str,
+ body: TransferRepoOption,
+ ) -> Result<Repository, ForgejoError> {
+ let request = self
+ .post(&format!("repos/{owner}/{repo}/transfer"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 202 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Accept a repo transfer
+ ///
+ /// - `owner`: owner of the repo to transfer
+ /// - `repo`: name of the repo to transfer
+ pub async fn accept_repo_transfer(
+ &self,
+ owner: &str,
+ repo: &str,
+ ) -> Result<Repository, ForgejoError> {
+ let request = self
+ .post(&format!("repos/{owner}/{repo}/transfer/accept"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 202 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Reject a repo transfer
+ ///
+ /// - `owner`: owner of the repo to transfer
+ /// - `repo`: name of the repo to transfer
+ pub async fn reject_repo_transfer(
+ &self,
+ owner: &str,
+ repo: &str,
+ ) -> Result<Repository, ForgejoError> {
+ let request = self
+ .post(&format!("repos/{owner}/{repo}/transfer/reject"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Create a wiki page
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `body`: See [`CreateWikiPageOptions`]
+ pub async fn repo_create_wiki_page(
+ &self,
+ owner: &str,
+ repo: &str,
+ body: CreateWikiPageOptions,
+ ) -> Result<WikiPage, ForgejoError> {
+ let request = self
+ .post(&format!("repos/{owner}/{repo}/wiki/new"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get a wiki page
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `pageName`: name of the page
+ pub async fn repo_get_wiki_page(
+ &self,
+ owner: &str,
+ repo: &str,
+ page_name: &str,
+ ) -> Result<WikiPage, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/wiki/page/{page_name}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete a wiki page
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `pageName`: name of the page
+ pub async fn repo_delete_wiki_page(
+ &self,
+ owner: &str,
+ repo: &str,
+ page_name: &str,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!("repos/{owner}/{repo}/wiki/page/{page_name}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Edit a wiki page
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `pageName`: name of the page
+ /// - `body`: See [`CreateWikiPageOptions`]
+ pub async fn repo_edit_wiki_page(
+ &self,
+ owner: &str,
+ repo: &str,
+ page_name: &str,
+ body: CreateWikiPageOptions,
+ ) -> Result<WikiPage, ForgejoError> {
+ let request = self
+ .patch(&format!("repos/{owner}/{repo}/wiki/page/{page_name}"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get all wiki pages
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn repo_get_wiki_pages(
+ &self,
+ owner: &str,
+ repo: &str,
+ query: RepoGetWikiPagesQuery,
+ ) -> Result<Vec<WikiPageMetaData>, ForgejoError> {
+ let request = self
+ .get(&format!("repos/{owner}/{repo}/wiki/pages?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get revisions of a wiki page
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ /// - `pageName`: name of the page
+ pub async fn repo_get_wiki_page_revisions(
+ &self,
+ owner: &str,
+ repo: &str,
+ page_name: &str,
+ query: RepoGetWikiPageRevisionsQuery,
+ ) -> Result<WikiCommitList, ForgejoError> {
+ let request = self
+ .get(&format!(
+ "repos/{owner}/{repo}/wiki/revisions/{page_name}?{query}"
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Create a repository using a template
+ ///
+ /// - `template_owner`: name of the template repository owner
+ /// - `template_repo`: name of the template repository
+ /// - `body`: See [`GenerateRepoOption`]
+ pub async fn generate_repo(
+ &self,
+ template_owner: &str,
+ template_repo: &str,
+ body: GenerateRepoOption,
+ ) -> Result<Repository, ForgejoError> {
+ let request = self
+ .post(&format!("repos/{template_owner}/{template_repo}/generate"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get a repository by id
+ ///
+ /// - `id`: id of the repo to get
+ pub async fn repo_get_by_id(&self, id: u64) -> Result<Repository, ForgejoError> {
+ let request = self.get(&format!("repositories/{id}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get instance's global settings for api
+ pub async fn get_general_api_settings(&self) -> Result<GeneralAPISettings, ForgejoError> {
+ let request = self.get("settings/api").build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get instance's global settings for Attachment
+ pub async fn get_general_attachment_settings(
+ &self,
+ ) -> Result<GeneralAttachmentSettings, ForgejoError> {
+ let request = self.get("settings/attachment").build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get instance's global settings for repositories
+ pub async fn get_general_repository_settings(
+ &self,
+ ) -> Result<GeneralRepoSettings, ForgejoError> {
+ let request = self.get("settings/repository").build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get instance's global settings for ui
+ pub async fn get_general_ui_settings(&self) -> Result<GeneralUISettings, ForgejoError> {
+ let request = self.get("settings/ui").build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get default signing-key.gpg
+ pub async fn get_signing_key(&self) -> Result<String, ForgejoError> {
+ let request = self.get("signing-key.gpg").build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.text().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get a team
+ ///
+ /// - `id`: id of the team to get
+ pub async fn org_get_team(&self, id: u64) -> Result<Team, ForgejoError> {
+ let request = self.get(&format!("teams/{id}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete a team
+ ///
+ /// - `id`: id of the team to delete
+ pub async fn org_delete_team(&self, id: u64) -> Result<(), ForgejoError> {
+ let request = self.delete(&format!("teams/{id}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Edit a team
+ ///
+ /// - `id`: id of the team to edit
+ /// - `body`: See [`EditTeamOption`]
+ pub async fn org_edit_team(&self, id: u32, body: EditTeamOption) -> Result<Team, ForgejoError> {
+ let request = self.patch(&format!("teams/{id}")).json(&body).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List a team's activity feeds
+ ///
+ /// - `id`: id of the team
+ pub async fn org_list_team_activity_feeds(
+ &self,
+ id: u64,
+ query: OrgListTeamActivityFeedsQuery,
+ ) -> Result<Vec<Activity>, ForgejoError> {
+ let request = self
+ .get(&format!("teams/{id}/activities/feeds?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List a team's members
+ ///
+ /// - `id`: id of the team
+ pub async fn org_list_team_members(
+ &self,
+ id: u64,
+ query: OrgListTeamMembersQuery,
+ ) -> Result<Vec<User>, ForgejoError> {
+ let request = self.get(&format!("teams/{id}/members?{query}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List a particular member of team
+ ///
+ /// - `id`: id of the team
+ /// - `username`: username of the member to list
+ pub async fn org_list_team_member(
+ &self,
+ id: u64,
+ username: &str,
+ ) -> Result<User, ForgejoError> {
+ let request = self
+ .get(&format!("teams/{id}/members/{username}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Add a team member
+ ///
+ /// - `id`: id of the team
+ /// - `username`: username of the user to add
+ pub async fn org_add_team_member(&self, id: u64, username: &str) -> Result<(), ForgejoError> {
+ let request = self
+ .put(&format!("teams/{id}/members/{username}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Remove a team member
+ ///
+ /// - `id`: id of the team
+ /// - `username`: username of the user to remove
+ pub async fn org_remove_team_member(
+ &self,
+ id: u64,
+ username: &str,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!("teams/{id}/members/{username}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List a team's repos
+ ///
+ /// - `id`: id of the team
+ pub async fn org_list_team_repos(
+ &self,
+ id: u64,
+ query: OrgListTeamReposQuery,
+ ) -> Result<Vec<Repository>, ForgejoError> {
+ let request = self.get(&format!("teams/{id}/repos?{query}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List a particular repo of team
+ ///
+ /// - `id`: id of the team
+ /// - `org`: organization that owns the repo to list
+ /// - `repo`: name of the repo to list
+ pub async fn org_list_team_repo(
+ &self,
+ id: u64,
+ org: &str,
+ repo: &str,
+ ) -> Result<Repository, ForgejoError> {
+ let request = self
+ .get(&format!("teams/{id}/repos/{org}/{repo}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Add a repository to a team
+ ///
+ /// - `id`: id of the team
+ /// - `org`: organization that owns the repo to add
+ /// - `repo`: name of the repo to add
+ pub async fn org_add_team_repository(
+ &self,
+ id: u64,
+ org: &str,
+ repo: &str,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .put(&format!("teams/{id}/repos/{org}/{repo}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Remove a repository from a team
+ ///
+ /// - `id`: id of the team
+ /// - `org`: organization that owns the repo to remove
+ /// - `repo`: name of the repo to remove
+ pub async fn org_remove_team_repository(
+ &self,
+ id: u64,
+ org: &str,
+ repo: &str,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!("teams/{id}/repos/{org}/{repo}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// search topics via keyword
+ ///
+ pub async fn topic_search(
+ &self,
+ query: TopicSearchQuery,
+ ) -> Result<Vec<TopicResponse>, ForgejoError> {
+ let request = self.get(&format!("topics/search?{query}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get the authenticated user
+ pub async fn user_get_current(&self) -> Result<User, ForgejoError> {
+ let request = self.get("user").build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get an user's actions runner registration token
+ pub async fn user_get_runner_registration_token(
+ &self,
+ ) -> Result<RegistrationTokenHeaders, ForgejoError> {
+ let request = self
+ .get("user/actions/runners/registration-token")
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.headers().try_into()?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Create or Update a secret value in a user scope
+ ///
+ /// - `secretname`: name of the secret
+ /// - `body`: See [`CreateOrUpdateSecretOption`]
+ pub async fn update_user_secret(
+ &self,
+ secretname: &str,
+ body: CreateOrUpdateSecretOption,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .put(&format!("user/actions/secrets/{secretname}"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(()),
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete a secret in a user scope
+ ///
+ /// - `secretname`: name of the secret
+ pub async fn delete_user_secret(&self, secretname: &str) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!("user/actions/secrets/{secretname}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get the user-level list of variables which is created by current doer
+ ///
+ pub async fn get_user_variables_list(
+ &self,
+ query: GetUserVariablesListQuery,
+ ) -> Result<Vec<ActionVariable>, ForgejoError> {
+ let request = self
+ .get(&format!("user/actions/variables?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get a user-level variable which is created by current doer
+ ///
+ /// - `variablename`: name of the variable
+ pub async fn get_user_variable(
+ &self,
+ variablename: &str,
+ ) -> Result<ActionVariable, ForgejoError> {
+ let request = self
+ .get(&format!("user/actions/variables/{variablename}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Update a user-level variable which is created by current doer
+ ///
+ /// - `variablename`: name of the variable
+ /// - `body`: See [`UpdateVariableOption`]
+ pub async fn update_user_variable(
+ &self,
+ variablename: &str,
+ body: UpdateVariableOption,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .put(&format!("user/actions/variables/{variablename}"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(()),
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Create a user-level variable
+ ///
+ /// - `variablename`: name of the variable
+ /// - `body`: See [`CreateVariableOption`]
+ pub async fn create_user_variable(
+ &self,
+ variablename: &str,
+ body: CreateVariableOption,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .post(&format!("user/actions/variables/{variablename}"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(()),
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete a user-level variable which is created by current doer
+ ///
+ /// - `variablename`: name of the variable
+ pub async fn delete_user_variable(&self, variablename: &str) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!("user/actions/variables/{variablename}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(()),
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List the authenticated user's oauth2 applications
+ ///
+ pub async fn user_get_oauth2_applications(
+ &self,
+ query: UserGetOAuth2ApplicationsQuery,
+ ) -> Result<Vec<OAuth2Application>, ForgejoError> {
+ let request = self
+ .get(&format!("user/applications/oauth2?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// creates a new OAuth2 application
+ ///
+ /// - `body`: See [`CreateOAuth2ApplicationOptions`]
+ pub async fn user_create_oauth2_application(
+ &self,
+ body: CreateOAuth2ApplicationOptions,
+ ) -> Result<OAuth2Application, ForgejoError> {
+ let request = self.post("user/applications/oauth2").json(&body).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// get an OAuth2 Application
+ ///
+ /// - `id`: Application ID to be found
+ pub async fn user_get_oauth2_application(
+ &self,
+ id: u64,
+ ) -> Result<OAuth2Application, ForgejoError> {
+ let request = self
+ .get(&format!("user/applications/oauth2/{id}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// delete an OAuth2 Application
+ ///
+ /// - `id`: token to be deleted
+ pub async fn user_delete_oauth2_application(&self, id: u64) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!("user/applications/oauth2/{id}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// update an OAuth2 Application, this includes regenerating the client secret
+ ///
+ /// - `id`: application to be updated
+ /// - `body`: See [`CreateOAuth2ApplicationOptions`]
+ pub async fn user_update_oauth2_application(
+ &self,
+ id: u64,
+ body: CreateOAuth2ApplicationOptions,
+ ) -> Result<OAuth2Application, ForgejoError> {
+ let request = self
+ .patch(&format!("user/applications/oauth2/{id}"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Update Avatar
+ ///
+ /// - `body`: See [`UpdateUserAvatarOption`]
+ pub async fn user_update_avatar(
+ &self,
+ body: UpdateUserAvatarOption,
+ ) -> Result<(), ForgejoError> {
+ let request = self.post("user/avatar").json(&body).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete Avatar
+ pub async fn user_delete_avatar(&self) -> Result<(), ForgejoError> {
+ let request = self.delete("user/avatar").build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Blocks a user from the doer.
+ ///
+ /// - `username`: username of the user
+ pub async fn user_block_user(&self, username: &str) -> Result<(), ForgejoError> {
+ let request = self.put(&format!("user/block/{username}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List the authenticated user's email addresses
+ pub async fn user_list_emails(&self) -> Result<Vec<Email>, ForgejoError> {
+ let request = self.get("user/emails").build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Add email addresses
+ ///
+ /// - `body`: See [`CreateEmailOption`]
+ pub async fn user_add_email(
+ &self,
+ body: CreateEmailOption,
+ ) -> Result<Vec<Email>, ForgejoError> {
+ let request = self.post("user/emails").json(&body).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete email addresses
+ ///
+ /// - `body`: See [`DeleteEmailOption`]
+ pub async fn user_delete_email(&self, body: DeleteEmailOption) -> Result<(), ForgejoError> {
+ let request = self.delete("user/emails").json(&body).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List the authenticated user's followers
+ ///
+ pub async fn user_current_list_followers(
+ &self,
+ query: UserCurrentListFollowersQuery,
+ ) -> Result<Vec<User>, ForgejoError> {
+ let request = self.get(&format!("user/followers?{query}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List the users that the authenticated user is following
+ ///
+ pub async fn user_current_list_following(
+ &self,
+ query: UserCurrentListFollowingQuery,
+ ) -> Result<Vec<User>, ForgejoError> {
+ let request = self.get(&format!("user/following?{query}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Check whether a user is followed by the authenticated user
+ ///
+ /// - `username`: username of followed user
+ pub async fn user_current_check_following(&self, username: &str) -> Result<(), ForgejoError> {
+ let request = self.get(&format!("user/following/{username}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Follow a user
+ ///
+ /// - `username`: username of user to follow
+ pub async fn user_current_put_follow(&self, username: &str) -> Result<(), ForgejoError> {
+ let request = self.put(&format!("user/following/{username}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Unfollow a user
+ ///
+ /// - `username`: username of user to unfollow
+ pub async fn user_current_delete_follow(&self, username: &str) -> Result<(), ForgejoError> {
+ let request = self.delete(&format!("user/following/{username}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get a Token to verify
+ pub async fn get_verification_token(&self) -> Result<String, ForgejoError> {
+ let request = self.get("user/gpg_key_token").build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.text().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Verify a GPG key
+ pub async fn user_verify_gpg_key(&self) -> Result<GPGKey, ForgejoError> {
+ let request = self.post("user/gpg_key_verify").build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List the authenticated user's GPG keys
+ ///
+ pub async fn user_current_list_gpg_keys(
+ &self,
+ query: UserCurrentListGpgKeysQuery,
+ ) -> Result<Vec<GPGKey>, ForgejoError> {
+ let request = self.get(&format!("user/gpg_keys?{query}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Create a GPG key
+ ///
+ /// - `Form`: See [`CreateGPGKeyOption`]
+ pub async fn user_current_post_gpg_key(
+ &self,
+ form: CreateGPGKeyOption,
+ ) -> Result<GPGKey, ForgejoError> {
+ let request = self.post("user/gpg_keys").json(&form).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get a GPG key
+ ///
+ /// - `id`: id of key to get
+ pub async fn user_current_get_gpg_key(&self, id: u64) -> Result<GPGKey, ForgejoError> {
+ let request = self.get(&format!("user/gpg_keys/{id}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Remove a GPG key
+ ///
+ /// - `id`: id of key to delete
+ pub async fn user_current_delete_gpg_key(&self, id: u64) -> Result<(), ForgejoError> {
+ let request = self.delete(&format!("user/gpg_keys/{id}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List the authenticated user's webhooks
+ ///
+ pub async fn user_list_hooks(
+ &self,
+ query: UserListHooksQuery,
+ ) -> Result<Vec<Hook>, ForgejoError> {
+ let request = self.get(&format!("user/hooks?{query}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Create a hook
+ ///
+ /// - `body`: See [`CreateHookOption`]
+ pub async fn user_create_hook(&self, body: CreateHookOption) -> Result<Hook, ForgejoError> {
+ let request = self.post("user/hooks").json(&body).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get a hook
+ ///
+ /// - `id`: id of the hook to get
+ pub async fn user_get_hook(&self, id: u64) -> Result<Hook, ForgejoError> {
+ let request = self.get(&format!("user/hooks/{id}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete a hook
+ ///
+ /// - `id`: id of the hook to delete
+ pub async fn user_delete_hook(&self, id: u64) -> Result<(), ForgejoError> {
+ let request = self.delete(&format!("user/hooks/{id}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Update a hook
+ ///
+ /// - `id`: id of the hook to update
+ /// - `body`: See [`EditHookOption`]
+ pub async fn user_edit_hook(
+ &self,
+ id: u64,
+ body: EditHookOption,
+ ) -> Result<Hook, ForgejoError> {
+ let request = self
+ .patch(&format!("user/hooks/{id}"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List the authenticated user's public keys
+ ///
+ pub async fn user_current_list_keys(
+ &self,
+ query: UserCurrentListKeysQuery,
+ ) -> Result<Vec<PublicKey>, ForgejoError> {
+ let request = self.get(&format!("user/keys?{query}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Create a public key
+ ///
+ /// - `body`: See [`CreateKeyOption`]
+ pub async fn user_current_post_key(
+ &self,
+ body: CreateKeyOption,
+ ) -> Result<PublicKey, ForgejoError> {
+ let request = self.post("user/keys").json(&body).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get a public key
+ ///
+ /// - `id`: id of key to get
+ pub async fn user_current_get_key(&self, id: u64) -> Result<PublicKey, ForgejoError> {
+ let request = self.get(&format!("user/keys/{id}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Delete a public key
+ ///
+ /// - `id`: id of key to delete
+ pub async fn user_current_delete_key(&self, id: u64) -> Result<(), ForgejoError> {
+ let request = self.delete(&format!("user/keys/{id}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List the authenticated user's blocked users
+ ///
+ pub async fn user_list_blocked_users(
+ &self,
+ query: UserListBlockedUsersQuery,
+ ) -> Result<Vec<BlockedUser>, ForgejoError> {
+ let request = self.get(&format!("user/list_blocked?{query}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List the current user's organizations
+ ///
+ pub async fn org_list_current_user_orgs(
+ &self,
+ query: OrgListCurrentUserOrgsQuery,
+ ) -> Result<Vec<Organization>, ForgejoError> {
+ let request = self.get(&format!("user/orgs?{query}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List the repos that the authenticated user owns
+ ///
+ pub async fn user_current_list_repos(
+ &self,
+ query: UserCurrentListReposQuery,
+ ) -> Result<Vec<Repository>, ForgejoError> {
+ let request = self.get(&format!("user/repos?{query}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Create a repository
+ ///
+ /// - `body`: See [`CreateRepoOption`]
+ pub async fn create_current_user_repo(
+ &self,
+ body: CreateRepoOption,
+ ) -> Result<Repository, ForgejoError> {
+ let request = self.post("user/repos").json(&body).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get user settings
+ pub async fn get_user_settings(&self) -> Result<UserSettings, ForgejoError> {
+ let request = self.get("user/settings").build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Update user settings
+ ///
+ /// - `body`: See [`UserSettingsOptions`]
+ pub async fn update_user_settings(
+ &self,
+ body: UserSettingsOptions,
+ ) -> Result<UserSettings, ForgejoError> {
+ let request = self.patch("user/settings").json(&body).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// The repos that the authenticated user has starred
+ ///
+ pub async fn user_current_list_starred(
+ &self,
+ query: UserCurrentListStarredQuery,
+ ) -> Result<Vec<Repository>, ForgejoError> {
+ let request = self.get(&format!("user/starred?{query}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Whether the authenticated is starring the repo
+ ///
+ /// - `owner`: owner of the repo
+ /// - `repo`: name of the repo
+ pub async fn user_current_check_starring(
+ &self,
+ owner: &str,
+ repo: &str,
+ ) -> Result<(), ForgejoError> {
+ let request = self.get(&format!("user/starred/{owner}/{repo}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Star the given repo
+ ///
+ /// - `owner`: owner of the repo to star
+ /// - `repo`: name of the repo to star
+ pub async fn user_current_put_star(&self, owner: &str, repo: &str) -> Result<(), ForgejoError> {
+ let request = self.put(&format!("user/starred/{owner}/{repo}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Unstar the given repo
+ ///
+ /// - `owner`: owner of the repo to unstar
+ /// - `repo`: name of the repo to unstar
+ pub async fn user_current_delete_star(
+ &self,
+ owner: &str,
+ repo: &str,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!("user/starred/{owner}/{repo}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get list of all existing stopwatches
+ ///
+ pub async fn user_get_stop_watches(
+ &self,
+ query: UserGetStopWatchesQuery,
+ ) -> Result<Vec<StopWatch>, ForgejoError> {
+ let request = self.get(&format!("user/stopwatches?{query}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List repositories watched by the authenticated user
+ ///
+ pub async fn user_current_list_subscriptions(
+ &self,
+ query: UserCurrentListSubscriptionsQuery,
+ ) -> Result<Vec<Repository>, ForgejoError> {
+ let request = self.get(&format!("user/subscriptions?{query}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List all the teams a user belongs to
+ ///
+ pub async fn user_list_teams(
+ &self,
+ query: UserListTeamsQuery,
+ ) -> Result<Vec<Team>, ForgejoError> {
+ let request = self.get(&format!("user/teams?{query}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List the current user's tracked times
+ ///
+ pub async fn user_current_tracked_times(
+ &self,
+ query: UserCurrentTrackedTimesQuery,
+ ) -> Result<Vec<TrackedTime>, ForgejoError> {
+ let request = self.get(&format!("user/times?{query}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Unblocks a user from the doer.
+ ///
+ /// - `username`: username of the user
+ pub async fn user_unblock_user(&self, username: &str) -> Result<(), ForgejoError> {
+ let request = self.put(&format!("user/unblock/{username}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Search for users
+ ///
+ pub async fn user_search(
+ &self,
+ query: UserSearchQuery,
+ ) -> Result<UserSearchResponse, ForgejoError> {
+ let request = self.get(&format!("users/search?{query}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get a user
+ ///
+ /// - `username`: username of user to get
+ pub async fn user_get(&self, username: &str) -> Result<User, ForgejoError> {
+ let request = self.get(&format!("users/{username}")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List a user's activity feeds
+ ///
+ /// - `username`: username of user
+ pub async fn user_list_activity_feeds(
+ &self,
+ username: &str,
+ query: UserListActivityFeedsQuery,
+ ) -> Result<Vec<Activity>, ForgejoError> {
+ let request = self
+ .get(&format!("users/{username}/activities/feeds?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List the given user's followers
+ ///
+ /// - `username`: username of user
+ pub async fn user_list_followers(
+ &self,
+ username: &str,
+ query: UserListFollowersQuery,
+ ) -> Result<Vec<User>, ForgejoError> {
+ let request = self
+ .get(&format!("users/{username}/followers?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List the users that the given user is following
+ ///
+ /// - `username`: username of user
+ pub async fn user_list_following(
+ &self,
+ username: &str,
+ query: UserListFollowingQuery,
+ ) -> Result<Vec<User>, ForgejoError> {
+ let request = self
+ .get(&format!("users/{username}/following?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Check if one user is following another user
+ ///
+ /// - `username`: username of following user
+ /// - `target`: username of followed user
+ pub async fn user_check_following(
+ &self,
+ username: &str,
+ target: &str,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .get(&format!("users/{username}/following/{target}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List the given user's GPG keys
+ ///
+ /// - `username`: username of user
+ pub async fn user_list_gpg_keys(
+ &self,
+ username: &str,
+ query: UserListGpgKeysQuery,
+ ) -> Result<Vec<GPGKey>, ForgejoError> {
+ let request = self
+ .get(&format!("users/{username}/gpg_keys?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get a user's heatmap
+ ///
+ /// - `username`: username of user to get
+ pub async fn user_get_heatmap_data(
+ &self,
+ username: &str,
+ ) -> Result<Vec<UserHeatmapData>, ForgejoError> {
+ let request = self.get(&format!("users/{username}/heatmap")).build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List the given user's public keys
+ ///
+ /// - `username`: username of user
+ pub async fn user_list_keys(
+ &self,
+ username: &str,
+ query: UserListKeysQuery,
+ ) -> Result<Vec<PublicKey>, ForgejoError> {
+ let request = self
+ .get(&format!("users/{username}/keys?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List a user's organizations
+ ///
+ /// - `username`: username of user
+ pub async fn org_list_user_orgs(
+ &self,
+ username: &str,
+ query: OrgListUserOrgsQuery,
+ ) -> Result<Vec<Organization>, ForgejoError> {
+ let request = self
+ .get(&format!("users/{username}/orgs?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Get user permissions in organization
+ ///
+ /// - `username`: username of user
+ /// - `org`: name of the organization
+ pub async fn org_get_user_permissions(
+ &self,
+ username: &str,
+ org: &str,
+ ) -> Result<OrganizationPermissions, ForgejoError> {
+ let request = self
+ .get(&format!("users/{username}/orgs/{org}/permissions"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List the repos owned by the given user
+ ///
+ /// - `username`: username of user
+ pub async fn user_list_repos(
+ &self,
+ username: &str,
+ query: UserListReposQuery,
+ ) -> Result<Vec<Repository>, ForgejoError> {
+ let request = self
+ .get(&format!("users/{username}/repos?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// The repos that the given user has starred
+ ///
+ /// - `username`: username of user
+ pub async fn user_list_starred(
+ &self,
+ username: &str,
+ query: UserListStarredQuery,
+ ) -> Result<Vec<Repository>, ForgejoError> {
+ let request = self
+ .get(&format!("users/{username}/starred?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List the repositories watched by a user
+ ///
+ /// - `username`: username of the user
+ pub async fn user_list_subscriptions(
+ &self,
+ username: &str,
+ query: UserListSubscriptionsQuery,
+ ) -> Result<Vec<Repository>, ForgejoError> {
+ let request = self
+ .get(&format!("users/{username}/subscriptions?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// List the authenticated user's access tokens
+ ///
+ /// - `username`: username of user
+ pub async fn user_get_tokens(
+ &self,
+ username: &str,
+ query: UserGetTokensQuery,
+ ) -> Result<Vec<AccessToken>, ForgejoError> {
+ let request = self
+ .get(&format!("users/{username}/tokens?{query}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Create an access token
+ ///
+ /// - `username`: username of user
+ /// - `body`: See [`CreateAccessTokenOption`]
+ pub async fn user_create_token(
+ &self,
+ username: &str,
+ body: CreateAccessTokenOption,
+ ) -> Result<AccessToken, ForgejoError> {
+ let request = self
+ .post(&format!("users/{username}/tokens"))
+ .json(&body)
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 201 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// delete an access token
+ ///
+ /// - `username`: username of user
+ /// - `token`: token to be deleted, identified by ID and if not available by name
+ pub async fn user_delete_access_token(
+ &self,
+ username: &str,
+ token: &str,
+ ) -> Result<(), ForgejoError> {
+ let request = self
+ .delete(&format!("users/{username}/tokens/{token}"))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 204 => Ok(()),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+
+ /// Returns the version of the Forgejo application
+ pub async fn get_version(&self) -> Result<ServerVersion, ForgejoError> {
+ let request = self.get("version").build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => Err(ForgejoError::UnexpectedStatusCode(response.status())),
+ }
+ }
+}