summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorCyborus <cyborus@cyborus.xyz>2024-01-18 19:44:07 +0100
committerCyborus <cyborus@cyborus.xyz>2024-01-18 19:44:07 +0100
commit81b17abc8aa286e7cc94b08079832916b5e89d10 (patch)
treeeab9ed5757f37a0d8d6968843db25f9b897d5a61 /src
parentrename `userGetOauth2Application` to `userGetOAuth2Applications` (diff)
downloadforgejo-api-81b17abc8aa286e7cc94b08079832916b5e89d10.tar.xz
forgejo-api-81b17abc8aa286e7cc94b08079832916b5e89d10.zip
replace with generated api
Diffstat (limited to 'src')
-rw-r--r--src/admin.rs502
-rw-r--r--src/generated.rs12253
-rw-r--r--src/issue.rs347
-rw-r--r--src/lib.rs220
-rw-r--r--src/misc.rs162
-rw-r--r--src/notification.rs273
-rw-r--r--src/organization.rs30
-rw-r--r--src/package.rs174
-rw-r--r--src/repository.rs743
-rw-r--r--src/user.rs59
10 files changed, 12272 insertions, 2491 deletions
diff --git a/src/admin.rs b/src/admin.rs
deleted file mode 100644
index 560d6c6..0000000
--- a/src/admin.rs
+++ /dev/null
@@ -1,502 +0,0 @@
-use super::*;
-
-use std::collections::BTreeMap;
-use std::fmt::Write;
-
-impl Forgejo {
- pub async fn admin_get_crons(&self, query: CronQuery) -> Result<Vec<Cron>, ForgejoError> {
- self.get(&query.path()).await
- }
-
- pub async fn admin_run_cron(&self, name: &str) -> Result<(), ForgejoError> {
- self.post_unit(&format!("admin/cron/{name}"), &()).await
- }
-
- pub async fn admin_get_emails(
- &self,
- query: EmailListQuery,
- ) -> Result<Vec<Email>, ForgejoError> {
- self.get(&query.path()).await
- }
-
- pub async fn admin_search_emails(
- &self,
- query: EmailSearchQuery,
- ) -> Result<Vec<Email>, ForgejoError> {
- self.get(&query.path()).await
- }
-
- pub async fn admin_get_hooks(&self, query: HookQuery) -> Result<Vec<Hook>, ForgejoError> {
- self.get(&query.path()).await
- }
-
- pub async fn admin_create_hook(&self, opt: CreateHookOption) -> Result<Hook, ForgejoError> {
- self.post("admin/hooks", &opt).await
- }
-
- pub async fn admin_get_hook(&self, id: u64) -> Result<Option<Hook>, ForgejoError> {
- self.get_opt(&format!("admin/hooks/{id}")).await
- }
-
- pub async fn admin_delete_hook(&self, id: u64) -> Result<(), ForgejoError> {
- self.delete(&format!("admin/hooks/{id}")).await
- }
-
- pub async fn admin_edit_hook(
- &self,
- id: u64,
- opt: EditHookOption,
- ) -> Result<Hook, ForgejoError> {
- self.patch(&format!("admin/hooks/{id}"), &opt).await
- }
-
- pub async fn admin_get_orgs(
- &self,
- query: AdminOrganizationQuery,
- ) -> Result<Vec<Organization>, ForgejoError> {
- self.get(&query.path()).await
- }
-
- pub async fn admin_unadopted_repos(
- &self,
- query: UnadoptedRepoQuery,
- ) -> Result<Vec<String>, ForgejoError> {
- self.get(&query.path()).await
- }
-
- pub async fn admin_adopt(&self, owner: &str, repo: &str) -> Result<(), ForgejoError> {
- self.post(&format!("admin/unadopted/{owner}/{repo}"), &())
- .await
- }
-
- pub async fn admin_delete_unadopted(
- &self,
- owner: &str,
- repo: &str,
- ) -> Result<(), ForgejoError> {
- self.delete(&format!("admin/unadopted/{owner}/{repo}"))
- .await
- }
-
- pub async fn admin_users(&self, query: AdminUserQuery) -> Result<Vec<User>, ForgejoError> {
- self.get(&query.path()).await
- }
-
- pub async fn admin_create_user(&self, opt: CreateUserOption) -> Result<User, ForgejoError> {
- self.post("admin/users", &opt).await
- }
-
- pub async fn admin_delete_user(&self, user: &str, purge: bool) -> Result<(), ForgejoError> {
- self.delete(&format!("admin/users/{user}?purge={purge}"))
- .await
- }
-
- pub async fn admin_edit_user(
- &self,
- user: &str,
- opt: CreateUserOption,
- ) -> Result<User, ForgejoError> {
- self.patch(&format!("admin/users/{user}"), &opt).await
- }
-
- pub async fn admin_add_key(
- &self,
- user: &str,
- opt: CreateKeyOption,
- ) -> Result<PublicKey, ForgejoError> {
- self.post(&format!("admin/users/{user}/keys"), &opt).await
- }
-
- pub async fn admin_delete_key(&self, user: &str, id: u64) -> Result<(), ForgejoError> {
- self.delete(&format!("admin/users/{user}/keys/{id}")).await
- }
-
- pub async fn admin_create_org(
- &self,
- owner: &str,
- opt: CreateOrgOption,
- ) -> Result<Organization, ForgejoError> {
- self.post(&format!("admin/users/{owner}/orgs"), &opt).await
- }
-
- pub async fn admin_rename_user(
- &self,
- user: &str,
- opt: RenameUserOption,
- ) -> Result<(), ForgejoError> {
- self.post_unit(&format!("admin/users/{user}/rename"), &opt)
- .await
- }
-
- pub async fn admin_create_repo(
- &self,
- owner: &str,
- opt: CreateRepoOption,
- ) -> Result<Repository, ForgejoError> {
- self.post(&format!("admin/users/{owner}/repos"), &opt).await
- }
-}
-
-#[derive(serde::Deserialize, Debug, PartialEq)]
-pub struct Cron {
- pub exec_times: u64,
- pub name: String,
- #[serde(with = "time::serde::rfc3339")]
- pub next: time::OffsetDateTime,
- #[serde(with = "time::serde::rfc3339")]
- pub prev: time::OffsetDateTime,
- pub schedule: String,
-}
-
-#[derive(Default, Debug)]
-pub struct CronQuery {
- pub page: Option<u32>,
- pub limit: Option<u32>,
-}
-
-impl CronQuery {
- fn path(&self) -> String {
- let mut s = String::from("admin/cron?");
- if let Some(page) = self.page {
- s.push_str("page=");
- s.write_fmt(format_args!("{page}"))
- .expect("writing to string can't fail");
- s.push('&');
- }
- if let Some(limit) = self.limit {
- s.push_str("limit=");
- s.write_fmt(format_args!("{limit}"))
- .expect("writing to string can't fail");
- s.push('&');
- }
- s
- }
-}
-
-#[derive(serde::Deserialize, Debug, PartialEq)]
-pub struct Email {
- pub email: String,
- pub primary: bool,
- pub user_id: u64,
- pub username: String,
- pub verified: bool,
-}
-
-#[derive(Default, Debug)]
-pub struct EmailListQuery {
- pub page: Option<u32>,
- pub limit: Option<u32>,
-}
-
-impl EmailListQuery {
- fn path(&self) -> String {
- let mut s = String::from("admin/emails?");
- if let Some(page) = self.page {
- s.push_str("page=");
- s.write_fmt(format_args!("{page}"))
- .expect("writing to string can't fail");
- s.push('&');
- }
- if let Some(limit) = self.limit {
- s.push_str("limit=");
- s.write_fmt(format_args!("{limit}"))
- .expect("writing to string can't fail");
- s.push('&');
- }
- s
- }
-}
-
-#[derive(Default, Debug)]
-pub struct EmailSearchQuery {
- pub query: String,
- pub page: Option<u32>,
- pub limit: Option<u32>,
-}
-
-impl EmailSearchQuery {
- fn path(&self) -> String {
- let mut s = String::from("admin/emails/search?");
- if !self.query.is_empty() {
- s.push_str("q=");
- s.push_str(&self.query);
- s.push('&');
- }
- if let Some(page) = self.page {
- s.push_str("page=");
- s.write_fmt(format_args!("{page}"))
- .expect("writing to string can't fail");
- s.push('&');
- }
- if let Some(limit) = self.limit {
- s.push_str("limit=");
- s.write_fmt(format_args!("{limit}"))
- .expect("writing to string can't fail");
- s.push('&');
- }
- s
- }
-}
-
-#[derive(serde::Deserialize, Debug, PartialEq)]
-pub struct Hook {
- pub active: bool,
- pub authorization_header: String,
- pub branch_filter: String,
- pub config: std::collections::BTreeMap<String, String>,
- #[serde(with = "time::serde::rfc3339")]
- pub created_at: time::OffsetDateTime,
- pub events: Vec<String>,
- pub id: u64,
- #[serde(rename = "type")]
- pub _type: HookType,
- #[serde(with = "time::serde::rfc3339")]
- pub updated_at: time::OffsetDateTime,
-}
-
-#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq)]
-#[non_exhaustive]
-#[serde(rename_all = "lowercase")]
-pub enum HookType {
- Forgejo,
- Dingtalk,
- Discord,
- Gitea,
- Gogs,
- Msteams,
- Slack,
- Telegram,
- Feishu,
- Wechatwork,
- Packagist,
-}
-
-#[derive(Default, Debug)]
-pub struct HookQuery {
- pub page: Option<u32>,
- pub limit: Option<u32>,
-}
-
-impl HookQuery {
- fn path(&self) -> String {
- let mut s = String::from("admin/hooks?");
- if let Some(page) = self.page {
- s.push_str("page=");
- s.write_fmt(format_args!("{page}"))
- .expect("writing to string can't fail");
- s.push('&');
- }
- if let Some(limit) = self.limit {
- s.push_str("limit=");
- s.write_fmt(format_args!("{limit}"))
- .expect("writing to string can't fail");
- s.push('&');
- }
- s
- }
-}
-
-#[derive(serde::Serialize, Debug, PartialEq)]
-pub struct CreateHookOption {
- pub active: Option<bool>,
- pub authorization_header: Option<String>,
- pub branch_filter: Option<String>,
- pub config: CreateHookOptionConfig,
- pub events: Vec<String>,
- #[serde(rename = "type")]
- pub _type: HookType,
-}
-
-#[derive(serde::Serialize, Debug, PartialEq)]
-pub struct CreateHookOptionConfig {
- pub content_type: String,
- pub url: Url,
- #[serde(flatten)]
- pub other: BTreeMap<String, String>,
-}
-
-#[derive(serde::Serialize, Debug, PartialEq, Default)]
-pub struct EditHookOption {
- pub active: Option<bool>,
- pub authorization_header: Option<String>,
- pub branch_filter: Option<String>,
- pub config: Option<BTreeMap<String, String>>,
- pub events: Option<Vec<String>>,
-}
-
-#[derive(Default, Debug)]
-pub struct AdminOrganizationQuery {
- pub page: Option<u32>,
- pub limit: Option<u32>,
-}
-
-impl AdminOrganizationQuery {
- fn path(&self) -> String {
- let mut s = String::from("admin/orgs?");
- if let Some(page) = self.page {
- s.push_str("page=");
- s.write_fmt(format_args!("{page}"))
- .expect("writing to string can't fail");
- s.push('&');
- }
- if let Some(limit) = self.limit {
- s.push_str("limit=");
- s.write_fmt(format_args!("{limit}"))
- .expect("writing to string can't fail");
- s.push('&');
- }
- s
- }
-}
-
-#[derive(Default, Debug)]
-pub struct UnadoptedRepoQuery {
- pub page: Option<u32>,
- pub limit: Option<u32>,
- pub pattern: String,
-}
-
-impl UnadoptedRepoQuery {
- fn path(&self) -> String {
- let mut s = String::from("admin/unadopted?");
- if let Some(page) = self.page {
- s.push_str("page=");
- s.write_fmt(format_args!("{page}"))
- .expect("writing to string can't fail");
- s.push('&');
- }
- if let Some(limit) = self.limit {
- s.push_str("limit=");
- s.write_fmt(format_args!("{limit}"))
- .expect("writing to string can't fail");
- s.push('&');
- }
- if !self.pattern.is_empty() {
- s.push_str("pattern=");
- s.push_str(&self.pattern);
- s.push('&');
- }
- s
- }
-}
-
-#[derive(Default, Debug)]
-pub struct AdminUserQuery {
- pub source_id: Option<u64>,
- pub login_name: String,
- pub page: Option<u32>,
- pub limit: Option<u32>,
-}
-
-impl AdminUserQuery {
- fn path(&self) -> String {
- let mut s = String::from("admin/users?");
- if let Some(source_id) = self.source_id {
- s.push_str("source_id=");
- s.write_fmt(format_args!("{source_id}"))
- .expect("writing to string can't fail");
- s.push('&');
- }
- if !self.login_name.is_empty() {
- s.push_str("login_name=");
- s.push_str(&self.login_name);
- s.push('&');
- }
- if let Some(page) = self.page {
- s.push_str("page=");
- s.write_fmt(format_args!("{page}"))
- .expect("writing to string can't fail");
- s.push('&');
- }
- if let Some(limit) = self.limit {
- s.push_str("limit=");
- s.write_fmt(format_args!("{limit}"))
- .expect("writing to string can't fail");
- s.push('&');
- }
- s
- }
-}
-
-#[derive(serde::Serialize, Debug, PartialEq)]
-pub struct CreateUserOption {
- #[serde(with = "time::serde::rfc3339::option")]
- pub created_at: Option<time::OffsetDateTime>,
- pub email: String,
- pub full_name: Option<String>,
- pub login_name: Option<String>,
- pub must_change_password: bool,
- pub password: String,
- pub restricted: bool,
- pub send_notify: bool,
- pub source_id: Option<u64>,
- pub username: String,
- pub visibility: String,
-}
-
-#[derive(serde::Serialize, Debug, PartialEq, Default)]
-pub struct EditUserOption {
- pub active: Option<bool>,
- pub admin: Option<bool>,
- pub allow_create_organization: Option<bool>,
- pub allow_git_hook: Option<bool>,
- pub allow_import_local: Option<bool>,
- pub description: Option<String>,
- pub email: Option<String>,
- pub full_name: Option<String>,
- pub location: Option<String>,
- pub login_name: Option<String>,
- pub max_repo_creation: Option<u64>,
- pub must_change_password: Option<bool>,
- pub password: Option<String>,
- pub prohibit_login: Option<bool>,
- pub restricted: Option<bool>,
- pub source_id: Option<u64>,
- pub visibility: Option<String>,
- pub website: Option<String>,
-}
-
-#[derive(serde::Serialize, Debug, PartialEq)]
-pub struct CreateKeyOption {
- pub key: String,
- pub read_only: Option<bool>,
- pub title: String,
-}
-
-#[derive(serde::Deserialize, Debug, PartialEq)]
-pub struct PublicKey {
- #[serde(with = "time::serde::rfc3339")]
- pub created_at: time::OffsetDateTime,
- pub fingerprint: String,
- pub id: u64,
- pub key: String,
- pub key_type: String,
- pub read_only: Option<bool>,
- pub title: String,
- pub url: Option<Url>,
- pub user: User,
-}
-
-#[derive(serde::Serialize, Debug, PartialEq)]
-pub struct CreateOrgOption {
- pub description: Option<String>,
- pub full_name: Option<String>,
- pub location: Option<String>,
- pub repo_admin_change_team_access: Option<bool>,
- pub username: String,
- pub visibility: OrgVisibility,
- pub website: Option<Url>,
-}
-
-#[derive(serde::Serialize, Debug, PartialEq)]
-#[serde(rename_all = "lowercase")]
-pub enum OrgVisibility {
- Public,
- Limited,
- Private,
-}
-
-#[derive(serde::Serialize, Debug, PartialEq)]
-pub struct RenameUserOption {
- pub new_username: String,
-}
diff --git a/src/generated.rs b/src/generated.rs
new file mode 100644
index 0000000..0486e27
--- /dev/null
+++ b/src/generated.rs
@@ -0,0 +1,12253 @@
+use crate::ForgejoError;
+impl crate::Forgejo {
+ /// 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.to_string()))
+ .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.to_string()))
+ .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.to_string()))
+ .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.to_string()))
+ .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`
+ 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`
+ 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.to_string()))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(response.json().await?),
+ _ => 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.to_string()))
+ .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.to_string()))
+ .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`
+ 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.to_string()))
+ .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`
+ 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`
+ 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`
+ 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`
+ 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`
+ 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`
+ 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
+ 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`
+ 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 Gitea 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.to_string()))
+ .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.to_string()))
+ .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.to_string()
+ ))
+ .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`
+ 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.to_string())).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`
+ 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`
+ 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())),
+ }
+ }
+
+ /// 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.to_string()
+ ))
+ .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`
+ 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())),
+ }
+ }
+
+ /// 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.to_string()
+ ))
+ .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`
+ 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.to_string()))
+ .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`
+ 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`
+ 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.to_string()))
+ .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`
+ 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`
+ 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.to_string()))
+ .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.to_string()))
+ .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.to_string()))
+ .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.to_string()))
+ .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`
+ 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.to_string()))
+ .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`
+ 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<serde_json::Map<String, serde_json::Value>, ForgejoError> {
+ let request = self
+ .get(&format!("/orgs/{org}/teams/search?{}", query.to_string()))
+ .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.to_string()))
+ .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.to_string()))
+ .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`
+ 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.to_string()))
+ .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
+ 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())),
+ }
+ }
+
+ /// 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`
+ 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 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.to_string()
+ ))
+ .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<(), 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(()),
+ _ => 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`
+ 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`
+ 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`
+ 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.to_string()
+ ))
+ .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`
+ 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.to_string()
+ ))
+ .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`
+ 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<Vec<Commit>, ForgejoError> {
+ let request = self
+ .get(&format!(
+ "/repos/{owner}/{repo}/commits?{}",
+ query.to_string()
+ ))
+ .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 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.to_string()
+ ))
+ .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.to_string()
+ ))
+ .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.to_string()
+ ))
+ .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`
+ 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.to_string()
+ ))
+ .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`
+ 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`
+ 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`
+ 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`
+ 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.to_string()
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => 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.to_string()
+ ))
+ .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`
+ 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.to_string()
+ ))
+ .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.to_string()
+ ))
+ .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.to_string()
+ ))
+ .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.to_string()
+ ))
+ .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`
+ 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`
+ 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`
+ 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.to_string()
+ ))
+ .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.to_string()
+ ))
+ .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`
+ 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.to_string()
+ ))
+ .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`
+ 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.to_string()
+ ))
+ .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`
+ 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`
+ 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`
+ 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`
+ 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.to_string()
+ ))
+ .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`
+ 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.to_string()
+ ))
+ .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`
+ 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`
+ 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.to_string()
+ ))
+ .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`
+ 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`
+ 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`
+ 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.to_string()
+ ))
+ .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`
+ 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`
+ 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`
+ 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`
+ 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`
+ 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`
+ 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.to_string()
+ ))
+ .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`
+ 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`
+ 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.to_string()
+ ))
+ .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.to_string()
+ ))
+ .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.to_string()
+ ))
+ .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`
+ 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.to_string()))
+ .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`
+ 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.to_string()
+ ))
+ .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`
+ 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`
+ 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<serde_json::Map<String, serde_json::Value>, 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<(), ForgejoError> {
+ let request = self
+ .get(&format!(
+ "/repos/{owner}/{repo}/media/{filepath}?{}",
+ query.to_string()
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(()),
+ _ => 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.to_string()
+ ))
+ .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`
+ 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`
+ 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.to_string()
+ ))
+ .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.to_string()
+ ))
+ .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.to_string()
+ ))
+ .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`
+ 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
+ ///
+ /// - `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`
+ 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.to_string()
+ ))
+ .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<Vec<Commit>, ForgejoError> {
+ let request = self
+ .get(&format!(
+ "/repos/{owner}/{repo}/pulls/{index}/commits?{}",
+ query.to_string()
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(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<Vec<ChangedFile>, ForgejoError> {
+ let request = self
+ .get(&format!(
+ "/repos/{owner}/{repo}/pulls/{index}/files?{}",
+ query.to_string()
+ ))
+ .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 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`
+ 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`
+ 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`
+ 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.to_string()
+ ))
+ .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`
+ 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`
+ 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())),
+ }
+ }
+
+ /// 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`
+ 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.to_string()
+ ))
+ .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.to_string()
+ ))
+ .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`
+ 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<(), ForgejoError> {
+ let request = self
+ .get(&format!(
+ "/repos/{owner}/{repo}/raw/{filepath}?{}",
+ query.to_string()
+ ))
+ .build()?;
+ let response = self.execute(request).await?;
+ match response.status().as_u16() {
+ 200 => Ok(()),
+ _ => 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.to_string()
+ ))
+ .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`
+ 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`
+ 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.to_string()
+ ))
+ .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`
+ 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 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.to_string()
+ ))
+ .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.to_string()
+ ))
+ .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`
+ 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.to_string()
+ ))
+ .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 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.to_string()))
+ .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`
+ 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() {
+ 200 => 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.to_string()
+ ))
+ .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.to_string()
+ ))
+ .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`
+ 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
+ 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`
+ 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`
+ 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.to_string()
+ ))
+ .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.to_string()
+ ))
+ .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`
+ 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`
+ 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.to_string()
+ ))
+ .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.to_string()))
+ .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.to_string()))
+ .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.to_string()))
+ .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())),
+ }
+ }
+
+ /// Create or Update a secret value in a user scope
+ ///
+ /// - `secretname`: name of the secret
+ /// - `body`
+ 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())),
+ }
+ }
+
+ /// 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.to_string()))
+ .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`
+ 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`
+ 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`
+ 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`
+ 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`
+ 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.to_string()))
+ .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.to_string()))
+ .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.to_string()))
+ .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`
+ 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.to_string()))
+ .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`
+ 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`
+ 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.to_string()))
+ .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`
+ 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.to_string()))
+ .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.to_string()))
+ .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.to_string()))
+ .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`
+ 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<Vec<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`
+ pub async fn update_user_settings(
+ &self,
+ body: UserSettingsOptions,
+ ) -> Result<Vec<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.to_string()))
+ .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.to_string()))
+ .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.to_string()))
+ .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.to_string()))
+ .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.to_string()))
+ .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<serde_json::Map<String, serde_json::Value>, ForgejoError> {
+ let request = self
+ .get(&format!("/users/search?{}", query.to_string()))
+ .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.to_string()
+ ))
+ .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.to_string()
+ ))
+ .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.to_string()
+ ))
+ .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.to_string()))
+ .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.to_string()))
+ .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.to_string()))
+ .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.to_string()))
+ .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.to_string()))
+ .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.to_string()
+ ))
+ .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.to_string()))
+ .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`
+ 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 Gitea 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())),
+ }
+ }
+}
+use structs::*;
+pub mod structs {
+ use std::fmt::Write;
+ /// APIError is an api error with a message
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct APIError {
+ pub message: Option<String>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub url: Option<url::Url>,
+ }
+
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct AccessToken {
+ pub id: Option<u64>,
+ pub name: Option<String>,
+ pub scopes: Option<Vec<String>>,
+ pub sha1: Option<String>,
+ pub token_last_eight: Option<String>,
+ }
+
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct Activity {
+ pub act_user: Option<User>,
+ pub act_user_id: Option<u64>,
+ pub comment: Option<Comment>,
+ pub comment_id: Option<u64>,
+ pub content: Option<String>,
+ pub created: Option<time::OffsetDateTime>,
+ pub id: Option<u64>,
+ pub is_private: Option<bool>,
+ pub op_type: Option<String>,
+ pub ref_name: Option<String>,
+ pub repo: Option<Repository>,
+ pub repo_id: Option<u64>,
+ pub user_id: Option<u64>,
+ }
+
+ /// ActivityPub type
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct ActivityPub {
+ #[serde(rename = "@context")]
+ pub context: Option<String>,
+ }
+
+ /// AddCollaboratorOption options when adding a user as a collaborator of a repository
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct AddCollaboratorOption {
+ pub permission: Option<String>,
+ }
+
+ /// AddTimeOption options for adding time to an issue
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct AddTimeOption {
+ pub created: Option<time::OffsetDateTime>,
+ pub time: u64,
+ pub user_name: Option<String>,
+ }
+
+ /// AnnotatedTag represents an annotated tag
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct AnnotatedTag {
+ pub message: Option<String>,
+ pub object: Option<AnnotatedTagObject>,
+ pub sha: Option<String>,
+ pub tag: Option<String>,
+ pub tagger: Option<CommitUser>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub url: Option<url::Url>,
+ pub verification: Option<PayloadCommitVerification>,
+ }
+
+ /// AnnotatedTagObject contains meta information of the tag object
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct AnnotatedTagObject {
+ pub sha: Option<String>,
+ #[serde(rename = "type")]
+ pub r#type: Option<String>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub url: Option<url::Url>,
+ }
+
+ /// Attachment a generic attachment
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct Attachment {
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub browser_download_url: Option<url::Url>,
+ pub created_at: Option<time::OffsetDateTime>,
+ pub download_count: Option<u64>,
+ pub id: Option<u64>,
+ pub name: Option<String>,
+ pub size: Option<u64>,
+ pub uuid: Option<String>,
+ }
+
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct BlockedUser {
+ pub block_id: Option<u64>,
+ pub created_at: Option<time::OffsetDateTime>,
+ }
+
+ /// Branch represents a repository branch
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct Branch {
+ pub commit: Option<PayloadCommit>,
+ pub effective_branch_protection_name: Option<String>,
+ pub enable_status_check: Option<bool>,
+ pub name: Option<String>,
+ pub protected: Option<bool>,
+ pub required_approvals: Option<u64>,
+ pub status_check_contexts: Option<Vec<String>>,
+ pub user_can_merge: Option<bool>,
+ pub user_can_push: Option<bool>,
+ }
+
+ /// BranchProtection represents a branch protection for a repository
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct BranchProtection {
+ pub approvals_whitelist_teams: Option<Vec<String>>,
+ pub approvals_whitelist_username: Option<Vec<String>>,
+ pub block_on_official_review_requests: Option<bool>,
+ pub block_on_outdated_branch: Option<bool>,
+ pub block_on_rejected_reviews: Option<bool>,
+ pub branch_name: Option<String>,
+ pub created_at: Option<time::OffsetDateTime>,
+ pub dismiss_stale_approvals: Option<bool>,
+ pub enable_approvals_whitelist: Option<bool>,
+ pub enable_merge_whitelist: Option<bool>,
+ pub enable_push: Option<bool>,
+ pub enable_push_whitelist: Option<bool>,
+ pub enable_status_check: Option<bool>,
+ pub merge_whitelist_teams: Option<Vec<String>>,
+ pub merge_whitelist_usernames: Option<Vec<String>>,
+ pub protected_file_patterns: Option<String>,
+ pub push_whitelist_deploy_keys: Option<bool>,
+ pub push_whitelist_teams: Option<Vec<String>>,
+ pub push_whitelist_usernames: Option<Vec<String>>,
+ pub require_signed_commits: Option<bool>,
+ pub required_approvals: Option<u64>,
+ pub rule_name: Option<String>,
+ pub status_check_contexts: Option<Vec<String>>,
+ pub unprotected_file_patterns: Option<String>,
+ pub updated_at: Option<time::OffsetDateTime>,
+ }
+
+ /// ChangeFileOperation for creating, updating or deleting a file
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct ChangeFileOperation {
+ pub content: Option<String>,
+ pub from_path: Option<String>,
+ pub operation: String,
+ pub path: String,
+ pub sha: Option<String>,
+ }
+
+ /// ChangeFilesOptions options for creating, updating or deleting multiple files
+ ///
+ /// Note: `author` and `committer` are optional (if only one is given, it will be used for the other, otherwise the authenticated user will be used)
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct ChangeFilesOptions {
+ pub author: Option<Identity>,
+ pub branch: Option<String>,
+ pub committer: Option<Identity>,
+ pub dates: Option<CommitDateOptions>,
+ pub files: Vec<ChangeFileOperation>,
+ pub message: Option<String>,
+ pub new_branch: Option<String>,
+ pub signoff: Option<bool>,
+ }
+
+ /// ChangedFile store information about files affected by the pull request
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct ChangedFile {
+ pub additions: Option<u64>,
+ pub changes: Option<u64>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub contents_url: Option<url::Url>,
+ pub deletions: Option<u64>,
+ pub filename: Option<String>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub html_url: Option<url::Url>,
+ pub previous_filename: Option<String>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub raw_url: Option<url::Url>,
+ pub status: Option<String>,
+ }
+
+ /// CombinedStatus holds the combined state of several statuses for a single commit
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct CombinedStatus {
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub commit_url: Option<url::Url>,
+ pub repository: Option<Repository>,
+ pub sha: Option<String>,
+ pub state: Option<String>,
+ pub statuses: Option<Vec<CommitStatus>>,
+ pub total_count: Option<u64>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub url: Option<url::Url>,
+ }
+
+ /// Comment represents a comment on a commit or issue
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct Comment {
+ pub assets: Option<Vec<Attachment>>,
+ pub body: Option<String>,
+ pub created_at: Option<time::OffsetDateTime>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub html_url: Option<url::Url>,
+ pub id: Option<u64>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub issue_url: Option<url::Url>,
+ pub original_author: Option<String>,
+ pub original_author_id: Option<u64>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub pull_request_url: Option<url::Url>,
+ pub updated_at: Option<time::OffsetDateTime>,
+ pub user: Option<User>,
+ }
+
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct Commit {
+ pub author: Option<User>,
+ pub commit: Option<RepoCommit>,
+ pub committer: Option<User>,
+ pub created: Option<time::OffsetDateTime>,
+ pub files: Option<Vec<CommitAffectedFiles>>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub html_url: Option<url::Url>,
+ pub parents: Option<Vec<CommitMeta>>,
+ pub sha: Option<String>,
+ pub stats: Option<CommitStats>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub url: Option<url::Url>,
+ }
+
+ /// CommitAffectedFiles store information about files affected by the commit
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct CommitAffectedFiles {
+ pub filename: Option<String>,
+ pub status: Option<String>,
+ }
+
+ /// CommitDateOptions store dates for GIT_AUTHOR_DATE and GIT_COMMITTER_DATE
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct CommitDateOptions {
+ pub author: Option<time::OffsetDateTime>,
+ pub committer: Option<time::OffsetDateTime>,
+ }
+
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct CommitMeta {
+ pub created: Option<time::OffsetDateTime>,
+ pub sha: Option<String>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub url: Option<url::Url>,
+ }
+
+ /// CommitStats is statistics for a RepoCommit
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct CommitStats {
+ pub additions: Option<u64>,
+ pub deletions: Option<u64>,
+ pub total: Option<u64>,
+ }
+
+ /// CommitStatus holds a single status of a single Commit
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct CommitStatus {
+ pub context: Option<String>,
+ pub created_at: Option<time::OffsetDateTime>,
+ pub creator: Option<User>,
+ pub description: Option<String>,
+ pub id: Option<u64>,
+ pub status: Option<String>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub target_url: Option<url::Url>,
+ pub updated_at: Option<time::OffsetDateTime>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub url: Option<url::Url>,
+ }
+
+ /// CommitStatusState holds the state of a CommitStatus
+ ///
+ /// It can be "pending", "success", "error" and "failure"
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct CommitStatusState {}
+
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct CommitUser {
+ pub date: Option<String>,
+ pub email: Option<String>,
+ pub name: Option<String>,
+ }
+
+ /// ContentsResponse contains information about a repo's entry's (dir, file, symlink, submodule) metadata and content
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct ContentsResponse {
+ #[serde(rename = "_links")]
+ pub links: Option<FileLinksResponse>,
+ pub content: Option<String>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub download_url: Option<url::Url>,
+ pub encoding: Option<String>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub git_url: Option<url::Url>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub html_url: Option<url::Url>,
+ pub last_commit_sha: Option<String>,
+ pub name: Option<String>,
+ pub path: Option<String>,
+ pub sha: Option<String>,
+ pub size: Option<u64>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub submodule_git_url: Option<url::Url>,
+ pub target: Option<String>,
+ #[serde(rename = "type")]
+ pub r#type: Option<String>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub url: Option<url::Url>,
+ }
+
+ /// CreateAccessTokenOption options when create access token
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct CreateAccessTokenOption {
+ pub name: String,
+ pub scopes: Option<Vec<String>>,
+ }
+
+ /// CreateBranchProtectionOption options for creating a branch protection
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct CreateBranchProtectionOption {
+ pub approvals_whitelist_teams: Option<Vec<String>>,
+ pub approvals_whitelist_username: Option<Vec<String>>,
+ pub block_on_official_review_requests: Option<bool>,
+ pub block_on_outdated_branch: Option<bool>,
+ pub block_on_rejected_reviews: Option<bool>,
+ pub branch_name: Option<String>,
+ pub dismiss_stale_approvals: Option<bool>,
+ pub enable_approvals_whitelist: Option<bool>,
+ pub enable_merge_whitelist: Option<bool>,
+ pub enable_push: Option<bool>,
+ pub enable_push_whitelist: Option<bool>,
+ pub enable_status_check: Option<bool>,
+ pub merge_whitelist_teams: Option<Vec<String>>,
+ pub merge_whitelist_usernames: Option<Vec<String>>,
+ pub protected_file_patterns: Option<String>,
+ pub push_whitelist_deploy_keys: Option<bool>,
+ pub push_whitelist_teams: Option<Vec<String>>,
+ pub push_whitelist_usernames: Option<Vec<String>>,
+ pub require_signed_commits: Option<bool>,
+ pub required_approvals: Option<u64>,
+ pub rule_name: Option<String>,
+ pub status_check_contexts: Option<Vec<String>>,
+ pub unprotected_file_patterns: Option<String>,
+ }
+
+ /// CreateBranchRepoOption options when creating a branch in a repository
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct CreateBranchRepoOption {
+ pub new_branch_name: String,
+ pub old_branch_name: Option<String>,
+ pub old_ref_name: Option<String>,
+ }
+
+ /// CreateEmailOption options when creating email addresses
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct CreateEmailOption {
+ pub emails: Option<Vec<String>>,
+ }
+
+ /// CreateFileOptions options for creating files
+ ///
+ /// Note: `author` and `committer` are optional (if only one is given, it will be used for the other, otherwise the authenticated user will be used)
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct CreateFileOptions {
+ pub author: Option<Identity>,
+ pub branch: Option<String>,
+ pub committer: Option<Identity>,
+ pub content: String,
+ pub dates: Option<CommitDateOptions>,
+ pub message: Option<String>,
+ pub new_branch: Option<String>,
+ pub signoff: Option<bool>,
+ }
+
+ /// CreateForkOption options for creating a fork
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct CreateForkOption {
+ pub name: Option<String>,
+ pub organization: Option<String>,
+ }
+
+ /// CreateGPGKeyOption options create user GPG key
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct CreateGPGKeyOption {
+ pub armored_public_key: String,
+ pub armored_signature: Option<String>,
+ }
+
+ /// CreateHookOption options when create a hook
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct CreateHookOption {
+ pub active: Option<bool>,
+ pub authorization_header: Option<String>,
+ pub branch_filter: Option<String>,
+ pub config: CreateHookOptionConfig,
+ pub events: Option<Vec<String>>,
+ #[serde(rename = "type")]
+ pub r#type: String,
+ }
+
+ /// CreateHookOptionConfig has all config options in it
+ ///
+ /// required are "content_type" and "url" Required
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct CreateHookOptionConfig {}
+
+ /// CreateIssueCommentOption options for creating a comment on an issue
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct CreateIssueCommentOption {
+ pub body: String,
+ pub updated_at: Option<time::OffsetDateTime>,
+ }
+
+ /// CreateIssueOption options to create one issue
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct CreateIssueOption {
+ pub assignee: Option<String>,
+ pub assignees: Option<Vec<String>>,
+ pub body: Option<String>,
+ pub closed: Option<bool>,
+ pub due_date: Option<time::OffsetDateTime>,
+ pub labels: Option<Vec<u64>>,
+ pub milestone: Option<u64>,
+ #[serde(rename = "ref")]
+ pub r#ref: Option<String>,
+ pub title: String,
+ }
+
+ /// CreateKeyOption options when creating a key
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct CreateKeyOption {
+ pub key: String,
+ pub read_only: Option<bool>,
+ pub title: String,
+ }
+
+ /// CreateLabelOption options for creating a label
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct CreateLabelOption {
+ pub color: String,
+ pub description: Option<String>,
+ pub exclusive: Option<bool>,
+ pub is_archived: Option<bool>,
+ pub name: String,
+ }
+
+ /// CreateMilestoneOption options for creating a milestone
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct CreateMilestoneOption {
+ pub description: Option<String>,
+ pub due_on: Option<time::OffsetDateTime>,
+ pub state: Option<String>,
+ pub title: Option<String>,
+ }
+
+ /// CreateOAuth2ApplicationOptions holds options to create an oauth2 application
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct CreateOAuth2ApplicationOptions {
+ pub confidential_client: Option<bool>,
+ pub name: Option<String>,
+ pub redirect_uris: Option<Vec<String>>,
+ }
+
+ /// CreateOrUpdateSecretOption options when creating or updating secret
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct CreateOrUpdateSecretOption {
+ pub data: String,
+ }
+
+ /// CreateOrgOption options for creating an organization
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct CreateOrgOption {
+ pub description: Option<String>,
+ pub email: Option<String>,
+ pub full_name: Option<String>,
+ pub location: Option<String>,
+ pub repo_admin_change_team_access: Option<bool>,
+ pub username: String,
+ pub visibility: Option<String>,
+ pub website: Option<String>,
+ }
+
+ /// CreatePullRequestOption options when creating a pull request
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct CreatePullRequestOption {
+ pub assignee: Option<String>,
+ pub assignees: Option<Vec<String>>,
+ pub base: Option<String>,
+ pub body: Option<String>,
+ pub due_date: Option<time::OffsetDateTime>,
+ pub head: Option<String>,
+ pub labels: Option<Vec<u64>>,
+ pub milestone: Option<u64>,
+ pub title: Option<String>,
+ }
+
+ /// CreatePullReviewComment represent a review comment for creation api
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct CreatePullReviewComment {
+ pub body: Option<String>,
+ pub new_position: Option<u64>,
+ pub old_position: Option<u64>,
+ pub path: Option<String>,
+ }
+
+ /// CreatePullReviewOptions are options to create a pull review
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct CreatePullReviewOptions {
+ pub body: Option<String>,
+ pub comments: Option<Vec<CreatePullReviewComment>>,
+ pub commit_id: Option<String>,
+ pub event: Option<String>,
+ }
+
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct CreatePushMirrorOption {
+ pub interval: Option<String>,
+ pub remote_address: Option<String>,
+ pub remote_password: Option<String>,
+ pub remote_username: Option<String>,
+ pub sync_on_commit: Option<bool>,
+ }
+
+ /// CreateReleaseOption options when creating a release
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct CreateReleaseOption {
+ pub body: Option<String>,
+ pub draft: Option<bool>,
+ pub name: Option<String>,
+ pub prerelease: Option<bool>,
+ pub tag_name: String,
+ pub target_commitish: Option<String>,
+ }
+
+ /// CreateRepoOption options when creating repository
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct CreateRepoOption {
+ pub auto_init: Option<bool>,
+ pub default_branch: Option<String>,
+ pub description: Option<String>,
+ pub gitignores: Option<String>,
+ pub issue_labels: Option<String>,
+ pub license: Option<String>,
+ pub name: String,
+ pub private: Option<bool>,
+ pub readme: Option<String>,
+ pub template: Option<bool>,
+ pub trust_model: Option<String>,
+ }
+
+ /// CreateStatusOption holds the information needed to create a new CommitStatus for a Commit
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct CreateStatusOption {
+ pub context: Option<String>,
+ pub description: Option<String>,
+ pub state: Option<String>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub target_url: Option<url::Url>,
+ }
+
+ /// CreateTagOption options when creating a tag
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct CreateTagOption {
+ pub message: Option<String>,
+ pub tag_name: String,
+ pub target: Option<String>,
+ }
+
+ /// CreateTeamOption options for creating a team
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct CreateTeamOption {
+ pub can_create_org_repo: Option<bool>,
+ pub description: Option<String>,
+ pub includes_all_repositories: Option<bool>,
+ pub name: String,
+ pub permission: Option<String>,
+ pub units: Option<Vec<String>>,
+ pub units_map: Option<serde_json::Map<String, serde_json::Value>>,
+ }
+
+ /// CreateUserOption create user options
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct CreateUserOption {
+ pub created_at: Option<time::OffsetDateTime>,
+ pub email: String,
+ pub full_name: Option<String>,
+ pub login_name: Option<String>,
+ pub must_change_password: Option<bool>,
+ pub password: Option<String>,
+ pub restricted: Option<bool>,
+ pub send_notify: Option<bool>,
+ pub source_id: Option<u64>,
+ pub username: String,
+ pub visibility: Option<String>,
+ }
+
+ /// CreateWikiPageOptions form for creating wiki
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct CreateWikiPageOptions {
+ pub content_base64: Option<String>,
+ pub message: Option<String>,
+ pub title: Option<String>,
+ }
+
+ /// Cron represents a Cron task
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct Cron {
+ pub exec_times: Option<u64>,
+ pub name: Option<String>,
+ pub next: Option<time::OffsetDateTime>,
+ pub prev: Option<time::OffsetDateTime>,
+ pub schedule: Option<String>,
+ }
+
+ /// DeleteEmailOption options when deleting email addresses
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct DeleteEmailOption {
+ pub emails: Option<Vec<String>>,
+ }
+
+ /// DeleteFileOptions options for deleting files (used for other File structs below)
+ ///
+ /// Note: `author` and `committer` are optional (if only one is given, it will be used for the other, otherwise the authenticated user will be used)
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct DeleteFileOptions {
+ pub author: Option<Identity>,
+ pub branch: Option<String>,
+ pub committer: Option<Identity>,
+ pub dates: Option<CommitDateOptions>,
+ pub message: Option<String>,
+ pub new_branch: Option<String>,
+ pub sha: String,
+ pub signoff: Option<bool>,
+ }
+
+ /// DeleteLabelOption options for deleting a label
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct DeleteLabelsOption {
+ pub updated_at: Option<time::OffsetDateTime>,
+ }
+
+ /// DeployKey a deploy key
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct DeployKey {
+ pub created_at: Option<time::OffsetDateTime>,
+ pub fingerprint: Option<String>,
+ pub id: Option<u64>,
+ pub key: Option<String>,
+ pub key_id: Option<u64>,
+ pub read_only: Option<bool>,
+ pub repository: Option<Repository>,
+ pub title: Option<String>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub url: Option<url::Url>,
+ }
+
+ /// DismissPullReviewOptions are options to dismiss a pull review
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct DismissPullReviewOptions {
+ pub message: Option<String>,
+ pub priors: Option<bool>,
+ }
+
+ /// EditAttachmentOptions options for editing attachments
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct EditAttachmentOptions {
+ pub name: Option<String>,
+ }
+
+ /// EditBranchProtectionOption options for editing a branch protection
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct EditBranchProtectionOption {
+ pub approvals_whitelist_teams: Option<Vec<String>>,
+ pub approvals_whitelist_username: Option<Vec<String>>,
+ pub block_on_official_review_requests: Option<bool>,
+ pub block_on_outdated_branch: Option<bool>,
+ pub block_on_rejected_reviews: Option<bool>,
+ pub dismiss_stale_approvals: Option<bool>,
+ pub enable_approvals_whitelist: Option<bool>,
+ pub enable_merge_whitelist: Option<bool>,
+ pub enable_push: Option<bool>,
+ pub enable_push_whitelist: Option<bool>,
+ pub enable_status_check: Option<bool>,
+ pub merge_whitelist_teams: Option<Vec<String>>,
+ pub merge_whitelist_usernames: Option<Vec<String>>,
+ pub protected_file_patterns: Option<String>,
+ pub push_whitelist_deploy_keys: Option<bool>,
+ pub push_whitelist_teams: Option<Vec<String>>,
+ pub push_whitelist_usernames: Option<Vec<String>>,
+ pub require_signed_commits: Option<bool>,
+ pub required_approvals: Option<u64>,
+ pub status_check_contexts: Option<Vec<String>>,
+ pub unprotected_file_patterns: Option<String>,
+ }
+
+ /// EditDeadlineOption options for creating a deadline
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct EditDeadlineOption {
+ pub due_date: time::OffsetDateTime,
+ }
+
+ /// EditGitHookOption options when modifying one Git hook
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct EditGitHookOption {
+ pub content: Option<String>,
+ }
+
+ /// EditHookOption options when modify one hook
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct EditHookOption {
+ pub active: Option<bool>,
+ pub authorization_header: Option<String>,
+ pub branch_filter: Option<String>,
+ pub config: Option<serde_json::Map<String, serde_json::Value>>,
+ pub events: Option<Vec<String>>,
+ }
+
+ /// EditIssueCommentOption options for editing a comment
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct EditIssueCommentOption {
+ pub body: String,
+ pub updated_at: Option<time::OffsetDateTime>,
+ }
+
+ /// EditIssueOption options for editing an issue
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct EditIssueOption {
+ pub assignee: Option<String>,
+ pub assignees: Option<Vec<String>>,
+ pub body: Option<String>,
+ pub due_date: Option<time::OffsetDateTime>,
+ pub milestone: Option<u64>,
+ #[serde(rename = "ref")]
+ pub r#ref: Option<String>,
+ pub state: Option<String>,
+ pub title: Option<String>,
+ pub unset_due_date: Option<bool>,
+ pub updated_at: Option<time::OffsetDateTime>,
+ }
+
+ /// EditLabelOption options for editing a label
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct EditLabelOption {
+ pub color: Option<String>,
+ pub description: Option<String>,
+ pub exclusive: Option<bool>,
+ pub is_archived: Option<bool>,
+ pub name: Option<String>,
+ }
+
+ /// EditMilestoneOption options for editing a milestone
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct EditMilestoneOption {
+ pub description: Option<String>,
+ pub due_on: Option<time::OffsetDateTime>,
+ pub state: Option<String>,
+ pub title: Option<String>,
+ }
+
+ /// EditOrgOption options for editing an organization
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct EditOrgOption {
+ pub description: Option<String>,
+ pub email: Option<String>,
+ pub full_name: Option<String>,
+ pub location: Option<String>,
+ pub repo_admin_change_team_access: Option<bool>,
+ pub visibility: Option<String>,
+ pub website: Option<String>,
+ }
+
+ /// EditPullRequestOption options when modify pull request
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct EditPullRequestOption {
+ pub allow_maintainer_edit: Option<bool>,
+ pub assignee: Option<String>,
+ pub assignees: Option<Vec<String>>,
+ pub base: Option<String>,
+ pub body: Option<String>,
+ pub due_date: Option<time::OffsetDateTime>,
+ pub labels: Option<Vec<u64>>,
+ pub milestone: Option<u64>,
+ pub state: Option<String>,
+ pub title: Option<String>,
+ pub unset_due_date: Option<bool>,
+ }
+
+ /// EditReactionOption contain the reaction type
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct EditReactionOption {
+ pub content: Option<String>,
+ }
+
+ /// EditReleaseOption options when editing a release
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct EditReleaseOption {
+ pub body: Option<String>,
+ pub draft: Option<bool>,
+ pub name: Option<String>,
+ pub prerelease: Option<bool>,
+ pub tag_name: Option<String>,
+ pub target_commitish: Option<String>,
+ }
+
+ /// EditRepoOption options when editing a repository's properties
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct EditRepoOption {
+ pub allow_manual_merge: Option<bool>,
+ pub allow_merge_commits: Option<bool>,
+ pub allow_rebase: Option<bool>,
+ pub allow_rebase_explicit: Option<bool>,
+ pub allow_rebase_update: Option<bool>,
+ pub allow_squash_merge: Option<bool>,
+ pub archived: Option<bool>,
+ pub autodetect_manual_merge: Option<bool>,
+ pub default_allow_maintainer_edit: Option<bool>,
+ pub default_branch: Option<String>,
+ pub default_delete_branch_after_merge: Option<bool>,
+ pub default_merge_style: Option<String>,
+ pub description: Option<String>,
+ pub enable_prune: Option<bool>,
+ pub external_tracker: Option<ExternalTracker>,
+ pub external_wiki: Option<ExternalWiki>,
+ pub has_actions: Option<bool>,
+ pub has_issues: Option<bool>,
+ pub has_packages: Option<bool>,
+ pub has_projects: Option<bool>,
+ pub has_pull_requests: Option<bool>,
+ pub has_releases: Option<bool>,
+ pub has_wiki: Option<bool>,
+ pub ignore_whitespace_conflicts: Option<bool>,
+ pub internal_tracker: Option<InternalTracker>,
+ pub mirror_interval: Option<String>,
+ pub name: Option<String>,
+ pub private: Option<bool>,
+ pub template: Option<bool>,
+ pub website: Option<String>,
+ }
+
+ /// EditTeamOption options for editing a team
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct EditTeamOption {
+ pub can_create_org_repo: Option<bool>,
+ pub description: Option<String>,
+ pub includes_all_repositories: Option<bool>,
+ pub name: String,
+ pub permission: Option<String>,
+ pub units: Option<Vec<String>>,
+ pub units_map: Option<serde_json::Map<String, serde_json::Value>>,
+ }
+
+ /// EditUserOption edit user options
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct EditUserOption {
+ pub active: Option<bool>,
+ pub admin: Option<bool>,
+ pub allow_create_organization: Option<bool>,
+ pub allow_git_hook: Option<bool>,
+ pub allow_import_local: Option<bool>,
+ pub description: Option<String>,
+ pub email: Option<String>,
+ pub full_name: Option<String>,
+ pub location: Option<String>,
+ pub login_name: String,
+ pub max_repo_creation: Option<u64>,
+ pub must_change_password: Option<bool>,
+ pub password: Option<String>,
+ pub prohibit_login: Option<bool>,
+ pub restricted: Option<bool>,
+ pub source_id: u64,
+ pub visibility: Option<String>,
+ pub website: Option<String>,
+ }
+
+ /// Email an email address belonging to a user
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct Email {
+ pub email: Option<String>,
+ pub primary: Option<bool>,
+ pub user_id: Option<u64>,
+ pub username: Option<String>,
+ pub verified: Option<bool>,
+ }
+
+ /// ExternalTracker represents settings for external tracker
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct ExternalTracker {
+ pub external_tracker_format: Option<String>,
+ pub external_tracker_regexp_pattern: Option<String>,
+ pub external_tracker_style: Option<String>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub external_tracker_url: Option<url::Url>,
+ }
+
+ /// ExternalWiki represents setting for external wiki
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct ExternalWiki {
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub external_wiki_url: Option<url::Url>,
+ }
+
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct FileCommitResponse {
+ pub author: Option<CommitUser>,
+ pub committer: Option<CommitUser>,
+ pub created: Option<time::OffsetDateTime>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub html_url: Option<url::Url>,
+ pub message: Option<String>,
+ pub parents: Option<Vec<CommitMeta>>,
+ pub sha: Option<String>,
+ pub tree: Option<CommitMeta>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub url: Option<url::Url>,
+ }
+
+ /// FileDeleteResponse contains information about a repo's file that was deleted
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct FileDeleteResponse {
+ pub commit: Option<FileCommitResponse>,
+ pub content: Option<()>,
+ pub verification: Option<PayloadCommitVerification>,
+ }
+
+ /// FileLinksResponse contains the links for a repo's file
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct FileLinksResponse {
+ pub git: Option<String>,
+ pub html: Option<String>,
+ #[serde(rename = "self")]
+ pub this: Option<String>,
+ }
+
+ /// FileResponse contains information about a repo's file
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct FileResponse {
+ pub commit: Option<FileCommitResponse>,
+ pub content: Option<ContentsResponse>,
+ pub verification: Option<PayloadCommitVerification>,
+ }
+
+ /// FilesResponse contains information about multiple files from a repo
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct FilesResponse {
+ pub commit: Option<FileCommitResponse>,
+ pub files: Option<Vec<ContentsResponse>>,
+ pub verification: Option<PayloadCommitVerification>,
+ }
+
+ /// GPGKey a user GPG key to sign commit and tag in repository
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct GPGKey {
+ pub can_certify: Option<bool>,
+ pub can_encrypt_comms: Option<bool>,
+ pub can_encrypt_storage: Option<bool>,
+ pub can_sign: Option<bool>,
+ pub created_at: Option<time::OffsetDateTime>,
+ pub emails: Option<Vec<GPGKeyEmail>>,
+ pub expires_at: Option<time::OffsetDateTime>,
+ pub id: Option<u64>,
+ pub key_id: Option<String>,
+ pub primary_key_id: Option<String>,
+ pub public_key: Option<String>,
+ pub subkeys: Option<Vec<GPGKey>>,
+ pub verified: Option<bool>,
+ }
+
+ /// GPGKeyEmail an email attached to a GPGKey
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct GPGKeyEmail {
+ pub email: Option<String>,
+ pub verified: Option<bool>,
+ }
+
+ /// GeneralAPISettings contains global api settings exposed by it
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct GeneralAPISettings {
+ pub default_git_trees_per_page: Option<u64>,
+ pub default_max_blob_size: Option<u64>,
+ pub default_paging_num: Option<u64>,
+ pub max_response_items: Option<u64>,
+ }
+
+ /// GeneralAttachmentSettings contains global Attachment settings exposed by API
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct GeneralAttachmentSettings {
+ pub allowed_types: Option<String>,
+ pub enabled: Option<bool>,
+ pub max_files: Option<u64>,
+ pub max_size: Option<u64>,
+ }
+
+ /// GeneralRepoSettings contains global repository settings exposed by API
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct GeneralRepoSettings {
+ pub http_git_disabled: Option<bool>,
+ pub lfs_disabled: Option<bool>,
+ pub migrations_disabled: Option<bool>,
+ pub mirrors_disabled: Option<bool>,
+ pub stars_disabled: Option<bool>,
+ pub time_tracking_disabled: Option<bool>,
+ }
+
+ /// GeneralUISettings contains global ui settings exposed by API
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct GeneralUISettings {
+ pub allowed_reactions: Option<Vec<String>>,
+ pub custom_emojis: Option<Vec<String>>,
+ pub default_theme: Option<String>,
+ }
+
+ /// GenerateRepoOption options when creating repository using a template
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct GenerateRepoOption {
+ pub avatar: Option<bool>,
+ pub default_branch: Option<String>,
+ pub description: Option<String>,
+ pub git_content: Option<bool>,
+ pub git_hooks: Option<bool>,
+ pub labels: Option<bool>,
+ pub name: String,
+ pub owner: String,
+ pub private: Option<bool>,
+ pub protected_branch: Option<bool>,
+ pub topics: Option<bool>,
+ pub webhooks: Option<bool>,
+ }
+
+ /// GitBlobResponse represents a git blob
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct GitBlobResponse {
+ pub content: Option<String>,
+ pub encoding: Option<String>,
+ pub sha: Option<String>,
+ pub size: Option<u64>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub url: Option<url::Url>,
+ }
+
+ /// GitEntry represents a git tree
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct GitEntry {
+ pub mode: Option<String>,
+ pub path: Option<String>,
+ pub sha: Option<String>,
+ pub size: Option<u64>,
+ #[serde(rename = "type")]
+ pub r#type: Option<String>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub url: Option<url::Url>,
+ }
+
+ /// GitHook represents a Git repository hook
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct GitHook {
+ pub content: Option<String>,
+ pub is_active: Option<bool>,
+ pub name: Option<String>,
+ }
+
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct GitObject {
+ pub sha: Option<String>,
+ #[serde(rename = "type")]
+ pub r#type: Option<String>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub url: Option<url::Url>,
+ }
+
+ /// GitTreeResponse returns a git tree
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct GitTreeResponse {
+ pub page: Option<u64>,
+ pub sha: Option<String>,
+ pub total_count: Option<u64>,
+ pub tree: Option<Vec<GitEntry>>,
+ pub truncated: Option<bool>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub url: Option<url::Url>,
+ }
+
+ /// GitignoreTemplateInfo name and text of a gitignore template
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct GitignoreTemplateInfo {
+ pub name: Option<String>,
+ pub source: Option<String>,
+ }
+
+ /// Hook a hook is a web hook when one repository changed
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct Hook {
+ pub active: Option<bool>,
+ pub authorization_header: Option<String>,
+ pub branch_filter: Option<String>,
+ pub config: Option<serde_json::Map<String, serde_json::Value>>,
+ pub created_at: Option<time::OffsetDateTime>,
+ pub events: Option<Vec<String>>,
+ pub id: Option<u64>,
+ #[serde(rename = "type")]
+ pub r#type: Option<String>,
+ pub updated_at: Option<time::OffsetDateTime>,
+ }
+
+ /// Identity for a person's identity like an author or committer
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct Identity {
+ pub email: Option<String>,
+ pub name: Option<String>,
+ }
+
+ /// InternalTracker represents settings for internal tracker
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct InternalTracker {
+ pub allow_only_contributors_to_track_time: Option<bool>,
+ pub enable_issue_dependencies: Option<bool>,
+ pub enable_time_tracker: Option<bool>,
+ }
+
+ /// Issue represents an issue in a repository
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct Issue {
+ pub assets: Option<Vec<Attachment>>,
+ pub assignee: Option<User>,
+ pub assignees: Option<Vec<User>>,
+ pub body: Option<String>,
+ pub closed_at: Option<time::OffsetDateTime>,
+ pub comments: Option<u64>,
+ pub created_at: Option<time::OffsetDateTime>,
+ pub due_date: Option<time::OffsetDateTime>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub html_url: Option<url::Url>,
+ pub id: Option<u64>,
+ pub is_locked: Option<bool>,
+ pub labels: Option<Vec<Label>>,
+ pub milestone: Option<Milestone>,
+ pub number: Option<u64>,
+ pub original_author: Option<String>,
+ pub original_author_id: Option<u64>,
+ pub pin_order: Option<u64>,
+ pub pull_request: Option<PullRequestMeta>,
+ #[serde(rename = "ref")]
+ pub r#ref: Option<String>,
+ pub repository: Option<RepositoryMeta>,
+ pub state: Option<String>,
+ pub title: Option<String>,
+ pub updated_at: Option<time::OffsetDateTime>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub url: Option<url::Url>,
+ pub user: Option<User>,
+ }
+
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct IssueConfig {
+ pub blank_issues_enabled: Option<bool>,
+ pub contact_links: Option<Vec<IssueConfigContactLink>>,
+ }
+
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct IssueConfigContactLink {
+ pub about: Option<String>,
+ pub name: Option<String>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub url: Option<url::Url>,
+ }
+
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct IssueConfigValidation {
+ pub message: Option<String>,
+ pub valid: Option<bool>,
+ }
+
+ /// IssueDeadline represents an issue deadline
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct IssueDeadline {
+ pub due_date: Option<time::OffsetDateTime>,
+ }
+
+ /// IssueFormField represents a form field
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct IssueFormField {
+ pub attributes: Option<serde_json::Map<String, serde_json::Value>>,
+ pub id: Option<String>,
+ #[serde(rename = "type")]
+ pub r#type: Option<String>,
+ pub validations: Option<serde_json::Map<String, serde_json::Value>>,
+ }
+
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct IssueFormFieldType {}
+
+ /// IssueLabelsOption a collection of labels
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct IssueLabelsOption {
+ pub labels: Option<Vec<u64>>,
+ pub updated_at: Option<time::OffsetDateTime>,
+ }
+
+ /// IssueMeta basic issue information
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct IssueMeta {
+ pub index: Option<u64>,
+ pub owner: Option<String>,
+ pub repo: Option<String>,
+ }
+
+ /// IssueTemplate represents an issue template for a repository
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct IssueTemplate {
+ pub about: Option<String>,
+ pub body: Option<Vec<IssueFormField>>,
+ pub content: Option<String>,
+ pub file_name: Option<String>,
+ pub labels: Option<Vec<String>>,
+ pub name: Option<String>,
+ #[serde(rename = "ref")]
+ pub r#ref: Option<String>,
+ pub title: Option<String>,
+ }
+
+ /// Label a label to an issue or a pr
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct Label {
+ pub color: Option<String>,
+ pub description: Option<String>,
+ pub exclusive: Option<bool>,
+ pub id: Option<u64>,
+ pub is_archived: Option<bool>,
+ pub name: Option<String>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub url: Option<url::Url>,
+ }
+
+ /// LabelTemplate info of a Label template
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct LabelTemplate {
+ pub color: Option<String>,
+ pub description: Option<String>,
+ pub exclusive: Option<bool>,
+ pub name: Option<String>,
+ }
+
+ /// LicensesInfo contains information about a License
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct LicenseTemplateInfo {
+ pub body: Option<String>,
+ pub implementation: Option<String>,
+ pub key: Option<String>,
+ pub name: Option<String>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub url: Option<url::Url>,
+ }
+
+ /// LicensesListEntry is used for the API
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct LicensesTemplateListEntry {
+ pub key: Option<String>,
+ pub name: Option<String>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub url: Option<url::Url>,
+ }
+
+ /// MarkdownOption markdown options
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct MarkdownOption {
+ #[serde(rename = "Context")]
+ pub context: Option<String>,
+ #[serde(rename = "Mode")]
+ pub mode: Option<String>,
+ #[serde(rename = "Text")]
+ pub text: Option<String>,
+ #[serde(rename = "Wiki")]
+ pub wiki: Option<bool>,
+ }
+
+ /// MarkupOption markup options
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct MarkupOption {
+ #[serde(rename = "Context")]
+ pub context: Option<String>,
+ #[serde(rename = "FilePath")]
+ pub file_path: Option<String>,
+ #[serde(rename = "Mode")]
+ pub mode: Option<String>,
+ #[serde(rename = "Text")]
+ pub text: Option<String>,
+ #[serde(rename = "Wiki")]
+ pub wiki: Option<bool>,
+ }
+
+ /// MergePullRequestForm form for merging Pull Request
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct MergePullRequestOption {
+ #[serde(rename = "Do")]
+ pub r#do: String,
+ #[serde(rename = "MergeCommitID")]
+ pub merge_commit_id: Option<String>,
+ #[serde(rename = "MergeMessageField")]
+ pub merge_message_field: Option<String>,
+ #[serde(rename = "MergeTitleField")]
+ pub merge_title_field: Option<String>,
+ pub delete_branch_after_merge: Option<bool>,
+ pub force_merge: Option<bool>,
+ pub head_commit_id: Option<String>,
+ pub merge_when_checks_succeed: Option<bool>,
+ }
+
+ /// MigrateRepoOptions options for migrating repository's
+ ///
+ /// this is used to interact with api v1
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct MigrateRepoOptions {
+ pub auth_password: Option<String>,
+ pub auth_token: Option<String>,
+ pub auth_username: Option<String>,
+ pub clone_addr: String,
+ pub description: Option<String>,
+ pub issues: Option<bool>,
+ pub labels: Option<bool>,
+ pub lfs: Option<bool>,
+ pub lfs_endpoint: Option<String>,
+ pub milestones: Option<bool>,
+ pub mirror: Option<bool>,
+ pub mirror_interval: Option<String>,
+ pub private: Option<bool>,
+ pub pull_requests: Option<bool>,
+ pub releases: Option<bool>,
+ pub repo_name: String,
+ pub repo_owner: Option<String>,
+ pub service: Option<String>,
+ pub uid: Option<u64>,
+ pub wiki: Option<bool>,
+ }
+
+ /// Milestone milestone is a collection of issues on one repository
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct Milestone {
+ pub closed_at: Option<time::OffsetDateTime>,
+ pub closed_issues: Option<u64>,
+ pub created_at: Option<time::OffsetDateTime>,
+ pub description: Option<String>,
+ pub due_on: Option<time::OffsetDateTime>,
+ pub id: Option<u64>,
+ pub open_issues: Option<u64>,
+ pub state: Option<String>,
+ pub title: Option<String>,
+ pub updated_at: Option<time::OffsetDateTime>,
+ }
+
+ /// NewIssuePinsAllowed represents an API response that says if new Issue Pins are allowed
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct NewIssuePinsAllowed {
+ pub issues: Option<bool>,
+ pub pull_requests: Option<bool>,
+ }
+
+ /// NodeInfo contains standardized way of exposing metadata about a server running one of the distributed social networks
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct NodeInfo {
+ pub metadata: Option<serde_json::Map<String, serde_json::Value>>,
+ #[serde(rename = "openRegistrations")]
+ pub open_registrations: Option<bool>,
+ pub protocols: Option<Vec<String>>,
+ pub services: Option<NodeInfoServices>,
+ pub software: Option<NodeInfoSoftware>,
+ pub usage: Option<NodeInfoUsage>,
+ pub version: Option<String>,
+ }
+
+ /// NodeInfoServices contains the third party sites this server can connect to via their application API
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct NodeInfoServices {
+ pub inbound: Option<Vec<String>>,
+ pub outbound: Option<Vec<String>>,
+ }
+
+ /// NodeInfoSoftware contains Metadata about server software in use
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct NodeInfoSoftware {
+ pub homepage: Option<String>,
+ pub name: Option<String>,
+ pub repository: Option<String>,
+ pub version: Option<String>,
+ }
+
+ /// NodeInfoUsage contains usage statistics for this server
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct NodeInfoUsage {
+ #[serde(rename = "localComments")]
+ pub local_comments: Option<u64>,
+ #[serde(rename = "localPosts")]
+ pub local_posts: Option<u64>,
+ pub users: Option<NodeInfoUsageUsers>,
+ }
+
+ /// NodeInfoUsageUsers contains statistics about the users of this server
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct NodeInfoUsageUsers {
+ #[serde(rename = "activeHalfyear")]
+ pub active_halfyear: Option<u64>,
+ #[serde(rename = "activeMonth")]
+ pub active_month: Option<u64>,
+ pub total: Option<u64>,
+ }
+
+ /// Note contains information related to a git note
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct Note {
+ pub commit: Option<Commit>,
+ pub message: Option<String>,
+ }
+
+ /// NotificationCount number of unread notifications
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct NotificationCount {
+ pub new: Option<u64>,
+ }
+
+ /// NotificationSubject contains the notification subject (Issue/Pull/Commit)
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct NotificationSubject {
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub html_url: Option<url::Url>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub latest_comment_html_url: Option<url::Url>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub latest_comment_url: Option<url::Url>,
+ pub state: Option<String>,
+ pub title: Option<String>,
+ #[serde(rename = "type")]
+ pub r#type: Option<String>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub url: Option<url::Url>,
+ }
+
+ /// NotificationThread expose Notification on API
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct NotificationThread {
+ pub id: Option<u64>,
+ pub pinned: Option<bool>,
+ pub repository: Option<Repository>,
+ pub subject: Option<NotificationSubject>,
+ pub unread: Option<bool>,
+ pub updated_at: Option<time::OffsetDateTime>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub url: Option<url::Url>,
+ }
+
+ /// NotifySubjectType represent type of notification subject
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct NotifySubjectType {}
+
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct OAuth2Application {
+ pub client_id: Option<String>,
+ pub client_secret: Option<String>,
+ pub confidential_client: Option<bool>,
+ pub created: Option<time::OffsetDateTime>,
+ pub id: Option<u64>,
+ pub name: Option<String>,
+ pub redirect_uris: Option<Vec<String>>,
+ }
+
+ /// Organization represents an organization
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct Organization {
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub avatar_url: Option<url::Url>,
+ pub description: Option<String>,
+ pub email: Option<String>,
+ pub full_name: Option<String>,
+ pub id: Option<u64>,
+ pub location: Option<String>,
+ pub name: Option<String>,
+ pub repo_admin_change_team_access: Option<bool>,
+ pub username: Option<String>,
+ pub visibility: Option<String>,
+ pub website: Option<String>,
+ }
+
+ /// OrganizationPermissions list different users permissions on an organization
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct OrganizationPermissions {
+ pub can_create_repository: Option<bool>,
+ pub can_read: Option<bool>,
+ pub can_write: Option<bool>,
+ pub is_admin: Option<bool>,
+ pub is_owner: Option<bool>,
+ }
+
+ /// PRBranchInfo information about a branch
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct PRBranchInfo {
+ pub label: Option<String>,
+ #[serde(rename = "ref")]
+ pub r#ref: Option<String>,
+ pub repo: Option<Repository>,
+ pub repo_id: Option<u64>,
+ pub sha: Option<String>,
+ }
+
+ /// Package represents a package
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct Package {
+ pub created_at: Option<time::OffsetDateTime>,
+ pub creator: Option<User>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub html_url: Option<url::Url>,
+ pub id: Option<u64>,
+ pub name: Option<String>,
+ pub owner: Option<User>,
+ pub repository: Option<Repository>,
+ #[serde(rename = "type")]
+ pub r#type: Option<String>,
+ pub version: Option<String>,
+ }
+
+ /// PackageFile represents a package file
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct PackageFile {
+ #[serde(rename = "Size")]
+ pub size: Option<u64>,
+ pub id: Option<u64>,
+ pub md5: Option<String>,
+ pub name: Option<String>,
+ pub sha1: Option<String>,
+ pub sha256: Option<String>,
+ pub sha512: Option<String>,
+ }
+
+ /// PayloadCommit represents a commit
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct PayloadCommit {
+ pub added: Option<Vec<String>>,
+ pub author: Option<PayloadUser>,
+ pub committer: Option<PayloadUser>,
+ pub id: Option<String>,
+ pub message: Option<String>,
+ pub modified: Option<Vec<String>>,
+ pub removed: Option<Vec<String>>,
+ pub timestamp: Option<time::OffsetDateTime>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub url: Option<url::Url>,
+ pub verification: Option<PayloadCommitVerification>,
+ }
+
+ /// PayloadCommitVerification represents the GPG verification of a commit
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct PayloadCommitVerification {
+ pub payload: Option<String>,
+ pub reason: Option<String>,
+ pub signature: Option<String>,
+ pub signer: Option<PayloadUser>,
+ pub verified: Option<bool>,
+ }
+
+ /// PayloadUser represents the author or committer of a commit
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct PayloadUser {
+ pub email: Option<String>,
+ pub name: Option<String>,
+ pub username: Option<String>,
+ }
+
+ /// Permission represents a set of permissions
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct Permission {
+ pub admin: Option<bool>,
+ pub pull: Option<bool>,
+ pub push: Option<bool>,
+ }
+
+ /// PublicKey publickey is a user key to push code to repository
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct PublicKey {
+ pub created_at: Option<time::OffsetDateTime>,
+ pub fingerprint: Option<String>,
+ pub id: Option<u64>,
+ pub key: Option<String>,
+ pub key_type: Option<String>,
+ pub read_only: Option<bool>,
+ pub title: Option<String>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub url: Option<url::Url>,
+ pub user: Option<User>,
+ }
+
+ /// PullRequest represents a pull request
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct PullRequest {
+ pub allow_maintainer_edit: Option<bool>,
+ pub assignee: Option<User>,
+ pub assignees: Option<Vec<User>>,
+ pub base: Option<PRBranchInfo>,
+ pub body: Option<String>,
+ pub closed_at: Option<time::OffsetDateTime>,
+ pub comments: Option<u64>,
+ pub created_at: Option<time::OffsetDateTime>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub diff_url: Option<url::Url>,
+ pub due_date: Option<time::OffsetDateTime>,
+ pub head: Option<PRBranchInfo>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub html_url: Option<url::Url>,
+ pub id: Option<u64>,
+ pub is_locked: Option<bool>,
+ pub labels: Option<Vec<Label>>,
+ pub merge_base: Option<String>,
+ pub merge_commit_sha: Option<String>,
+ pub mergeable: Option<bool>,
+ pub merged: Option<bool>,
+ pub merged_at: Option<time::OffsetDateTime>,
+ pub merged_by: Option<User>,
+ pub milestone: Option<Milestone>,
+ pub number: Option<u64>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub patch_url: Option<url::Url>,
+ pub pin_order: Option<u64>,
+ pub requested_reviewers: Option<Vec<User>>,
+ pub state: Option<String>,
+ pub title: Option<String>,
+ pub updated_at: Option<time::OffsetDateTime>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub url: Option<url::Url>,
+ pub user: Option<User>,
+ }
+
+ /// PullRequestMeta PR info if an issue is a PR
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct PullRequestMeta {
+ pub merged: Option<bool>,
+ pub merged_at: Option<time::OffsetDateTime>,
+ }
+
+ /// PullReview represents a pull request review
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct PullReview {
+ pub body: Option<String>,
+ pub comments_count: Option<u64>,
+ pub commit_id: Option<String>,
+ pub dismissed: Option<bool>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub html_url: Option<url::Url>,
+ pub id: Option<u64>,
+ pub official: Option<bool>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub pull_request_url: Option<url::Url>,
+ pub stale: Option<bool>,
+ pub state: Option<String>,
+ pub submitted_at: Option<time::OffsetDateTime>,
+ pub team: Option<Team>,
+ pub updated_at: Option<time::OffsetDateTime>,
+ pub user: Option<User>,
+ }
+
+ /// PullReviewComment represents a comment on a pull request review
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct PullReviewComment {
+ pub body: Option<String>,
+ pub commit_id: Option<String>,
+ pub created_at: Option<time::OffsetDateTime>,
+ pub diff_hunk: Option<String>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub html_url: Option<url::Url>,
+ pub id: Option<u64>,
+ pub original_commit_id: Option<String>,
+ pub original_position: Option<u32>,
+ pub path: Option<String>,
+ pub position: Option<u32>,
+ pub pull_request_review_id: Option<u64>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub pull_request_url: Option<url::Url>,
+ pub resolver: Option<User>,
+ pub updated_at: Option<time::OffsetDateTime>,
+ pub user: Option<User>,
+ }
+
+ /// PullReviewRequestOptions are options to add or remove pull review requests
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct PullReviewRequestOptions {
+ pub reviewers: Option<Vec<String>>,
+ pub team_reviewers: Option<Vec<String>>,
+ }
+
+ /// PushMirror represents information of a push mirror
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct PushMirror {
+ pub created: Option<String>,
+ pub interval: Option<String>,
+ pub last_error: Option<String>,
+ pub last_update: Option<String>,
+ pub remote_address: Option<String>,
+ pub remote_name: Option<String>,
+ pub repo_name: Option<String>,
+ pub sync_on_commit: Option<bool>,
+ }
+
+ /// Reaction contain one reaction
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct Reaction {
+ pub content: Option<String>,
+ pub created_at: Option<time::OffsetDateTime>,
+ pub user: Option<User>,
+ }
+
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct Reference {
+ pub object: Option<GitObject>,
+ #[serde(rename = "ref")]
+ pub r#ref: Option<String>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub url: Option<url::Url>,
+ }
+
+ /// Release represents a repository release
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct Release {
+ pub assets: Option<Vec<Attachment>>,
+ pub author: Option<User>,
+ pub body: Option<String>,
+ pub created_at: Option<time::OffsetDateTime>,
+ pub draft: Option<bool>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub html_url: Option<url::Url>,
+ pub id: Option<u64>,
+ pub name: Option<String>,
+ pub prerelease: Option<bool>,
+ pub published_at: Option<time::OffsetDateTime>,
+ pub tag_name: Option<String>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub tarball_url: Option<url::Url>,
+ pub target_commitish: Option<String>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub upload_url: Option<url::Url>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub url: Option<url::Url>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub zipball_url: Option<url::Url>,
+ }
+
+ /// RenameUserOption options when renaming a user
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct RenameUserOption {
+ pub new_username: String,
+ }
+
+ /// RepoCollaboratorPermission to get repository permission for a collaborator
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct RepoCollaboratorPermission {
+ pub permission: Option<String>,
+ pub role_name: Option<String>,
+ pub user: Option<User>,
+ }
+
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct RepoCommit {
+ pub author: Option<CommitUser>,
+ pub committer: Option<CommitUser>,
+ pub message: Option<String>,
+ pub tree: Option<CommitMeta>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub url: Option<url::Url>,
+ pub verification: Option<PayloadCommitVerification>,
+ }
+
+ /// RepoTopicOptions a collection of repo topic names
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct RepoTopicOptions {
+ pub topics: Option<Vec<String>>,
+ }
+
+ /// RepoTransfer represents a pending repo transfer
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct RepoTransfer {
+ pub doer: Option<User>,
+ pub recipient: Option<User>,
+ pub teams: Option<Vec<Team>>,
+ }
+
+ /// Repository represents a repository
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct Repository {
+ pub allow_merge_commits: Option<bool>,
+ pub allow_rebase: Option<bool>,
+ pub allow_rebase_explicit: Option<bool>,
+ pub allow_rebase_update: Option<bool>,
+ pub allow_squash_merge: Option<bool>,
+ pub archived: Option<bool>,
+ pub archived_at: Option<time::OffsetDateTime>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub avatar_url: Option<url::Url>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub clone_url: Option<url::Url>,
+ pub created_at: Option<time::OffsetDateTime>,
+ pub default_allow_maintainer_edit: Option<bool>,
+ pub default_branch: Option<String>,
+ pub default_delete_branch_after_merge: Option<bool>,
+ pub default_merge_style: Option<String>,
+ pub description: Option<String>,
+ pub empty: Option<bool>,
+ pub external_tracker: Option<ExternalTracker>,
+ pub external_wiki: Option<ExternalWiki>,
+ pub fork: Option<bool>,
+ pub forks_count: Option<u64>,
+ pub full_name: Option<String>,
+ pub has_actions: Option<bool>,
+ pub has_issues: Option<bool>,
+ pub has_packages: Option<bool>,
+ pub has_projects: Option<bool>,
+ pub has_pull_requests: Option<bool>,
+ pub has_releases: Option<bool>,
+ pub has_wiki: Option<bool>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub html_url: Option<url::Url>,
+ pub id: Option<u64>,
+ pub ignore_whitespace_conflicts: Option<bool>,
+ pub internal: Option<bool>,
+ pub internal_tracker: Option<InternalTracker>,
+ pub language: Option<String>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub languages_url: Option<url::Url>,
+ pub link: Option<String>,
+ pub mirror: Option<bool>,
+ pub mirror_interval: Option<String>,
+ pub mirror_updated: Option<time::OffsetDateTime>,
+ pub name: Option<String>,
+ pub open_issues_count: Option<u64>,
+ pub open_pr_counter: Option<u64>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub original_url: Option<url::Url>,
+ pub owner: Option<User>,
+ pub parent: Option<Box<Repository>>,
+ pub permissions: Option<Permission>,
+ pub private: Option<bool>,
+ pub release_counter: Option<u64>,
+ pub repo_transfer: Option<RepoTransfer>,
+ pub size: Option<u64>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub ssh_url: Option<url::Url>,
+ pub stars_count: Option<u64>,
+ pub template: Option<bool>,
+ pub updated_at: Option<time::OffsetDateTime>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub url: Option<url::Url>,
+ pub watchers_count: Option<u64>,
+ pub website: Option<String>,
+ }
+
+ /// RepositoryMeta basic repository information
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct RepositoryMeta {
+ pub full_name: Option<String>,
+ pub id: Option<u64>,
+ pub name: Option<String>,
+ pub owner: Option<String>,
+ }
+
+ /// ReviewStateType review state type
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct ReviewStateType {}
+
+ /// SearchResults results of a successful search
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct SearchResults {
+ pub data: Option<Vec<Repository>>,
+ pub ok: Option<bool>,
+ }
+
+ /// Secret represents a secret
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct Secret {
+ pub created_at: Option<time::OffsetDateTime>,
+ pub name: Option<String>,
+ }
+
+ /// ServerVersion wraps the version of the server
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct ServerVersion {
+ pub version: Option<String>,
+ }
+
+ /// StateType issue state type
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct StateType {}
+
+ /// StopWatch represent a running stopwatch
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct StopWatch {
+ pub created: Option<time::OffsetDateTime>,
+ pub duration: Option<String>,
+ pub issue_index: Option<u64>,
+ pub issue_title: Option<String>,
+ pub repo_name: Option<String>,
+ pub repo_owner_name: Option<String>,
+ pub seconds: Option<u64>,
+ }
+
+ /// SubmitPullReviewOptions are options to submit a pending pull review
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct SubmitPullReviewOptions {
+ pub body: Option<String>,
+ pub event: Option<String>,
+ }
+
+ /// Tag represents a repository tag
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct Tag {
+ pub commit: Option<CommitMeta>,
+ pub id: Option<String>,
+ pub message: Option<String>,
+ pub name: Option<String>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub tarball_url: Option<url::Url>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub zipball_url: Option<url::Url>,
+ }
+
+ /// Team represents a team in an organization
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct Team {
+ pub can_create_org_repo: Option<bool>,
+ pub description: Option<String>,
+ pub id: Option<u64>,
+ pub includes_all_repositories: Option<bool>,
+ pub name: Option<String>,
+ pub organization: Option<Organization>,
+ pub permission: Option<String>,
+ pub units: Option<Vec<String>>,
+ pub units_map: Option<serde_json::Map<String, serde_json::Value>>,
+ }
+
+ /// TimeStamp defines a timestamp
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct TimeStamp {}
+
+ /// TimelineComment represents a timeline comment (comment of any type) on a commit or issue
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct TimelineComment {
+ pub assignee: Option<User>,
+ pub assignee_team: Option<Team>,
+ pub body: Option<String>,
+ pub created_at: Option<time::OffsetDateTime>,
+ pub dependent_issue: Option<Issue>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub html_url: Option<url::Url>,
+ pub id: Option<u64>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub issue_url: Option<url::Url>,
+ pub label: Option<Label>,
+ pub milestone: Option<Milestone>,
+ pub new_ref: Option<String>,
+ pub new_title: Option<String>,
+ pub old_milestone: Option<Milestone>,
+ pub old_project_id: Option<u64>,
+ pub old_ref: Option<String>,
+ pub old_title: Option<String>,
+ pub project_id: Option<u64>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub pull_request_url: Option<url::Url>,
+ pub ref_action: Option<String>,
+ pub ref_comment: Option<Comment>,
+ pub ref_commit_sha: Option<String>,
+ pub ref_issue: Option<Issue>,
+ pub removed_assignee: Option<bool>,
+ pub resolve_doer: Option<User>,
+ pub review_id: Option<u64>,
+ pub tracked_time: Option<TrackedTime>,
+ #[serde(rename = "type")]
+ pub r#type: Option<String>,
+ pub updated_at: Option<time::OffsetDateTime>,
+ pub user: Option<User>,
+ }
+
+ /// TopicName a list of repo topic names
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct TopicName {
+ pub topics: Option<Vec<String>>,
+ }
+
+ /// TopicResponse for returning topics
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct TopicResponse {
+ pub created: Option<time::OffsetDateTime>,
+ pub id: Option<u64>,
+ pub repo_count: Option<u64>,
+ pub topic_name: Option<String>,
+ pub updated: Option<time::OffsetDateTime>,
+ }
+
+ /// TrackedTime worked time for an issue / pr
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct TrackedTime {
+ pub created: Option<time::OffsetDateTime>,
+ pub id: Option<u64>,
+ pub issue: Option<Issue>,
+ pub issue_id: Option<u64>,
+ pub time: Option<u64>,
+ pub user_id: Option<u64>,
+ pub user_name: Option<String>,
+ }
+
+ /// TransferRepoOption options when transfer a repository's ownership
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct TransferRepoOption {
+ pub new_owner: String,
+ pub team_ids: Option<Vec<u64>>,
+ }
+
+ /// UpdateFileOptions options for updating files
+ ///
+ /// Note: `author` and `committer` are optional (if only one is given, it will be used for the other, otherwise the authenticated user will be used)
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct UpdateFileOptions {
+ pub author: Option<Identity>,
+ pub branch: Option<String>,
+ pub committer: Option<Identity>,
+ pub content: String,
+ pub dates: Option<CommitDateOptions>,
+ pub from_path: Option<String>,
+ pub message: Option<String>,
+ pub new_branch: Option<String>,
+ pub sha: String,
+ pub signoff: Option<bool>,
+ }
+
+ /// UpdateRepoAvatarUserOption options when updating the repo avatar
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct UpdateRepoAvatarOption {
+ pub image: Option<String>,
+ }
+
+ /// UpdateUserAvatarUserOption options when updating the user avatar
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct UpdateUserAvatarOption {
+ pub image: Option<String>,
+ }
+
+ /// User represents a user
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct User {
+ pub active: Option<bool>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub avatar_url: Option<url::Url>,
+ pub created: Option<time::OffsetDateTime>,
+ pub description: Option<String>,
+ pub email: Option<String>,
+ pub followers_count: Option<u64>,
+ pub following_count: Option<u64>,
+ pub full_name: Option<String>,
+ pub id: Option<u64>,
+ pub is_admin: Option<bool>,
+ pub language: Option<String>,
+ pub last_login: Option<time::OffsetDateTime>,
+ pub location: Option<String>,
+ pub login: Option<String>,
+ pub login_name: Option<String>,
+ pub prohibit_login: Option<bool>,
+ pub restricted: Option<bool>,
+ pub starred_repos_count: Option<u64>,
+ pub visibility: Option<String>,
+ pub website: Option<String>,
+ }
+
+ /// UserHeatmapData represents the data needed to create a heatmap
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct UserHeatmapData {
+ pub contributions: Option<u64>,
+ pub timestamp: Option<u64>,
+ }
+
+ /// UserSettings represents user settings
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct UserSettings {
+ pub description: Option<String>,
+ pub diff_view_style: Option<String>,
+ pub full_name: Option<String>,
+ pub hide_activity: Option<bool>,
+ pub hide_email: Option<bool>,
+ pub language: Option<String>,
+ pub location: Option<String>,
+ pub theme: Option<String>,
+ pub website: Option<String>,
+ }
+
+ /// UserSettingsOptions represents options to change user settings
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct UserSettingsOptions {
+ pub description: Option<String>,
+ pub diff_view_style: Option<String>,
+ pub full_name: Option<String>,
+ pub hide_activity: Option<bool>,
+ pub hide_email: Option<bool>,
+ pub language: Option<String>,
+ pub location: Option<String>,
+ pub theme: Option<String>,
+ pub website: Option<String>,
+ }
+
+ /// WatchInfo represents an API watch status of one repository
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct WatchInfo {
+ pub created_at: Option<time::OffsetDateTime>,
+ pub ignored: Option<bool>,
+ pub reason: Option<()>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub repository_url: Option<url::Url>,
+ pub subscribed: Option<bool>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub url: Option<url::Url>,
+ }
+
+ /// WikiCommit page commit/revision
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct WikiCommit {
+ pub author: Option<CommitUser>,
+ pub commiter: Option<CommitUser>,
+ pub message: Option<String>,
+ pub sha: Option<String>,
+ }
+
+ /// WikiCommitList commit/revision list
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct WikiCommitList {
+ pub commits: Option<Vec<WikiCommit>>,
+ pub count: Option<u64>,
+ }
+
+ /// WikiPage a wiki page
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct WikiPage {
+ pub commit_count: Option<u64>,
+ pub content_base64: Option<String>,
+ pub footer: Option<String>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub html_url: Option<url::Url>,
+ pub last_commit: Option<WikiCommit>,
+ pub sidebar: Option<String>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub sub_url: Option<url::Url>,
+ pub title: Option<String>,
+ }
+
+ /// WikiPageMetaData wiki page meta information
+ ///
+ #[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
+ pub struct WikiPageMetaData {
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub html_url: Option<url::Url>,
+ pub last_commit: Option<WikiCommit>,
+ #[serde(deserialize_with = "crate::none_if_blank_url")]
+ pub sub_url: Option<url::Url>,
+ pub title: Option<String>,
+ }
+
+ pub struct AdminCronListQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl AdminCronListQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct AdminGetAllEmailsQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl AdminGetAllEmailsQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct AdminSearchEmailsQuery {
+ pub q: Option<String>,
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl AdminSearchEmailsQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(q) = self.q {
+ s.push_str("q=");
+ s.push_str(&q);
+ s.push('&');
+ }
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct AdminListHooksQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl AdminListHooksQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct AdminGetAllOrgsQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl AdminGetAllOrgsQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct AdminUnadoptedListQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ pub pattern: Option<String>,
+ }
+
+ impl AdminUnadoptedListQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ if let Some(pattern) = self.pattern {
+ s.push_str("pattern=");
+ s.push_str(&pattern);
+ s.push('&');
+ }
+ s
+ }
+ }
+ pub struct AdminSearchUsersQuery {
+ pub source_id: Option<u64>,
+ pub login_name: Option<String>,
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl AdminSearchUsersQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(source_id) = self.source_id {
+ write!(&mut s, "source_id={}&", source_id).unwrap();
+ }
+ if let Some(login_name) = self.login_name {
+ s.push_str("login_name=");
+ s.push_str(&login_name);
+ s.push('&');
+ }
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct AdminDeleteUserQuery {
+ pub purge: Option<bool>,
+ }
+
+ impl AdminDeleteUserQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(purge) = self.purge {
+ write!(&mut s, "purge={}&", purge).unwrap();
+ }
+ s
+ }
+ }
+ pub struct NotifyGetListQuery {
+ pub all: Option<bool>,
+ pub status_types: Option<Vec<String>>,
+ pub subject_type: Option<Vec<String>>,
+ pub since: Option<time::OffsetDateTime>,
+ pub before: Option<time::OffsetDateTime>,
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl NotifyGetListQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(all) = self.all {
+ write!(&mut s, "all={}&", all).unwrap();
+ }
+ if let Some(status_types) = self.status_types {
+ if !status_types.is_empty() {
+ for item in status_types {
+ s.push_str("status-types=");
+ s.push_str(&item);
+ s.push('&')
+ }
+ }
+ }
+ if let Some(subject_type) = self.subject_type {
+ if !subject_type.is_empty() {
+ for item in subject_type {
+ s.push_str("subject-type=");
+ s.push_str(&item);
+ s.push('&')
+ }
+ }
+ }
+ if let Some(since) = self.since {
+ s.push_str("since=");
+ s.push_str(
+ &since
+ .format(&time::format_description::well_known::Rfc3339)
+ .unwrap(),
+ );
+ s.push('&');
+ }
+ if let Some(before) = self.before {
+ s.push_str("before=");
+ s.push_str(
+ &before
+ .format(&time::format_description::well_known::Rfc3339)
+ .unwrap(),
+ );
+ s.push('&');
+ }
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct NotifyReadListQuery {
+ pub last_read_at: Option<time::OffsetDateTime>,
+ pub all: Option<String>,
+ pub status_types: Option<Vec<String>>,
+ pub to_status: Option<String>,
+ }
+
+ impl NotifyReadListQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(last_read_at) = self.last_read_at {
+ s.push_str("last_read_at=");
+ s.push_str(
+ &last_read_at
+ .format(&time::format_description::well_known::Rfc3339)
+ .unwrap(),
+ );
+ s.push('&');
+ }
+ if let Some(all) = self.all {
+ s.push_str("all=");
+ s.push_str(&all);
+ s.push('&');
+ }
+ if let Some(status_types) = self.status_types {
+ if !status_types.is_empty() {
+ for item in status_types {
+ s.push_str("status-types=");
+ s.push_str(&item);
+ s.push('&')
+ }
+ }
+ }
+ if let Some(to_status) = self.to_status {
+ s.push_str("to-status=");
+ s.push_str(&to_status);
+ s.push('&');
+ }
+ s
+ }
+ }
+ pub struct NotifyReadThreadQuery {
+ pub to_status: Option<String>,
+ }
+
+ impl NotifyReadThreadQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(to_status) = self.to_status {
+ s.push_str("to-status=");
+ s.push_str(&to_status);
+ s.push('&');
+ }
+ s
+ }
+ }
+ pub struct OrgGetAllQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl OrgGetAllQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct OrgListActionsSecretsQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl OrgListActionsSecretsQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct OrgListActivityFeedsQuery {
+ pub date: Option<time::Date>,
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl OrgListActivityFeedsQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(date) = self.date {
+ s.push_str("date=");
+ s.push_str(
+ &date
+ .format(&time::format_description::well_known::Rfc3339)
+ .unwrap(),
+ );
+ s.push('&');
+ }
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct OrgListHooksQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl OrgListHooksQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct OrgListLabelsQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl OrgListLabelsQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct OrgListBlockedUsersQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl OrgListBlockedUsersQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct OrgListMembersQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl OrgListMembersQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct OrgListPublicMembersQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl OrgListPublicMembersQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct OrgListReposQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl OrgListReposQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct OrgListTeamsQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl OrgListTeamsQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct TeamSearchQuery {
+ pub q: Option<String>,
+ pub include_desc: Option<bool>,
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl TeamSearchQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(q) = self.q {
+ s.push_str("q=");
+ s.push_str(&q);
+ s.push('&');
+ }
+ if let Some(include_desc) = self.include_desc {
+ write!(&mut s, "include_desc={}&", include_desc).unwrap();
+ }
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct ListPackagesQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ pub r#type: Option<String>,
+ pub q: Option<String>,
+ }
+
+ impl ListPackagesQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ if let Some(r#type) = self.r#type {
+ s.push_str("type=");
+ s.push_str(&r#type);
+ s.push('&');
+ }
+ if let Some(q) = self.q {
+ s.push_str("q=");
+ s.push_str(&q);
+ s.push('&');
+ }
+ s
+ }
+ }
+ pub struct IssueSearchIssuesQuery {
+ pub state: Option<String>,
+ pub labels: Option<String>,
+ pub milestones: Option<String>,
+ pub q: Option<String>,
+ pub priority_repo_id: Option<u64>,
+ pub r#type: Option<String>,
+ pub since: Option<time::OffsetDateTime>,
+ pub before: Option<time::OffsetDateTime>,
+ pub assigned: Option<bool>,
+ pub created: Option<bool>,
+ pub mentioned: Option<bool>,
+ pub review_requested: Option<bool>,
+ pub reviewed: Option<bool>,
+ pub owner: Option<String>,
+ pub team: Option<String>,
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl IssueSearchIssuesQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(state) = self.state {
+ s.push_str("state=");
+ s.push_str(&state);
+ s.push('&');
+ }
+ if let Some(labels) = self.labels {
+ s.push_str("labels=");
+ s.push_str(&labels);
+ s.push('&');
+ }
+ if let Some(milestones) = self.milestones {
+ s.push_str("milestones=");
+ s.push_str(&milestones);
+ s.push('&');
+ }
+ if let Some(q) = self.q {
+ s.push_str("q=");
+ s.push_str(&q);
+ s.push('&');
+ }
+ if let Some(priority_repo_id) = self.priority_repo_id {
+ write!(&mut s, "priority_repo_id={}&", priority_repo_id).unwrap();
+ }
+ if let Some(r#type) = self.r#type {
+ s.push_str("type=");
+ s.push_str(&r#type);
+ s.push('&');
+ }
+ if let Some(since) = self.since {
+ s.push_str("since=");
+ s.push_str(
+ &since
+ .format(&time::format_description::well_known::Rfc3339)
+ .unwrap(),
+ );
+ s.push('&');
+ }
+ if let Some(before) = self.before {
+ s.push_str("before=");
+ s.push_str(
+ &before
+ .format(&time::format_description::well_known::Rfc3339)
+ .unwrap(),
+ );
+ s.push('&');
+ }
+ if let Some(assigned) = self.assigned {
+ write!(&mut s, "assigned={}&", assigned).unwrap();
+ }
+ if let Some(created) = self.created {
+ write!(&mut s, "created={}&", created).unwrap();
+ }
+ if let Some(mentioned) = self.mentioned {
+ write!(&mut s, "mentioned={}&", mentioned).unwrap();
+ }
+ if let Some(review_requested) = self.review_requested {
+ write!(&mut s, "review_requested={}&", review_requested).unwrap();
+ }
+ if let Some(reviewed) = self.reviewed {
+ write!(&mut s, "reviewed={}&", reviewed).unwrap();
+ }
+ if let Some(owner) = self.owner {
+ s.push_str("owner=");
+ s.push_str(&owner);
+ s.push('&');
+ }
+ if let Some(team) = self.team {
+ s.push_str("team=");
+ s.push_str(&team);
+ s.push('&');
+ }
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct RepoSearchQuery {
+ pub q: Option<String>,
+ pub topic: Option<bool>,
+ pub include_desc: Option<bool>,
+ pub uid: Option<u64>,
+ pub priority_owner_id: Option<u64>,
+ pub team_id: Option<u64>,
+ pub starred_by: Option<u64>,
+ pub private: Option<bool>,
+ pub is_private: Option<bool>,
+ pub template: Option<bool>,
+ pub archived: Option<bool>,
+ pub mode: Option<String>,
+ pub exclusive: Option<bool>,
+ pub sort: Option<String>,
+ pub order: Option<String>,
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl RepoSearchQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(q) = self.q {
+ s.push_str("q=");
+ s.push_str(&q);
+ s.push('&');
+ }
+ if let Some(topic) = self.topic {
+ write!(&mut s, "topic={}&", topic).unwrap();
+ }
+ if let Some(include_desc) = self.include_desc {
+ write!(&mut s, "includeDesc={}&", include_desc).unwrap();
+ }
+ if let Some(uid) = self.uid {
+ write!(&mut s, "uid={}&", uid).unwrap();
+ }
+ if let Some(priority_owner_id) = self.priority_owner_id {
+ write!(&mut s, "priority_owner_id={}&", priority_owner_id).unwrap();
+ }
+ if let Some(team_id) = self.team_id {
+ write!(&mut s, "team_id={}&", team_id).unwrap();
+ }
+ if let Some(starred_by) = self.starred_by {
+ write!(&mut s, "starredBy={}&", starred_by).unwrap();
+ }
+ if let Some(private) = self.private {
+ write!(&mut s, "private={}&", private).unwrap();
+ }
+ if let Some(is_private) = self.is_private {
+ write!(&mut s, "is_private={}&", is_private).unwrap();
+ }
+ if let Some(template) = self.template {
+ write!(&mut s, "template={}&", template).unwrap();
+ }
+ if let Some(archived) = self.archived {
+ write!(&mut s, "archived={}&", archived).unwrap();
+ }
+ if let Some(mode) = self.mode {
+ s.push_str("mode=");
+ s.push_str(&mode);
+ s.push('&');
+ }
+ if let Some(exclusive) = self.exclusive {
+ write!(&mut s, "exclusive={}&", exclusive).unwrap();
+ }
+ if let Some(sort) = self.sort {
+ s.push_str("sort=");
+ s.push_str(&sort);
+ s.push('&');
+ }
+ if let Some(order) = self.order {
+ s.push_str("order=");
+ s.push_str(&order);
+ s.push('&');
+ }
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct RepoListActivityFeedsQuery {
+ pub date: Option<time::Date>,
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl RepoListActivityFeedsQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(date) = self.date {
+ s.push_str("date=");
+ s.push_str(
+ &date
+ .format(&time::format_description::well_known::Rfc3339)
+ .unwrap(),
+ );
+ s.push('&');
+ }
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct RepoListBranchesQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl RepoListBranchesQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct RepoListCollaboratorsQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl RepoListCollaboratorsQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct RepoGetAllCommitsQuery {
+ pub sha: Option<String>,
+ pub path: Option<String>,
+ pub stat: Option<bool>,
+ pub verification: Option<bool>,
+ pub files: Option<bool>,
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ pub not: Option<String>,
+ }
+
+ impl RepoGetAllCommitsQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(sha) = self.sha {
+ s.push_str("sha=");
+ s.push_str(&sha);
+ s.push('&');
+ }
+ if let Some(path) = self.path {
+ s.push_str("path=");
+ s.push_str(&path);
+ s.push('&');
+ }
+ if let Some(stat) = self.stat {
+ write!(&mut s, "stat={}&", stat).unwrap();
+ }
+ if let Some(verification) = self.verification {
+ write!(&mut s, "verification={}&", verification).unwrap();
+ }
+ if let Some(files) = self.files {
+ write!(&mut s, "files={}&", files).unwrap();
+ }
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ if let Some(not) = self.not {
+ s.push_str("not=");
+ s.push_str(&not);
+ s.push('&');
+ }
+ s
+ }
+ }
+ pub struct RepoGetCombinedStatusByRefQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl RepoGetCombinedStatusByRefQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct RepoListStatusesByRefQuery {
+ pub sort: Option<String>,
+ pub state: Option<String>,
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl RepoListStatusesByRefQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(sort) = self.sort {
+ s.push_str("sort=");
+ s.push_str(&sort);
+ s.push('&');
+ }
+ if let Some(state) = self.state {
+ s.push_str("state=");
+ s.push_str(&state);
+ s.push('&');
+ }
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct RepoGetContentsListQuery {
+ pub r#ref: Option<String>,
+ }
+
+ impl RepoGetContentsListQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(r#ref) = self.r#ref {
+ s.push_str("ref=");
+ s.push_str(&r#ref);
+ s.push('&');
+ }
+ s
+ }
+ }
+ pub struct RepoGetContentsQuery {
+ pub r#ref: Option<String>,
+ }
+
+ impl RepoGetContentsQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(r#ref) = self.r#ref {
+ s.push_str("ref=");
+ s.push_str(&r#ref);
+ s.push('&');
+ }
+ s
+ }
+ }
+ pub struct RepoGetEditorConfigQuery {
+ pub r#ref: Option<String>,
+ }
+
+ impl RepoGetEditorConfigQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(r#ref) = self.r#ref {
+ s.push_str("ref=");
+ s.push_str(&r#ref);
+ s.push('&');
+ }
+ s
+ }
+ }
+ pub struct ListForksQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl ListForksQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct RepoGetSingleCommitQuery {
+ pub stat: Option<bool>,
+ pub verification: Option<bool>,
+ pub files: Option<bool>,
+ }
+
+ impl RepoGetSingleCommitQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(stat) = self.stat {
+ write!(&mut s, "stat={}&", stat).unwrap();
+ }
+ if let Some(verification) = self.verification {
+ write!(&mut s, "verification={}&", verification).unwrap();
+ }
+ if let Some(files) = self.files {
+ write!(&mut s, "files={}&", files).unwrap();
+ }
+ s
+ }
+ }
+ pub struct RepoGetNoteQuery {
+ pub verification: Option<bool>,
+ pub files: Option<bool>,
+ }
+
+ impl RepoGetNoteQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(verification) = self.verification {
+ write!(&mut s, "verification={}&", verification).unwrap();
+ }
+ if let Some(files) = self.files {
+ write!(&mut s, "files={}&", files).unwrap();
+ }
+ s
+ }
+ }
+ pub struct GetTreeQuery {
+ pub recursive: Option<bool>,
+ pub page: Option<u32>,
+ pub per_page: Option<u32>,
+ }
+
+ impl GetTreeQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(recursive) = self.recursive {
+ write!(&mut s, "recursive={}&", recursive).unwrap();
+ }
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(per_page) = self.per_page {
+ write!(&mut s, "per_page={}&", per_page).unwrap();
+ }
+ s
+ }
+ }
+ pub struct RepoListHooksQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl RepoListHooksQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct RepoTestHookQuery {
+ pub r#ref: Option<String>,
+ }
+
+ impl RepoTestHookQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(r#ref) = self.r#ref {
+ s.push_str("ref=");
+ s.push_str(&r#ref);
+ s.push('&');
+ }
+ s
+ }
+ }
+ pub struct IssueListIssuesQuery {
+ pub state: Option<String>,
+ pub labels: Option<String>,
+ pub q: Option<String>,
+ pub r#type: Option<String>,
+ pub milestones: Option<String>,
+ pub since: Option<time::OffsetDateTime>,
+ pub before: Option<time::OffsetDateTime>,
+ pub created_by: Option<String>,
+ pub assigned_by: Option<String>,
+ pub mentioned_by: Option<String>,
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl IssueListIssuesQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(state) = self.state {
+ s.push_str("state=");
+ s.push_str(&state);
+ s.push('&');
+ }
+ if let Some(labels) = self.labels {
+ s.push_str("labels=");
+ s.push_str(&labels);
+ s.push('&');
+ }
+ if let Some(q) = self.q {
+ s.push_str("q=");
+ s.push_str(&q);
+ s.push('&');
+ }
+ if let Some(r#type) = self.r#type {
+ s.push_str("type=");
+ s.push_str(&r#type);
+ s.push('&');
+ }
+ if let Some(milestones) = self.milestones {
+ s.push_str("milestones=");
+ s.push_str(&milestones);
+ s.push('&');
+ }
+ if let Some(since) = self.since {
+ s.push_str("since=");
+ s.push_str(
+ &since
+ .format(&time::format_description::well_known::Rfc3339)
+ .unwrap(),
+ );
+ s.push('&');
+ }
+ if let Some(before) = self.before {
+ s.push_str("before=");
+ s.push_str(
+ &before
+ .format(&time::format_description::well_known::Rfc3339)
+ .unwrap(),
+ );
+ s.push('&');
+ }
+ if let Some(created_by) = self.created_by {
+ s.push_str("created_by=");
+ s.push_str(&created_by);
+ s.push('&');
+ }
+ if let Some(assigned_by) = self.assigned_by {
+ s.push_str("assigned_by=");
+ s.push_str(&assigned_by);
+ s.push('&');
+ }
+ if let Some(mentioned_by) = self.mentioned_by {
+ s.push_str("mentioned_by=");
+ s.push_str(&mentioned_by);
+ s.push('&');
+ }
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct IssueGetRepoCommentsQuery {
+ pub since: Option<time::OffsetDateTime>,
+ pub before: Option<time::OffsetDateTime>,
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl IssueGetRepoCommentsQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(since) = self.since {
+ s.push_str("since=");
+ s.push_str(
+ &since
+ .format(&time::format_description::well_known::Rfc3339)
+ .unwrap(),
+ );
+ s.push('&');
+ }
+ if let Some(before) = self.before {
+ s.push_str("before=");
+ s.push_str(
+ &before
+ .format(&time::format_description::well_known::Rfc3339)
+ .unwrap(),
+ );
+ s.push('&');
+ }
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct IssueCreateIssueCommentAttachmentQuery {
+ pub name: Option<String>,
+ pub updated_at: Option<time::OffsetDateTime>,
+ }
+
+ impl IssueCreateIssueCommentAttachmentQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(name) = self.name {
+ s.push_str("name=");
+ s.push_str(&name);
+ s.push('&');
+ }
+ if let Some(updated_at) = self.updated_at {
+ s.push_str("updated_at=");
+ s.push_str(
+ &updated_at
+ .format(&time::format_description::well_known::Rfc3339)
+ .unwrap(),
+ );
+ s.push('&');
+ }
+ s
+ }
+ }
+ pub struct IssueCreateIssueAttachmentQuery {
+ pub name: Option<String>,
+ pub updated_at: Option<time::OffsetDateTime>,
+ }
+
+ impl IssueCreateIssueAttachmentQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(name) = self.name {
+ s.push_str("name=");
+ s.push_str(&name);
+ s.push('&');
+ }
+ if let Some(updated_at) = self.updated_at {
+ s.push_str("updated_at=");
+ s.push_str(
+ &updated_at
+ .format(&time::format_description::well_known::Rfc3339)
+ .unwrap(),
+ );
+ s.push('&');
+ }
+ s
+ }
+ }
+ pub struct IssueListBlocksQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl IssueListBlocksQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct IssueGetCommentsQuery {
+ pub since: Option<time::OffsetDateTime>,
+ pub before: Option<time::OffsetDateTime>,
+ }
+
+ impl IssueGetCommentsQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(since) = self.since {
+ s.push_str("since=");
+ s.push_str(
+ &since
+ .format(&time::format_description::well_known::Rfc3339)
+ .unwrap(),
+ );
+ s.push('&');
+ }
+ if let Some(before) = self.before {
+ s.push_str("before=");
+ s.push_str(
+ &before
+ .format(&time::format_description::well_known::Rfc3339)
+ .unwrap(),
+ );
+ s.push('&');
+ }
+ s
+ }
+ }
+ pub struct IssueListIssueDependenciesQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl IssueListIssueDependenciesQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct IssueGetIssueReactionsQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl IssueGetIssueReactionsQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct IssueSubscriptionsQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl IssueSubscriptionsQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct IssueGetCommentsAndTimelineQuery {
+ pub since: Option<time::OffsetDateTime>,
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ pub before: Option<time::OffsetDateTime>,
+ }
+
+ impl IssueGetCommentsAndTimelineQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(since) = self.since {
+ s.push_str("since=");
+ s.push_str(
+ &since
+ .format(&time::format_description::well_known::Rfc3339)
+ .unwrap(),
+ );
+ s.push('&');
+ }
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ if let Some(before) = self.before {
+ s.push_str("before=");
+ s.push_str(
+ &before
+ .format(&time::format_description::well_known::Rfc3339)
+ .unwrap(),
+ );
+ s.push('&');
+ }
+ s
+ }
+ }
+ pub struct IssueTrackedTimesQuery {
+ pub user: Option<String>,
+ pub since: Option<time::OffsetDateTime>,
+ pub before: Option<time::OffsetDateTime>,
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl IssueTrackedTimesQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(user) = self.user {
+ s.push_str("user=");
+ s.push_str(&user);
+ s.push('&');
+ }
+ if let Some(since) = self.since {
+ s.push_str("since=");
+ s.push_str(
+ &since
+ .format(&time::format_description::well_known::Rfc3339)
+ .unwrap(),
+ );
+ s.push('&');
+ }
+ if let Some(before) = self.before {
+ s.push_str("before=");
+ s.push_str(
+ &before
+ .format(&time::format_description::well_known::Rfc3339)
+ .unwrap(),
+ );
+ s.push('&');
+ }
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct RepoListKeysQuery {
+ pub key_id: Option<u32>,
+ pub fingerprint: Option<String>,
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl RepoListKeysQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(key_id) = self.key_id {
+ write!(&mut s, "key_id={}&", key_id).unwrap();
+ }
+ if let Some(fingerprint) = self.fingerprint {
+ s.push_str("fingerprint=");
+ s.push_str(&fingerprint);
+ s.push('&');
+ }
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct IssueListLabelsQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl IssueListLabelsQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct RepoGetRawFileOrLfsQuery {
+ pub r#ref: Option<String>,
+ }
+
+ impl RepoGetRawFileOrLfsQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(r#ref) = self.r#ref {
+ s.push_str("ref=");
+ s.push_str(&r#ref);
+ s.push('&');
+ }
+ s
+ }
+ }
+ pub struct IssueGetMilestonesListQuery {
+ pub state: Option<String>,
+ pub name: Option<String>,
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl IssueGetMilestonesListQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(state) = self.state {
+ s.push_str("state=");
+ s.push_str(&state);
+ s.push('&');
+ }
+ if let Some(name) = self.name {
+ s.push_str("name=");
+ s.push_str(&name);
+ s.push('&');
+ }
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct NotifyGetRepoListQuery {
+ pub all: Option<bool>,
+ pub status_types: Option<Vec<String>>,
+ pub subject_type: Option<Vec<String>>,
+ pub since: Option<time::OffsetDateTime>,
+ pub before: Option<time::OffsetDateTime>,
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl NotifyGetRepoListQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(all) = self.all {
+ write!(&mut s, "all={}&", all).unwrap();
+ }
+ if let Some(status_types) = self.status_types {
+ if !status_types.is_empty() {
+ for item in status_types {
+ s.push_str("status-types=");
+ s.push_str(&item);
+ s.push('&')
+ }
+ }
+ }
+ if let Some(subject_type) = self.subject_type {
+ if !subject_type.is_empty() {
+ for item in subject_type {
+ s.push_str("subject-type=");
+ s.push_str(&item);
+ s.push('&')
+ }
+ }
+ }
+ if let Some(since) = self.since {
+ s.push_str("since=");
+ s.push_str(
+ &since
+ .format(&time::format_description::well_known::Rfc3339)
+ .unwrap(),
+ );
+ s.push('&');
+ }
+ if let Some(before) = self.before {
+ s.push_str("before=");
+ s.push_str(
+ &before
+ .format(&time::format_description::well_known::Rfc3339)
+ .unwrap(),
+ );
+ s.push('&');
+ }
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct NotifyReadRepoListQuery {
+ pub all: Option<String>,
+ pub status_types: Option<Vec<String>>,
+ pub to_status: Option<String>,
+ pub last_read_at: Option<time::OffsetDateTime>,
+ }
+
+ impl NotifyReadRepoListQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(all) = self.all {
+ s.push_str("all=");
+ s.push_str(&all);
+ s.push('&');
+ }
+ if let Some(status_types) = self.status_types {
+ if !status_types.is_empty() {
+ for item in status_types {
+ s.push_str("status-types=");
+ s.push_str(&item);
+ s.push('&')
+ }
+ }
+ }
+ if let Some(to_status) = self.to_status {
+ s.push_str("to-status=");
+ s.push_str(&to_status);
+ s.push('&');
+ }
+ if let Some(last_read_at) = self.last_read_at {
+ s.push_str("last_read_at=");
+ s.push_str(
+ &last_read_at
+ .format(&time::format_description::well_known::Rfc3339)
+ .unwrap(),
+ );
+ s.push('&');
+ }
+ s
+ }
+ }
+ pub struct RepoListPullRequestsQuery {
+ pub state: Option<String>,
+ pub sort: Option<String>,
+ pub milestone: Option<u64>,
+ pub labels: Option<Vec<u64>>,
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl RepoListPullRequestsQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(state) = self.state {
+ s.push_str("state=");
+ s.push_str(&state);
+ s.push('&');
+ }
+ if let Some(sort) = self.sort {
+ s.push_str("sort=");
+ s.push_str(&sort);
+ s.push('&');
+ }
+ if let Some(milestone) = self.milestone {
+ write!(&mut s, "milestone={}&", milestone).unwrap();
+ }
+ if let Some(labels) = self.labels {
+ if !labels.is_empty() {
+ for item in labels {
+ s.push_str("labels=");
+ write!(&mut s, "{item}").unwrap();
+ s.push('&')
+ }
+ }
+ }
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct RepoDownloadPullDiffOrPatchQuery {
+ pub binary: Option<bool>,
+ }
+
+ impl RepoDownloadPullDiffOrPatchQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(binary) = self.binary {
+ write!(&mut s, "binary={}&", binary).unwrap();
+ }
+ s
+ }
+ }
+ pub struct RepoGetPullRequestCommitsQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ pub verification: Option<bool>,
+ pub files: Option<bool>,
+ }
+
+ impl RepoGetPullRequestCommitsQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ if let Some(verification) = self.verification {
+ write!(&mut s, "verification={}&", verification).unwrap();
+ }
+ if let Some(files) = self.files {
+ write!(&mut s, "files={}&", files).unwrap();
+ }
+ s
+ }
+ }
+ pub struct RepoGetPullRequestFilesQuery {
+ pub skip_to: Option<String>,
+ pub whitespace: Option<String>,
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl RepoGetPullRequestFilesQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(skip_to) = self.skip_to {
+ s.push_str("skip-to=");
+ s.push_str(&skip_to);
+ s.push('&');
+ }
+ if let Some(whitespace) = self.whitespace {
+ s.push_str("whitespace=");
+ s.push_str(&whitespace);
+ s.push('&');
+ }
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct RepoListPullReviewsQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl RepoListPullReviewsQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct RepoUpdatePullRequestQuery {
+ pub style: Option<String>,
+ }
+
+ impl RepoUpdatePullRequestQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(style) = self.style {
+ s.push_str("style=");
+ s.push_str(&style);
+ s.push('&');
+ }
+ s
+ }
+ }
+ pub struct RepoListPushMirrorsQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl RepoListPushMirrorsQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct RepoGetRawFileQuery {
+ pub r#ref: Option<String>,
+ }
+
+ impl RepoGetRawFileQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(r#ref) = self.r#ref {
+ s.push_str("ref=");
+ s.push_str(&r#ref);
+ s.push('&');
+ }
+ s
+ }
+ }
+ pub struct RepoListReleasesQuery {
+ pub draft: Option<bool>,
+ pub pre_release: Option<bool>,
+ pub per_page: Option<u32>,
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl RepoListReleasesQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(draft) = self.draft {
+ write!(&mut s, "draft={}&", draft).unwrap();
+ }
+ if let Some(pre_release) = self.pre_release {
+ write!(&mut s, "pre-release={}&", pre_release).unwrap();
+ }
+ if let Some(per_page) = self.per_page {
+ write!(&mut s, "per_page={}&", per_page).unwrap();
+ }
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct RepoCreateReleaseAttachmentQuery {
+ pub name: Option<String>,
+ }
+
+ impl RepoCreateReleaseAttachmentQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(name) = self.name {
+ s.push_str("name=");
+ s.push_str(&name);
+ s.push('&');
+ }
+ s
+ }
+ }
+ pub struct RepoListStargazersQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl RepoListStargazersQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct RepoListStatusesQuery {
+ pub sort: Option<String>,
+ pub state: Option<String>,
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl RepoListStatusesQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(sort) = self.sort {
+ s.push_str("sort=");
+ s.push_str(&sort);
+ s.push('&');
+ }
+ if let Some(state) = self.state {
+ s.push_str("state=");
+ s.push_str(&state);
+ s.push('&');
+ }
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct RepoListSubscribersQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl RepoListSubscribersQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct RepoListTagsQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl RepoListTagsQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct RepoTrackedTimesQuery {
+ pub user: Option<String>,
+ pub since: Option<time::OffsetDateTime>,
+ pub before: Option<time::OffsetDateTime>,
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl RepoTrackedTimesQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(user) = self.user {
+ s.push_str("user=");
+ s.push_str(&user);
+ s.push('&');
+ }
+ if let Some(since) = self.since {
+ s.push_str("since=");
+ s.push_str(
+ &since
+ .format(&time::format_description::well_known::Rfc3339)
+ .unwrap(),
+ );
+ s.push('&');
+ }
+ if let Some(before) = self.before {
+ s.push_str("before=");
+ s.push_str(
+ &before
+ .format(&time::format_description::well_known::Rfc3339)
+ .unwrap(),
+ );
+ s.push('&');
+ }
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct RepoListTopicsQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl RepoListTopicsQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct RepoGetWikiPagesQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl RepoGetWikiPagesQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct RepoGetWikiPageRevisionsQuery {
+ pub page: Option<u32>,
+ }
+
+ impl RepoGetWikiPageRevisionsQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ s
+ }
+ }
+ pub struct OrgListTeamActivityFeedsQuery {
+ pub date: Option<time::Date>,
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl OrgListTeamActivityFeedsQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(date) = self.date {
+ s.push_str("date=");
+ s.push_str(
+ &date
+ .format(&time::format_description::well_known::Rfc3339)
+ .unwrap(),
+ );
+ s.push('&');
+ }
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct OrgListTeamMembersQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl OrgListTeamMembersQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct OrgListTeamReposQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl OrgListTeamReposQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct TopicSearchQuery {
+ pub q: String,
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl TopicSearchQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ let q = self.q;
+ s.push_str("q=");
+ s.push_str(&q);
+ s.push('&');
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct UserGetOAuth2ApplicationsQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl UserGetOAuth2ApplicationsQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct UserCurrentListFollowersQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl UserCurrentListFollowersQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct UserCurrentListFollowingQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl UserCurrentListFollowingQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct UserCurrentListGpgKeysQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl UserCurrentListGpgKeysQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct UserListHooksQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl UserListHooksQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct UserCurrentListKeysQuery {
+ pub fingerprint: Option<String>,
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl UserCurrentListKeysQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(fingerprint) = self.fingerprint {
+ s.push_str("fingerprint=");
+ s.push_str(&fingerprint);
+ s.push('&');
+ }
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct UserListBlockedUsersQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl UserListBlockedUsersQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct OrgListCurrentUserOrgsQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl OrgListCurrentUserOrgsQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct UserCurrentListReposQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl UserCurrentListReposQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct UserCurrentListStarredQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl UserCurrentListStarredQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct UserGetStopWatchesQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl UserGetStopWatchesQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct UserCurrentListSubscriptionsQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl UserCurrentListSubscriptionsQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct UserListTeamsQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl UserListTeamsQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct UserCurrentTrackedTimesQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ pub since: Option<time::OffsetDateTime>,
+ pub before: Option<time::OffsetDateTime>,
+ }
+
+ impl UserCurrentTrackedTimesQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ if let Some(since) = self.since {
+ s.push_str("since=");
+ s.push_str(
+ &since
+ .format(&time::format_description::well_known::Rfc3339)
+ .unwrap(),
+ );
+ s.push('&');
+ }
+ if let Some(before) = self.before {
+ s.push_str("before=");
+ s.push_str(
+ &before
+ .format(&time::format_description::well_known::Rfc3339)
+ .unwrap(),
+ );
+ s.push('&');
+ }
+ s
+ }
+ }
+ pub struct UserSearchQuery {
+ pub q: Option<String>,
+ pub uid: Option<u64>,
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl UserSearchQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(q) = self.q {
+ s.push_str("q=");
+ s.push_str(&q);
+ s.push('&');
+ }
+ if let Some(uid) = self.uid {
+ write!(&mut s, "uid={}&", uid).unwrap();
+ }
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct UserListActivityFeedsQuery {
+ pub only_performed_by: Option<bool>,
+ pub date: Option<time::Date>,
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl UserListActivityFeedsQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(only_performed_by) = self.only_performed_by {
+ write!(&mut s, "only-performed-by={}&", only_performed_by).unwrap();
+ }
+ if let Some(date) = self.date {
+ s.push_str("date=");
+ s.push_str(
+ &date
+ .format(&time::format_description::well_known::Rfc3339)
+ .unwrap(),
+ );
+ s.push('&');
+ }
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct UserListFollowersQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl UserListFollowersQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct UserListFollowingQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl UserListFollowingQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct UserListGpgKeysQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl UserListGpgKeysQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct UserListKeysQuery {
+ pub fingerprint: Option<String>,
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl UserListKeysQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(fingerprint) = self.fingerprint {
+ s.push_str("fingerprint=");
+ s.push_str(&fingerprint);
+ s.push('&');
+ }
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct OrgListUserOrgsQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl OrgListUserOrgsQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct UserListReposQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl UserListReposQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct UserListStarredQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl UserListStarredQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct UserListSubscriptionsQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl UserListSubscriptionsQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+ pub struct UserGetTokensQuery {
+ pub page: Option<u32>,
+ pub limit: Option<u32>,
+ }
+
+ impl UserGetTokensQuery {
+ pub(crate) fn to_string(self) -> String {
+ let mut s = String::new();
+ if let Some(page) = self.page {
+ write!(&mut s, "page={}&", page).unwrap();
+ }
+ if let Some(limit) = self.limit {
+ write!(&mut s, "limit={}&", limit).unwrap();
+ }
+ s
+ }
+ }
+}
diff --git a/src/issue.rs b/src/issue.rs
deleted file mode 100644
index 71f2fd5..0000000
--- a/src/issue.rs
+++ /dev/null
@@ -1,347 +0,0 @@
-use super::*;
-
-impl Forgejo {
- pub async fn get_repo_issues(
- &self,
- owner: &str,
- repo: &str,
- query: IssueQuery,
- ) -> Result<Vec<Issue>, ForgejoError> {
- self.get(&query.to_string(owner, repo)).await
- }
-
- pub async fn create_issue(
- &self,
- owner: &str,
- repo: &str,
- opts: CreateIssueOption,
- ) -> Result<Issue, ForgejoError> {
- self.post(&format!("repos/{owner}/{repo}/issues"), &opts)
- .await
- }
-
- pub async fn get_issue(
- &self,
- owner: &str,
- repo: &str,
- id: u64,
- ) -> Result<Option<Issue>, ForgejoError> {
- self.get_opt(&format!("repos/{owner}/{repo}/issues/{id}"))
- .await
- }
-
- pub async fn delete_issue(&self, owner: &str, repo: &str, id: u64) -> Result<(), ForgejoError> {
- self.delete(&format!("repos/{owner}/{repo}/issues/{id}"))
- .await
- }
-
- pub async fn edit_issue(
- &self,
- owner: &str,
- repo: &str,
- id: u64,
- opts: EditIssueOption,
- ) -> Result<Issue, ForgejoError> {
- self.patch(&format!("repos/{owner}/{repo}/issues/{id}"), &opts)
- .await
- }
-
- pub async fn get_repo_comments(
- &self,
- owner: &str,
- repo: &str,
- query: RepoCommentQuery,
- ) -> Result<Vec<Comment>, ForgejoError> {
- self.get(&query.to_string(owner, repo)).await
- }
-
- pub async fn get_issue_comments(
- &self,
- owner: &str,
- repo: &str,
- issue_id: u64,
- query: IssueCommentQuery,
- ) -> Result<Vec<Comment>, ForgejoError> {
- self.get(&query.to_string(owner, repo, issue_id)).await
- }
-
- pub async fn create_comment(
- &self,
- owner: &str,
- repo: &str,
- issue_id: u64,
- opts: CreateIssueCommentOption,
- ) -> Result<Comment, ForgejoError> {
- self.post(
- &format!("repos/{owner}/{repo}/issues/{issue_id}/comments"),
- &opts,
- )
- .await
- }
-
- pub async fn get_comment(
- &self,
- owner: &str,
- repo: &str,
- id: u64,
- ) -> Result<Option<Comment>, ForgejoError> {
- self.get_opt(&format!("repos/{owner}/{repo}/issues/comments/{id}"))
- .await
- }
-
- pub async fn delete_comment(
- &self,
- owner: &str,
- repo: &str,
- id: u64,
- ) -> Result<(), ForgejoError> {
- self.delete(&format!("repos/{owner}/{repo}/issues/comments/{id}"))
- .await
- }
-
- pub async fn edit_comment(
- &self,
- owner: &str,
- repo: &str,
- id: u64,
- opts: EditIssueCommentOption,
- ) -> Result<Comment, ForgejoError> {
- self.patch(&format!("repos/{owner}/{repo}/issues/comments/{id}"), &opts)
- .await
- }
-}
-
-#[derive(serde::Deserialize, Debug, PartialEq)]
-pub struct Issue {
- pub assets: Vec<Attachment>,
- pub assignee: Option<User>,
- pub assignees: Option<Vec<User>>,
- pub body: String,
- #[serde(with = "time::serde::rfc3339::option")]
- pub closed_at: Option<time::OffsetDateTime>,
- pub comments: u64,
- #[serde(with = "time::serde::rfc3339")]
- pub created_at: time::OffsetDateTime,
- #[serde(with = "time::serde::rfc3339::option")]
- pub due_date: Option<time::OffsetDateTime>,
- pub html_url: Url,
- pub id: u64,
- pub is_locked: bool,
- pub labels: Vec<Label>,
- pub milestone: Option<Milestone>,
- pub number: u64,
- pub original_author: String,
- pub original_author_id: u64,
- pub pin_order: u64,
- pub pull_request: Option<PullRequestMeta>,
- #[serde(rename = "ref")]
- pub _ref: String,
- pub repository: RepositoryMeta,
- pub state: State,
- pub title: String,
- #[serde(with = "time::serde::rfc3339")]
- pub updated_at: time::OffsetDateTime,
- pub url: Url,
- pub user: User,
-}
-
-#[derive(serde::Deserialize, Debug, PartialEq)]
-pub struct Label {
- pub color: String,
- pub description: String,
- pub exclusive: bool,
- pub id: u64,
- pub name: String,
- pub url: Url,
-}
-
-#[derive(serde::Deserialize, Debug, PartialEq)]
-pub struct Attachment {
- pub browser_download_url: Url,
- #[serde(with = "time::serde::rfc3339")]
- pub created_at: time::OffsetDateTime,
- pub download_count: u64,
- pub id: u64,
- pub name: String,
- pub size: u64,
- pub uuid: String,
-}
-
-#[derive(serde::Serialize, Debug, PartialEq, Default)]
-pub struct EditAttachmentOption {
- pub name: Option<String>,
-}
-
-#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Clone, Copy)]
-pub enum State {
- #[serde(rename = "open")]
- Open,
- #[serde(rename = "closed")]
- Closed,
-}
-
-impl State {
- pub(crate) fn as_str(&self) -> &'static str {
- match self {
- State::Open => "open",
- State::Closed => "closed",
- }
- }
-}
-
-#[derive(serde::Deserialize, Debug, PartialEq)]
-pub struct Comment {
- pub assets: Vec<Attachment>,
- pub body: String,
- #[serde(with = "time::serde::rfc3339")]
- pub created_at: time::OffsetDateTime,
- pub html_url: Url,
- pub id: u64,
- pub issue_url: Url,
- pub original_author: String,
- pub original_author_id: u64,
- #[serde(deserialize_with = "crate::none_if_blank_url")]
- pub pull_request_url: Option<Url>,
- #[serde(with = "time::serde::rfc3339")]
- pub updated_at: time::OffsetDateTime,
- pub user: User,
-}
-
-#[derive(Default, Debug)]
-pub struct IssueQuery {
- pub state: Option<State>,
- pub labels: Vec<String>,
- pub query: Option<String>,
- pub _type: Option<IssueQueryType>,
- pub milestones: Vec<String>,
- pub since: Option<time::OffsetDateTime>,
- pub before: Option<time::OffsetDateTime>,
- pub created_by: Option<String>,
- pub assigned_by: Option<String>,
- pub mentioned_by: Option<String>,
- pub page: Option<u32>,
- pub limit: Option<u32>,
-}
-
-impl IssueQuery {
- fn to_string(&self, owner: &str, repo: &str) -> String {
- format!("repos/{owner}/{repo}/issues?state={}&labels={}&q={}&type={}&milestones={}&since={}&before={}&created_by={}&assigned_by={}&mentioned_by={}&page={}&limit={}",
- self.state.map(|s| s.as_str()).unwrap_or_default(),
- self.labels.join(","),
- self.query.as_deref().unwrap_or_default(),
- self._type.map(|t| t.as_str()).unwrap_or_default(),
- self.milestones.join(","),
- self.since.map(|t| t.format(&time::format_description::well_known::Rfc3339).unwrap()).unwrap_or_default(),
- self.before.map(|t| t.format(&time::format_description::well_known::Rfc3339).unwrap()).unwrap_or_default(),
- self.created_by.as_deref().unwrap_or_default(),
- self.assigned_by.as_deref().unwrap_or_default(),
- self.mentioned_by.as_deref().unwrap_or_default(),
- self.page.map(|page| page.to_string()).unwrap_or_default(),
- self.limit.map(|page| page.to_string()).unwrap_or_default(),
- )
- }
-}
-
-#[derive(Debug, PartialEq, Clone, Copy)]
-pub enum IssueQueryType {
- Issues,
- Pulls,
-}
-
-impl IssueQueryType {
- fn as_str(&self) -> &'static str {
- match self {
- IssueQueryType::Issues => "issues",
- IssueQueryType::Pulls => "pulls",
- }
- }
-}
-
-#[derive(Default, Debug)]
-pub struct IssueCommentQuery {
- pub since: Option<time::OffsetDateTime>,
- pub before: Option<time::OffsetDateTime>,
-}
-
-impl IssueCommentQuery {
- fn to_string(&self, owner: &str, repo: &str, issue_id: u64) -> String {
- format!(
- "repos/{owner}/{repo}/issues/{issue_id}/comments?since={}&before={}",
- self.since
- .map(|t| t
- .format(&time::format_description::well_known::Rfc3339)
- .unwrap())
- .unwrap_or_default(),
- self.before
- .map(|t| t
- .format(&time::format_description::well_known::Rfc3339)
- .unwrap())
- .unwrap_or_default(),
- )
- }
-}
-
-#[derive(Default, Debug)]
-pub struct RepoCommentQuery {
- pub since: Option<time::OffsetDateTime>,
- pub before: Option<time::OffsetDateTime>,
- pub page: Option<u32>,
- pub limit: Option<u32>,
-}
-
-impl RepoCommentQuery {
- fn to_string(&self, owner: &str, repo: &str) -> String {
- format!(
- "repos/{owner}/{repo}/issues/comments?since={}&before={}&page={}&limit={}",
- self.since
- .map(|t| t
- .format(&time::format_description::well_known::Rfc3339)
- .unwrap())
- .unwrap_or_default(),
- self.before
- .map(|t| t
- .format(&time::format_description::well_known::Rfc3339)
- .unwrap())
- .unwrap_or_default(),
- self.page.map(|page| page.to_string()).unwrap_or_default(),
- self.limit.map(|page| page.to_string()).unwrap_or_default(),
- )
- }
-}
-
-#[derive(serde::Serialize, Debug, PartialEq, Default)]
-pub struct CreateIssueOption {
- pub assignees: Vec<String>,
- pub body: Option<String>,
- pub closed: Option<bool>,
- #[serde(with = "time::serde::rfc3339::option")]
- pub due_date: Option<time::OffsetDateTime>,
- pub labels: Vec<u64>,
- pub milestone: Option<u64>,
- pub _ref: Option<String>,
- pub title: String,
-}
-
-#[derive(serde::Serialize, Debug, PartialEq, Default)]
-pub struct EditIssueOption {
- pub assignees: Vec<String>,
- pub body: Option<String>,
- #[serde(with = "time::serde::rfc3339::option")]
- pub due_date: Option<time::OffsetDateTime>,
- pub labels: Vec<u64>,
- pub milestone: Option<u64>,
- pub _ref: Option<String>,
- pub state: Option<State>,
- pub title: Option<String>,
- pub unset_due_date: Option<bool>,
-}
-
-#[derive(serde::Serialize, Debug, PartialEq, Default)]
-pub struct CreateIssueCommentOption {
- pub body: String,
-}
-
-#[derive(serde::Serialize, Debug, PartialEq, Default)]
-pub struct EditIssueCommentOption {
- pub body: String,
-}
diff --git a/src/lib.rs b/src/lib.rs
index 1776812..47d9bc2 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,5 +1,4 @@
use reqwest::{Client, Request, StatusCode};
-use serde::{de::DeserializeOwned, Serialize};
use soft_assert::*;
use url::Url;
use zeroize::Zeroize;
@@ -9,23 +8,9 @@ pub struct Forgejo {
client: Client,
}
-mod admin;
-mod issue;
-mod misc;
-mod notification;
-mod organization;
-mod package;
-mod repository;
-mod user;
+mod generated;
-pub use admin::*;
-pub use issue::*;
-pub use misc::*;
-pub use notification::*;
-pub use organization::*;
-pub use package::*;
-pub use repository::*;
-pub use user::*;
+pub use generated::structs;
#[derive(thiserror::Error, Debug)]
pub enum ForgejoError {
@@ -134,202 +119,35 @@ impl Forgejo {
Ok(Self { url, client })
}
- async fn get<T: DeserializeOwned>(&self, path: &str) -> Result<T, ForgejoError> {
- let url = self.url.join("api/v1/").unwrap().join(path).unwrap();
- let request = self.client.get(url).build()?;
- self.execute(request).await
+ fn get(&self, path: &str) -> reqwest::RequestBuilder {
+ let url = self.url.join("api/v1").unwrap().join(path).unwrap();
+ self.client.get(url)
}
- async fn get_opt<T: DeserializeOwned>(&self, path: &str) -> Result<Option<T>, ForgejoError> {
- let url = self.url.join("api/v1/").unwrap().join(path).unwrap();
- let request = self.client.get(url).build()?;
- self.execute_opt(request).await
+ fn put(&self, path: &str) -> reqwest::RequestBuilder {
+ let url = self.url.join("api/v1").unwrap().join(path).unwrap();
+ self.client.put(url)
}
- async fn get_str(&self, path: &str) -> Result<String, ForgejoError> {
- let url = self.url.join("api/v1/").unwrap().join(path).unwrap();
- let request = self.client.get(url).build()?;
- self.execute_str(request).await
+ fn post(&self, path: &str) -> reqwest::RequestBuilder {
+ let url = self.url.join("api/v1").unwrap().join(path).unwrap();
+ self.client.post(url)
}
- async fn get_exists(&self, path: &str) -> Result<bool, ForgejoError> {
- let url = self.url.join("api/v1/").unwrap().join(path).unwrap();
- let request = self.client.get(url).build()?;
- self.execute_exists(request).await
+ fn delete(&self, path: &str) -> reqwest::RequestBuilder {
+ let url = self.url.join("api/v1").unwrap().join(path).unwrap();
+ self.client.post(url)
}
- async fn post<T: Serialize, U: DeserializeOwned>(
- &self,
- path: &str,
- body: &T,
- ) -> Result<U, ForgejoError> {
- let url = self.url.join("api/v1/").unwrap().join(path).unwrap();
- let request = self.client.post(url).json(body).build()?;
- self.execute(request).await
+ fn patch(&self, path: &str) -> reqwest::RequestBuilder {
+ let url = self.url.join("api/v1").unwrap().join(path).unwrap();
+ self.client.post(url)
}
- async fn post_multipart<T: DeserializeOwned>(
- &self,
- path: &str,
- body: reqwest::multipart::Form,
- ) -> Result<T, ForgejoError> {
- let url = self.url.join("api/v1/").unwrap().join(path).unwrap();
- let request = self.client.post(url).multipart(body).build()?;
- self.execute(request).await
- }
-
- async fn post_str_out<T: Serialize>(
- &self,
- path: &str,
- body: &T,
- ) -> Result<String, ForgejoError> {
- let url = self.url.join("api/v1/").unwrap().join(path).unwrap();
- let request = self.client.post(url).json(body).build()?;
- self.execute_str(request).await
- }
-
- async fn post_unit<T: Serialize>(&self, path: &str, body: &T) -> Result<(), ForgejoError> {
- let url = self.url.join("api/v1/").unwrap().join(path).unwrap();
- let request = self.client.post(url).json(body).build()?;
- self.execute_unit(request).await
- }
-
- async fn post_raw(&self, path: &str, body: String) -> Result<String, ForgejoError> {
- let url = self.url.join("api/v1/").unwrap().join(path).unwrap();
- let request = self.client.post(url).body(body).build()?;
- self.execute_str(request).await
- }
-
- async fn delete(&self, path: &str) -> Result<(), ForgejoError> {
- let url = self.url.join("api/v1/").unwrap().join(path).unwrap();
- let request = self.client.delete(url).build()?;
- self.execute_unit(request).await
- }
-
- async fn patch<T: Serialize, U: DeserializeOwned>(
- &self,
- path: &str,
- body: &T,
- ) -> Result<U, ForgejoError> {
- let url = self.url.join("api/v1/").unwrap().join(path).unwrap();
- let request = self.client.patch(url).json(body).build()?;
- self.execute(request).await
- }
-
- async fn put<T: DeserializeOwned>(&self, path: &str) -> Result<T, ForgejoError> {
- let url = self.url.join("api/v1/").unwrap().join(path).unwrap();
- let request = self.client.put(url).build()?;
- self.execute(request).await
- }
-
- async fn execute<T: DeserializeOwned>(&self, request: Request) -> Result<T, ForgejoError> {
- let response = self.client.execute(request).await?;
- match response.status() {
- status if status.is_success() => {
- let body = response.text().await?;
- let out =
- serde_json::from_str(&body).map_err(|e| ForgejoError::BadStructure(e, body))?;
- Ok(out)
- }
- status if status.is_client_error() => Err(ForgejoError::ApiError(
- status,
- response
- .json::<ErrorMessage>()
- .await?
- .message
- .unwrap_or_else(|| String::from("[no message]")),
- )),
- status => Err(ForgejoError::UnexpectedStatusCode(status)),
- }
- }
-
- /// Like `execute`, but returns a `String`.
- async fn execute_opt_raw(
- &self,
- request: Request,
- ) -> Result<Option<bytes::Bytes>, ForgejoError> {
- let response = self.client.execute(request).await?;
- match response.status() {
- status if status.is_success() => Ok(Some(response.bytes().await?)),
- StatusCode::NOT_FOUND => Ok(None),
- status if status.is_client_error() => Err(ForgejoError::ApiError(
- status,
- response
- .json::<ErrorMessage>()
- .await?
- .message
- .unwrap_or_else(|| String::from("[no message]")),
- )),
- status => Err(ForgejoError::UnexpectedStatusCode(status)),
- }
- }
-
- /// Like `execute`, but returns a `String`.
- async fn execute_str(&self, request: Request) -> Result<String, ForgejoError> {
- let response = self.client.execute(request).await?;
- match response.status() {
- status if status.is_success() => Ok(response.text().await?),
- status if status.is_client_error() => Err(ForgejoError::ApiError(
- status,
- response
- .json::<ErrorMessage>()
- .await?
- .message
- .unwrap_or_else(|| String::from("[no message]")),
- )),
- status => Err(ForgejoError::UnexpectedStatusCode(status)),
- }
- }
-
- /// Like `execute`, but returns unit.
- async fn execute_unit(&self, request: Request) -> Result<(), ForgejoError> {
- let response = self.client.execute(request).await?;
- match response.status() {
- status if status.is_success() => Ok(()),
- status if status.is_client_error() => Err(ForgejoError::ApiError(
- status,
- response
- .json::<ErrorMessage>()
- .await?
- .message
- .unwrap_or_else(|| String::from("[no message]")),
- )),
- status => Err(ForgejoError::UnexpectedStatusCode(status)),
- }
- }
-
- /// Like `execute`, but returns `Ok(None)` on 404.
- async fn execute_opt<T: DeserializeOwned>(
- &self,
- request: Request,
- ) -> Result<Option<T>, ForgejoError> {
- let response = self.client.execute(request).await?;
- match response.status() {
- status if status.is_success() => {
- let body = response.text().await?;
- let out =
- serde_json::from_str(&body).map_err(|e| ForgejoError::BadStructure(e, body))?;
- Ok(out)
- }
- StatusCode::NOT_FOUND => Ok(None),
- status if status.is_client_error() => Err(ForgejoError::ApiError(
- status,
- response
- .json::<ErrorMessage>()
- .await?
- .message
- .unwrap_or_else(|| String::from("[no message]")),
- )),
- status => Err(ForgejoError::UnexpectedStatusCode(status)),
- }
- }
-
- /// Like `execute`, but returns `false` on 404.
- async fn execute_exists(&self, request: Request) -> Result<bool, ForgejoError> {
+ async fn execute(&self, request: Request) -> Result<reqwest::Response, ForgejoError> {
let response = self.client.execute(request).await?;
match response.status() {
- status if status.is_success() => Ok(true),
- StatusCode::NOT_FOUND => Ok(false),
+ status if status.is_success() => Ok(response),
status if status.is_client_error() => Err(ForgejoError::ApiError(
status,
response
diff --git a/src/misc.rs b/src/misc.rs
deleted file mode 100644
index 76fc3b8..0000000
--- a/src/misc.rs
+++ /dev/null
@@ -1,162 +0,0 @@
-use super::*;
-
-impl Forgejo {
- pub async fn get_gitignore_templates(&self) -> Result<Vec<String>, ForgejoError> {
- self.get("gitignore/templates").await
- }
-
- pub async fn get_gitignore_template(
- &self,
- name: &str,
- ) -> Result<Option<GitignoreTemplateInfo>, ForgejoError> {
- self.get_opt(&format!("gitignore/templates/{name}")).await
- }
-
- pub async fn get_label_templates(&self) -> Result<Vec<String>, ForgejoError> {
- self.get("label/templates").await
- }
-
- pub async fn get_label_template(&self, name: &str) -> Result<Vec<LabelTemplate>, ForgejoError> {
- self.get(&format!("label/templates/{name}")).await
- }
-
- pub async fn get_licenses(&self) -> Result<Vec<LicenseTemplateListEntry>, ForgejoError> {
- self.get("licenses").await
- }
-
- pub async fn get_license(
- &self,
- name: &str,
- ) -> Result<Option<GitignoreTemplateInfo>, ForgejoError> {
- self.get_opt(&format!("license/{name}")).await
- }
-
- pub async fn render_markdown(&self, opt: MarkdownOption) -> Result<String, ForgejoError> {
- self.post_str_out("markdown", &opt).await
- }
-
- pub async fn render_markdown_raw(&self, body: String) -> Result<String, ForgejoError> {
- self.post_raw("markdown/raw", body).await
- }
-
- pub async fn render_markup(&self, opt: MarkupOption) -> Result<String, ForgejoError> {
- self.post_str_out("markup", &opt).await
- }
-
- pub async fn nodeinfo(&self) -> Result<NodeInfo, ForgejoError> {
- self.get("nodeinfo").await
- }
-
- pub async fn signing_key(&self) -> Result<String, ForgejoError> {
- self.get_str("signing-key.gpg").await
- }
-
- pub async fn version(&self) -> Result<ServerVersion, ForgejoError> {
- self.get("version").await
- }
-}
-
-#[derive(serde::Deserialize, Debug, PartialEq)]
-pub struct GitignoreTemplateInfo {
- pub name: String,
- pub source: String,
-}
-
-#[derive(serde::Deserialize, Debug, PartialEq)]
-pub struct LabelTemplate {
- pub color: String,
- pub description: String,
- pub exclusive: bool,
- pub name: String,
-}
-
-#[derive(serde::Deserialize, Debug, PartialEq)]
-pub struct LicenseTemplateListEntry {
- pub key: String,
- pub name: String,
- pub url: Url,
-}
-
-#[derive(serde::Deserialize, Debug, PartialEq)]
-pub struct LicenseTemplateInfo {
- pub body: String,
- pub implementation: String,
- pub key: String,
- pub name: String,
- pub url: Url,
-}
-
-#[derive(serde::Serialize, Debug, PartialEq, Default)]
-pub struct MarkdownOption {
- #[serde(rename = "Context")]
- pub context: String,
- #[serde(rename = "Mode")]
- pub mode: String,
- #[serde(rename = "Text")]
- pub text: String,
- #[serde(rename = "Wiki")]
- pub wiki: String,
-}
-
-#[derive(serde::Serialize, Debug, PartialEq, Default)]
-pub struct MarkupOption {
- #[serde(rename = "Context")]
- pub context: String,
- #[serde(rename = "FilePath")]
- pub file_path: String,
- #[serde(rename = "Mode")]
- pub mode: String,
- #[serde(rename = "Text")]
- pub text: String,
- #[serde(rename = "Wiki")]
- pub wiki: String,
-}
-
-#[derive(serde::Deserialize, Debug, PartialEq)]
-pub struct NodeInfo {
- pub metadata: std::collections::BTreeMap<String, String>,
- #[serde(rename = "openRegistrations")]
- pub open_registrations: bool,
- pub protocols: Vec<String>,
- pub services: NodeInfoServices,
- pub software: NodeInfoSoftware,
- pub usage: NodeInfoUsage,
- pub version: String,
-}
-
-#[derive(serde::Deserialize, Debug, PartialEq)]
-pub struct NodeInfoServices {
- pub inbound: Vec<String>,
- pub outbound: Vec<String>,
-}
-
-#[derive(serde::Deserialize, Debug, PartialEq)]
-pub struct NodeInfoSoftware {
- pub homepage: Url,
- pub name: String,
- pub repository: Url,
- pub version: String,
-}
-
-#[derive(serde::Deserialize, Debug, PartialEq)]
-pub struct NodeInfoUsage {
- #[serde(rename = "localComments")]
- pub local_comments: u64,
- #[serde(rename = "localPosts")]
- pub local_posts: u64,
- pub users: NodeInfoUsageUsers,
-}
-
-#[derive(serde::Deserialize, Debug, PartialEq)]
-pub struct NodeInfoUsageUsers {
- #[serde(rename = "activeHalfYear")]
- pub active_half_year: u64,
- #[serde(rename = "activeMonth")]
- pub active_month: u64,
- pub total: u64,
-}
-
-#[derive(serde::Deserialize, Debug, PartialEq)]
-pub struct ServerVersion {
- pub version: String,
-}
diff --git a/src/notification.rs b/src/notification.rs
deleted file mode 100644
index 348363a..0000000
--- a/src/notification.rs
+++ /dev/null
@@ -1,273 +0,0 @@
-use super::*;
-
-impl Forgejo {
- pub async fn notifications(
- &self,
- query: NotificationQuery,
- ) -> Result<Vec<NotificationThread>, ForgejoError> {
- self.get(&format!("notifications?{}", query.query_string()))
- .await
- }
-
- pub async fn set_notifications_state(
- &self,
- query: NotificationPutQuery,
- ) -> Result<Vec<NotificationThread>, ForgejoError> {
- self.put(&format!("notifications?{}", query.query_string()))
- .await
- }
-
- pub async fn notification_count(&self) -> Result<Vec<NotificationCount>, ForgejoError> {
- self.get("notifications/new").await
- }
-
- pub async fn get_notification(
- &self,
- id: u64,
- ) -> Result<Option<NotificationThread>, ForgejoError> {
- self.get_opt(&format!("notifications/threads/{id}")).await
- }
-
- pub async fn set_notification_state(
- &self,
- id: u64,
- to_status: ToStatus,
- ) -> Result<Option<NotificationThread>, ForgejoError> {
- self.patch(
- &format!(
- "notifications/threads/{id}?to-status={}",
- to_status.as_str()
- ),
- &(),
- )
- .await
- }
-
- pub async fn get_repo_notifications(
- &self,
- owner: &str,
- name: &str,
- query: NotificationQuery,
- ) -> Result<Vec<NotificationThread>, ForgejoError> {
- self.get(&format!(
- "repos/{owner}/{name}/notifications?{}",
- query.query_string()
- ))
- .await
- }
-
- pub async fn set_repo_notifications_state(
- &self,
- owner: &str,
- name: &str,
- query: NotificationPutQuery,
- ) -> Result<Vec<NotificationThread>, ForgejoError> {
- self.put(&format!(
- "repos/{owner}/{name}/notifications?{}",
- query.query_string()
- ))
- .await
- }
-}
-
-#[derive(Debug)]
-pub struct NotificationQuery {
- pub all: bool,
- pub include_unread: bool,
- pub include_read: bool,
- pub include_pinned: bool,
- pub subject_type: Option<NotificationSubjectType>,
- pub since: Option<time::OffsetDateTime>,
- pub before: Option<time::OffsetDateTime>,
- pub page: Option<u32>,
- pub limit: Option<u32>,
-}
-
-impl Default for NotificationQuery {
- fn default() -> Self {
- NotificationQuery {
- all: false,
- include_unread: true,
- include_read: false,
- include_pinned: true,
- subject_type: None,
- since: None,
- before: None,
- page: None,
- limit: None,
- }
- }
-}
-
-impl NotificationQuery {
- fn query_string(&self) -> String {
- use std::fmt::Write;
- let mut s = String::new();
- if self.all {
- s.push_str("all=true&");
- }
- if self.include_unread {
- s.push_str("status-types=unread&");
- }
- if self.include_read {
- s.push_str("status-types=read&");
- }
- if self.include_pinned {
- s.push_str("status-types=pinned&");
- }
- if let Some(subject_type) = self.subject_type {
- s.push_str("subject-type=");
- s.push_str(subject_type.as_str());
- s.push('&');
- }
- if let Some(since) = &self.since {
- s.push_str("since=");
- s.push_str(
- &since
- .format(&time::format_description::well_known::Rfc3339)
- .unwrap(),
- );
- s.push('&');
- }
- if let Some(before) = &self.before {
- s.push_str("before=");
- s.push_str(
- &before
- .format(&time::format_description::well_known::Rfc3339)
- .unwrap(),
- );
- s.push('&');
- }
- if let Some(page) = self.page {
- s.push_str("page=");
- s.write_fmt(format_args!("{page}"))
- .expect("writing to a string never fails");
- s.push('&');
- }
- if let Some(limit) = self.limit {
- s.push_str("limit=");
- s.write_fmt(format_args!("{limit}"))
- .expect("writing to a string never fails");
- }
- s
- }
-}
-
-#[derive(Debug, Clone, Copy)]
-pub enum NotificationSubjectType {
- Issue,
- Pull,
- Commit,
- Repository,
-}
-
-impl NotificationSubjectType {
- fn as_str(&self) -> &'static str {
- match self {
- NotificationSubjectType::Issue => "issue",
- NotificationSubjectType::Pull => "pull",
- NotificationSubjectType::Commit => "commit",
- NotificationSubjectType::Repository => "repository",
- }
- }
-}
-
-#[derive(serde::Deserialize, Debug, PartialEq)]
-pub struct NotificationThread {
- pub id: u64,
- pub pinned: bool,
- pub repository: Repository,
- pub subject: NotificationSubject,
- pub unread: bool,
- #[serde(with = "time::serde::rfc3339")]
- pub updated_at: time::OffsetDateTime,
- pub url: Url,
-}
-
-#[derive(serde::Deserialize, Debug, PartialEq)]
-pub struct NotificationSubject {
- pub html_url: Url,
- pub latest_comment_html_url: Url,
- pub latest_comment_url: Url,
- pub state: String,
- pub title: String,
- #[serde(rename = "type")]
- pub _type: String,
- pub url: Url,
-}
-
-#[derive(Debug)]
-pub struct NotificationPutQuery {
- pub last_read_at: Option<time::OffsetDateTime>,
- pub all: bool,
- pub include_unread: bool,
- pub include_read: bool,
- pub include_pinned: bool,
- pub to_status: ToStatus,
-}
-
-impl Default for NotificationPutQuery {
- fn default() -> Self {
- NotificationPutQuery {
- last_read_at: None,
- all: false,
- include_unread: true,
- include_read: false,
- include_pinned: false,
- to_status: ToStatus::default(),
- }
- }
-}
-
-impl NotificationPutQuery {
- fn query_string(&self) -> String {
- let mut s = String::new();
- if let Some(last_read_at) = &self.last_read_at {
- s.push_str("since=");
- s.push_str(
- &last_read_at
- .format(&time::format_description::well_known::Rfc3339)
- .unwrap(),
- );
- s.push('&');
- }
- if self.all {
- s.push_str("all=true&");
- }
- if self.include_unread {
- s.push_str("status-types=unread&");
- }
- if self.include_read {
- s.push_str("status-types=read&");
- }
- if self.include_pinned {
- s.push_str("status-types=pinned&");
- }
- s.push_str("subject-type=");
- s.push_str(self.to_status.as_str());
- s
- }
-}
-
-#[derive(Default, Debug)]
-pub enum ToStatus {
- #[default]
- Read,
- Unread,
- Pinned,
-}
-
-impl ToStatus {
- fn as_str(&self) -> &'static str {
- match self {
- ToStatus::Read => "read",
- ToStatus::Unread => "unread",
- ToStatus::Pinned => "pinned",
- }
- }
-}
-
-#[derive(serde::Deserialize, Debug, PartialEq)]
-pub struct NotificationCount {
- pub new: u64,
-}
diff --git a/src/organization.rs b/src/organization.rs
deleted file mode 100644
index 6a54f10..0000000
--- a/src/organization.rs
+++ /dev/null
@@ -1,30 +0,0 @@
-use crate::*;
-use std::collections::BTreeMap;
-
-#[derive(serde::Deserialize, Debug, PartialEq)]
-pub struct Organization {
- #[serde(deserialize_with = "crate::none_if_blank_url")]
- pub avatar_url: Option<Url>,
- pub description: String,
- pub full_name: String,
- pub id: u64,
- pub location: Option<String>,
- pub name: String,
- pub repo_admin_change_team_access: bool,
- pub visibility: String,
- #[serde(deserialize_with = "crate::none_if_blank_url")]
- pub website: Option<Url>,
-}
-
-#[derive(serde::Deserialize, Debug, PartialEq)]
-pub struct Team {
- pub can_create_org_repo: bool,
- pub description: String,
- pub id: u64,
- pub includes_all_repositories: bool,
- pub name: String,
- pub organization: Organization,
- pub permission: String,
- pub units: Vec<String>,
- pub units_map: BTreeMap<String, String>,
-}
diff --git a/src/package.rs b/src/package.rs
deleted file mode 100644
index 4c49d5b..0000000
--- a/src/package.rs
+++ /dev/null
@@ -1,174 +0,0 @@
-use std::fmt::Write;
-
-use super::*;
-
-impl Forgejo {
- pub async fn get_user_packages(
- &self,
- owner: &str,
- query: PackagesQuery,
- ) -> Result<Vec<Package>, ForgejoError> {
- self.get(&query.path(owner)).await
- }
-
- pub async fn get_package(
- &self,
- owner: &str,
- _type: PackageType,
- name: &str,
- version: &str,
- ) -> Result<Option<Package>, ForgejoError> {
- self.get_opt(&format!(
- "packages/{owner}/{}/{name}/{version}",
- _type.as_str()
- ))
- .await
- }
-
- pub async fn delete_package(
- &self,
- owner: &str,
- _type: PackageType,
- name: &str,
- version: &str,
- ) -> Result<(), ForgejoError> {
- self.delete(&format!(
- "packages/{owner}/{}/{name}/{version}",
- _type.as_str()
- ))
- .await
- }
-
- pub async fn get_package_files(
- &self,
- owner: &str,
- _type: PackageType,
- name: &str,
- version: &str,
- ) -> Result<Vec<PackageFile>, ForgejoError> {
- self.get(&format!(
- "packages/{owner}/{}/{name}/{version}",
- _type.as_str()
- ))
- .await
- }
-}
-
-#[derive(Default, Debug)]
-pub struct PackagesQuery {
- pub page: Option<u32>,
- pub limit: Option<u32>,
- pub kind: Option<PackageType>,
- pub query: String,
-}
-
-impl PackagesQuery {
- fn path(&self, owner: &str) -> String {
- let mut s = String::from("packages/");
- s.push_str(owner);
- s.push('?');
- if let Some(page) = self.page {
- s.push_str("page=");
- s.write_fmt(format_args!("{page}"))
- .expect("writing to string can't fail");
- s.push('&');
- }
- if let Some(limit) = self.limit {
- s.push_str("limit=");
- s.write_fmt(format_args!("{limit}"))
- .expect("writing to string can't fail");
- s.push('&');
- }
- if let Some(kind) = self.kind {
- s.push_str("type=");
- s.push_str(kind.as_str());
- s.push('&');
- }
- if !self.query.is_empty() {
- s.push_str("q=");
- s.push_str(&self.query);
- s.push('&');
- }
- s
- }
-}
-
-#[derive(serde::Deserialize, Debug, PartialEq, Eq, Clone, Copy)]
-#[serde(rename_all = "lowercase")]
-#[non_exhaustive]
-pub enum PackageType {
- Alpine,
- Cargo,
- Chef,
- Composer,
- Conan,
- Conda,
- Container,
- Cran,
- Debian,
- Generic,
- Go,
- Helm,
- Maven,
- Npm,
- Nuget,
- Pub,
- Pypi,
- Rpm,
- RubyGems,
- Swift,
- Vagrant,
-}
-
-impl PackageType {
- fn as_str(&self) -> &'static str {
- match self {
- PackageType::Alpine => "alpine",
- PackageType::Cargo => "cargo",
- PackageType::Chef => "chef",
- PackageType::Composer => "composer",
- PackageType::Conan => "conan",
- PackageType::Conda => "conda",
- PackageType::Container => "container",
- PackageType::Cran => "cran",
- PackageType::Debian => "debian",
- PackageType::Generic => "generic",
- PackageType::Go => "go",
- PackageType::Helm => "helm",
- PackageType::Maven => "maven",
- PackageType::Npm => "npm",
- PackageType::Nuget => "nuget",
- PackageType::Pub => "pub",
- PackageType::Pypi => "pypi",
- PackageType::Rpm => "rpm",
- PackageType::RubyGems => "rubygems",
- PackageType::Swift => "swift",
- PackageType::Vagrant => "vagrant",
- }
- }
-}
-
-#[derive(serde::Deserialize, Debug, PartialEq)]
-pub struct Package {
- #[serde(with = "time::serde::rfc3339")]
- pub created_at: time::OffsetDateTime,
- pub creator: User,
- pub id: u64,
- pub name: String,
- pub owner: User,
- pub repository: Option<Repository>,
- pub _type: PackageType,
- pub version: String,
-}
-
-#[derive(serde::Deserialize, Debug, PartialEq)]
-pub struct PackageFile {
- #[serde(rename = "Size")]
- pub size: u64,
- pub id: u64,
- pub md5: String,
- pub name: String,
- pub sha1: String,
- pub sha256: String,
- pub sha512: String,
-}
diff --git a/src/repository.rs b/src/repository.rs
deleted file mode 100644
index eb638ac..0000000
--- a/src/repository.rs
+++ /dev/null
@@ -1,743 +0,0 @@
-use super::*;
-
-/// Repository operations.
-impl Forgejo {
- /// Gets info about the specified repository.
- pub async fn get_repo(
- &self,
- user: &str,
- repo: &str,
- ) -> Result<Option<Repository>, ForgejoError> {
- self.get_opt(&format!("repos/{user}/{repo}/")).await
- }
-
- /// Creates a repository.
- pub async fn create_repo(&self, repo: CreateRepoOption) -> Result<Repository, ForgejoError> {
- self.post("user/repos", &repo).await
- }
-
- pub async fn get_pulls(
- &self,
- owner: &str,
- repo: &str,
- query: PullQuery,
- ) -> Result<Vec<PullRequest>, ForgejoError> {
- self.get(&query.to_string(owner, repo)).await
- }
-
- pub async fn create_pr(
- &self,
- owner: &str,
- repo: &str,
- opts: CreatePullRequestOption,
- ) -> Result<PullRequest, ForgejoError> {
- self.post(&format!("repos/{owner}/{repo}/pulls"), &opts)
- .await
- }
-
- pub async fn is_merged(&self, owner: &str, repo: &str, pr: u64) -> Result<bool, ForgejoError> {
- self.get_exists(&format!("repos/{owner}/{repo}/pulls/{pr}/merge"))
- .await
- }
-
- pub async fn merge_pr(
- &self,
- owner: &str,
- repo: &str,
- pr: u64,
- opts: MergePullRequestOption,
- ) -> Result<(), ForgejoError> {
- self.post_unit(&format!("repos/{owner}/{repo}/pulls/{pr}/merge"), &opts)
- .await
- }
-
- pub async fn cancel_merge(&self, owner: &str, repo: &str, pr: u64) -> Result<(), ForgejoError> {
- self.delete(&format!("repos/{owner}/{repo}/pulls/{pr}/merge"))
- .await
- }
-
- pub async fn get_releases(
- &self,
- owner: &str,
- repo: &str,
- query: ReleaseQuery,
- ) -> Result<Vec<Release>, ForgejoError> {
- self.get(&query.to_string(owner, repo)).await
- }
-
- pub async fn get_release(
- &self,
- owner: &str,
- repo: &str,
- id: u64,
- ) -> Result<Option<Release>, ForgejoError> {
- self.get_opt(&format!("repos/{owner}/{repo}/releases/{id}"))
- .await
- }
-
- pub async fn get_release_by_tag(
- &self,
- owner: &str,
- repo: &str,
- tag: &str,
- ) -> Result<Option<Release>, ForgejoError> {
- self.get_opt(&format!("repos/{owner}/{repo}/releases/tags/{tag}"))
- .await
- }
-
- pub async fn delete_release(
- &self,
- owner: &str,
- repo: &str,
- id: u64,
- ) -> Result<(), ForgejoError> {
- self.delete(&format!("repos/{owner}/{repo}/releases/{id}"))
- .await
- }
-
- pub async fn delete_release_by_tag(
- &self,
- owner: &str,
- repo: &str,
- tag: &str,
- ) -> Result<(), ForgejoError> {
- self.delete(&format!("repos/{owner}/{repo}/releases/tags/{tag}"))
- .await
- }
-
- pub async fn edit_release(
- &self,
- owner: &str,
- repo: &str,
- id: u64,
- opts: EditReleaseOption,
- ) -> Result<Release, ForgejoError> {
- self.patch(&format!("repos/{owner}/{repo}/releases/{id}"), &opts)
- .await
- }
-
- pub async fn get_release_attachments(
- &self,
- owner: &str,
- repo: &str,
- id: u64,
- ) -> Result<Vec<Attachment>, ForgejoError> {
- self.get(&format!("repos/{owner}/{repo}/releases/{id}/assets"))
- .await
- }
-
- pub async fn get_release_attachment(
- &self,
- owner: &str,
- repo: &str,
- release_id: u64,
- attachment_id: u64,
- ) -> Result<Attachment, ForgejoError> {
- self.get(&format!(
- "repos/{owner}/{repo}/releases/{release_id}/assets/{attachment_id}"
- ))
- .await
- }
-
- pub async fn create_release_attachment(
- &self,
- owner: &str,
- repo: &str,
- id: u64,
- name: &str,
- file: Vec<u8>,
- ) -> Result<Attachment, ForgejoError> {
- self.post_multipart(
- &format!("repos/{owner}/{repo}/releases/{id}/assets?name={name}"),
- reqwest::multipart::Form::new().part(
- "attachment",
- reqwest::multipart::Part::bytes(file)
- .file_name("file")
- .mime_str("*/*")
- .unwrap(),
- ),
- )
- .await
- }
-
- pub async fn delete_release_attachment(
- &self,
- owner: &str,
- repo: &str,
- release_id: u64,
- attachment_id: u64,
- ) -> Result<(), ForgejoError> {
- self.delete(&format!(
- "repos/{owner}/{repo}/releases/{release_id}/assets/{attachment_id}"
- ))
- .await
- }
-
- pub async fn edit_release_attachment(
- &self,
- owner: &str,
- repo: &str,
- release_id: u64,
- attachment_id: u64,
- opts: EditAttachmentOption,
- ) -> Result<Attachment, ForgejoError> {
- self.patch(
- &format!("repos/{owner}/{repo}/releases/{release_id}/assets/{attachment_id}"),
- &opts,
- )
- .await
- }
-
- pub async fn create_release(
- &self,
- owner: &str,
- repo: &str,
- opts: CreateReleaseOption,
- ) -> Result<Release, ForgejoError> {
- self.post(&format!("repos/{owner}/{repo}/releases"), &opts)
- .await
- }
-
- pub async fn latest_release(
- &self,
- owner: &str,
- repo: &str,
- ) -> Result<Option<Release>, ForgejoError> {
- self.get_opt(&format!("repos/{owner}/{repo}/releases/latest"))
- .await
- }
-
- pub async fn download_zip_archive(
- &self,
- owner: &str,
- repo: &str,
- target: &str,
- ) -> Result<Option<bytes::Bytes>, ForgejoError> {
- let request = self
- .client
- .get(
- self.url
- .join(&format!("api/v1/repos/{owner}/{repo}/archive/{target}.zip"))
- .unwrap(),
- )
- .build()?;
- self.execute_opt_raw(request).await
- }
-
- pub async fn download_tarball_archive(
- &self,
- owner: &str,
- repo: &str,
- target: &str,
- ) -> Result<Option<bytes::Bytes>, ForgejoError> {
- let request = self
- .client
- .get(
- self.url
- .join(&format!(
- "api/v1/repos/{owner}/{repo}/archive/{target}.tar.gz"
- ))
- .unwrap(),
- )
- .build()?;
- self.execute_opt_raw(request).await
- }
-
- pub async fn download_release_attachment(
- &self,
- owner: &str,
- repo: &str,
- release: u64,
- attach: u64,
- ) -> Result<Option<bytes::Bytes>, ForgejoError> {
- let release = self
- .get_release_attachment(owner, repo, release, attach)
- .await?;
- let request = self.client.get(release.browser_download_url).build()?;
- self.execute_opt_raw(request).await
- }
-
- pub async fn get_tags(
- &self,
- owner: &str,
- repo: &str,
- query: TagQuery,
- ) -> Result<Vec<Tag>, ForgejoError> {
- self.get(&query.to_string(owner, repo)).await
- }
-
- pub async fn create_tag(
- &self,
- owner: &str,
- repo: &str,
- opts: CreateTagOption,
- ) -> Result<Tag, ForgejoError> {
- self.post(&format!("repos/{owner}/{repo}/tags"), &opts)
- .await
- }
-
- pub async fn get_tag(
- &self,
- owner: &str,
- repo: &str,
- tag: &str,
- ) -> Result<Option<Tag>, ForgejoError> {
- self.get_opt(&format!("repos/{owner}/{repo}/tags/{tag}"))
- .await
- }
-
- pub async fn delete_tag(&self, owner: &str, repo: &str, tag: &str) -> Result<(), ForgejoError> {
- self.delete(&format!("repos/{owner}/{repo}/tags/{tag}"))
- .await
- }
-}
-
-#[derive(serde::Deserialize, Debug, PartialEq)]
-pub struct Repository {
- pub allow_merge_commits: bool,
- pub allow_rebase: bool,
- pub allow_rebase_explicit: bool,
- pub allow_rebase_update: bool,
- pub allow_squash_merge: bool,
- pub archived: bool,
- #[serde(with = "time::serde::rfc3339::option")]
- pub archived_at: Option<time::OffsetDateTime>,
- #[serde(deserialize_with = "crate::none_if_blank_url")]
- pub avatar_url: Option<Url>,
- pub clone_url: Url,
- #[serde(with = "time::serde::rfc3339")]
- pub created_at: time::OffsetDateTime,
- pub default_allow_maintainer_edit: bool,
- pub default_branch: String,
- pub default_delete_branch_after_merge: bool,
- pub default_merge_style: String,
- pub description: String,
- pub empty: bool,
- pub external_tracker: Option<ExternalTracker>,
- pub external_wiki: Option<ExternalWiki>,
- pub fork: bool,
- pub forks_count: u64,
- pub full_name: String,
- pub has_actions: bool,
- pub has_issues: bool,
- pub has_packages: bool,
- pub has_projects: bool,
- pub has_pull_requests: bool,
- pub has_releases: bool,
- pub has_wiki: bool,
- pub html_url: Url,
- pub id: u64,
- pub ignore_whitespace_conflicts: bool,
- pub internal: bool,
- pub internal_tracker: Option<InternalTracker>,
- pub language: String,
- pub languages_url: Url,
- pub link: String,
- pub mirror: bool,
- pub mirror_interval: Option<String>,
- #[serde(with = "time::serde::rfc3339::option")]
- pub mirror_updated: Option<time::OffsetDateTime>,
- pub name: String,
- pub open_issues_count: u64,
- pub open_pr_counter: u64,
- #[serde(deserialize_with = "crate::none_if_blank_url")]
- pub original_url: Option<Url>,
- pub owner: User,
- pub parent: Option<Box<Repository>>,
- pub permissions: Permission,
- pub private: bool,
- pub release_counter: u64,
- pub repo_transfer: Option<RepoTransfer>,
- pub size: u64,
- pub ssh_url: String,
- pub stars_count: u64,
- pub template: bool,
- #[serde(with = "time::serde::rfc3339")]
- pub updated_at: time::OffsetDateTime,
- pub url: Url,
- pub watchers_count: u64,
- pub website: Option<String>,
-}
-
-#[derive(serde::Deserialize, Debug, PartialEq)]
-pub struct RepositoryMeta {
- pub full_name: String,
- pub id: u64,
- pub name: String,
- pub owner: String,
-}
-
-#[derive(serde::Serialize, Debug, PartialEq)]
-pub struct CreateRepoOption {
- pub auto_init: bool,
- pub default_branch: String,
- pub description: Option<String>,
- pub gitignores: String,
- pub issue_labels: String,
- pub license: String,
- pub name: String,
- pub private: bool,
- pub readme: String,
- pub template: bool,
- pub trust_model: TrustModel,
-}
-
-#[derive(serde::Serialize, Debug, PartialEq)]
-pub enum TrustModel {
- Default,
- Collaborator,
- Committer,
- #[serde(rename = "collaboratorcommiter")]
- CollaboratorCommitter,
-}
-
-#[derive(serde::Deserialize, Debug, PartialEq)]
-pub struct Milestone {
- #[serde(with = "time::serde::rfc3339::option")]
- pub closed_at: Option<time::OffsetDateTime>,
- pub closed_issues: u64,
- #[serde(with = "time::serde::rfc3339")]
- pub created_at: time::OffsetDateTime,
- pub description: String,
- #[serde(with = "time::serde::rfc3339::option")]
- pub due_on: Option<time::OffsetDateTime>,
- pub id: u64,
- pub open_issues: u64,
- pub state: State,
- pub title: String,
- #[serde(with = "time::serde::rfc3339")]
- pub updated_at: time::OffsetDateTime,
-}
-
-#[derive(serde::Deserialize, Debug, PartialEq)]
-pub struct PullRequest {
- pub allow_maintainer_edit: bool,
- pub assignee: User,
- pub assignees: Vec<User>,
- pub base: PrBranchInfo,
- pub body: String,
- #[serde(with = "time::serde::rfc3339::option")]
- pub closed_at: Option<time::OffsetDateTime>,
- pub comments: u64,
- #[serde(with = "time::serde::rfc3339")]
- pub created_at: time::OffsetDateTime,
- pub diff_url: Url,
- #[serde(with = "time::serde::rfc3339::option")]
- pub due_date: Option<time::OffsetDateTime>,
- pub head: PrBranchInfo,
- pub html_url: Url,
- pub id: u64,
- pub is_locked: bool,
- pub labels: Vec<Label>,
- pub merge_base: String,
- pub merge_commit_sha: Option<String>,
- pub mergeable: bool,
- pub merged: bool,
- #[serde(with = "time::serde::rfc3339::option")]
- pub merged_at: Option<time::OffsetDateTime>,
- pub merged_by: Option<User>,
- pub milestone: Option<Milestone>,
- pub number: u64,
- pub patch_url: Url,
- pub pin_order: u64,
- pub requested_reviewers: Option<Vec<User>>,
- pub state: State,
- pub title: String,
- #[serde(with = "time::serde::rfc3339")]
- pub updated_at: time::OffsetDateTime,
- pub url: Url,
- pub user: User,
-}
-
-#[derive(serde::Deserialize, Debug, PartialEq)]
-pub struct PrBranchInfo {
- pub label: String,
- #[serde(rename = "ref")]
- pub _ref: String,
- pub repo: Repository,
- pub repo_id: u64,
- pub sha: String,
-}
-
-#[derive(serde::Deserialize, Debug, PartialEq)]
-pub struct PullRequestMeta {
- pub merged: bool,
- #[serde(with = "time::serde::rfc3339::option")]
- pub merged_at: Option<time::OffsetDateTime>,
-}
-
-#[derive(Debug)]
-pub struct PullQuery {
- pub state: Option<State>,
- pub sort: Option<PullQuerySort>,
- pub milestone: Option<u64>,
- pub labels: Vec<u64>,
- pub page: Option<u32>,
- pub limit: Option<u32>,
-}
-
-impl PullQuery {
- fn to_string(&self, owner: &str, repo: &str) -> String {
- use std::fmt::Write;
- // This is different to other query struct serialization because
- // `labels` is serialized so strangely
- let mut s = String::new();
- s.push_str("repos/");
- s.push_str(owner);
- s.push('/');
- s.push_str(repo);
- s.push_str("/pulls?");
- if let Some(state) = self.state {
- s.push_str("state=");
- s.push_str(state.as_str());
- s.push('&');
- }
- if let Some(sort) = self.sort {
- s.push_str("sort=");
- s.push_str(sort.as_str());
- s.push('&');
- }
- if let Some(milestone) = self.milestone {
- s.push_str("sort=");
- s.write_fmt(format_args!("{milestone}"))
- .expect("writing to a string never fails");
- s.push('&');
- }
- for label in &self.labels {
- s.push_str("labels=");
- s.write_fmt(format_args!("{label}"))
- .expect("writing to a string never fails");
- s.push('&');
- }
- if let Some(page) = self.page {
- s.push_str("page=");
- s.write_fmt(format_args!("{page}"))
- .expect("writing to a string never fails");
- s.push('&');
- }
- if let Some(limit) = self.limit {
- s.push_str("limit=");
- s.write_fmt(format_args!("{limit}"))
- .expect("writing to a string never fails");
- s.push('&');
- }
- s
- }
-}
-
-#[derive(Clone, Copy, Debug)]
-pub enum PullQuerySort {
- Oldest,
- RecentUpdate,
- LeastUpdate,
- MostComment,
- LeastComment,
- Priority,
-}
-
-impl PullQuerySort {
- fn as_str(&self) -> &'static str {
- match self {
- PullQuerySort::Oldest => "oldest",
- PullQuerySort::RecentUpdate => "recentupdate",
- PullQuerySort::LeastUpdate => "leastupdate",
- PullQuerySort::MostComment => "mostcomment",
- PullQuerySort::LeastComment => "leastcomment",
- PullQuerySort::Priority => "priority",
- }
- }
-}
-
-#[derive(serde::Serialize, Debug, PartialEq, Default)]
-pub struct CreatePullRequestOption {
- pub assignee: Option<String>,
- pub assignees: Vec<String>,
- pub base: String,
- pub body: String,
- #[serde(with = "time::serde::rfc3339::option")]
- pub due_date: Option<time::OffsetDateTime>,
- pub head: String,
- pub labels: Vec<u64>,
- pub milestone: Option<u64>,
- pub title: String,
-}
-
-#[derive(serde::Serialize, Debug, PartialEq, Default)]
-pub struct MergePullRequestOption {
- #[serde(rename = "Do")]
- pub act: MergePrAction,
- #[serde(rename = "MergeCommitId")]
- pub merge_commit_id: Option<String>,
- #[serde(rename = "MergeMessageField")]
- pub merge_message_field: Option<String>,
- #[serde(rename = "MergeTitleField")]
- pub merge_title_field: Option<String>,
- pub delete_branch_after_merge: Option<bool>,
- pub force_merge: Option<bool>,
- pub head_commit_id: Option<String>,
- pub merge_when_checks_succeed: Option<bool>,
-}
-
-#[derive(serde::Serialize, Debug, PartialEq, Default)]
-pub enum MergePrAction {
- #[serde(rename = "merge")]
- #[default]
- Merge,
- #[serde(rename = "rebase")]
- Rebase,
- #[serde(rename = "rebase-merge")]
- RebaseMerge,
- #[serde(rename = "squash")]
- Squash,
- #[serde(rename = "manually-merged")]
- ManuallyMerged,
-}
-
-#[derive(serde::Deserialize, Debug, PartialEq)]
-pub struct Release {
- pub assets: Vec<Attachment>,
- pub author: User,
- pub body: String,
- #[serde(with = "time::serde::rfc3339")]
- pub created_at: time::OffsetDateTime,
- pub draft: bool,
- pub html_url: Url,
- pub id: u64,
- pub name: String,
- pub prerelease: bool,
- #[serde(with = "time::serde::rfc3339")]
- pub published_at: time::OffsetDateTime,
- pub tag_name: String,
- pub tarball_url: Url,
- pub target_commitish: String,
- pub url: Url,
- pub zipball_url: Url,
-}
-
-#[derive(serde::Serialize, Debug, PartialEq, Default)]
-pub struct CreateReleaseOption {
- pub body: String,
- pub draft: bool,
- pub name: String,
- pub prerelease: bool,
- pub tag_name: String,
- pub target_commitish: Option<String>,
-}
-
-#[derive(serde::Serialize, Debug, PartialEq, Default)]
-pub struct EditReleaseOption {
- pub body: Option<String>,
- pub draft: Option<bool>,
- pub name: Option<String>,
- pub prerelease: Option<bool>,
- pub tag_name: Option<String>,
- pub target_commitish: Option<String>,
-}
-
-#[derive(Default, Debug)]
-pub struct ReleaseQuery {
- pub draft: Option<bool>,
- pub prerelease: Option<bool>,
- pub page: Option<u32>,
- pub limit: Option<u32>,
-}
-
-impl ReleaseQuery {
- fn to_string(&self, owner: &str, repo: &str) -> String {
- format!(
- "repos/{owner}/{repo}/releases?draft={}&pre-release={}&page={}&limit={}",
- opt_bool_s(self.draft),
- opt_bool_s(self.prerelease),
- self.page.map(|page| page.to_string()).unwrap_or_default(),
- self.limit.map(|page| page.to_string()).unwrap_or_default(),
- )
- }
-}
-
-fn opt_bool_s(b: Option<bool>) -> &'static str {
- match b {
- Some(true) => "true",
- Some(false) => "false",
- None => "",
- }
-}
-
-#[derive(serde::Deserialize, Debug, PartialEq)]
-pub struct Tag {
- pub commit: CommitMeta,
- pub id: String,
- pub message: String,
- pub name: String,
- pub tarball_url: Url,
- pub zipball_url: Url,
-}
-
-#[derive(serde::Serialize, Debug, PartialEq, Default)]
-pub struct CreateTagOption {
- pub message: Option<String>,
- pub tag_name: String,
- pub target: Option<String>,
-}
-
-#[derive(Default, Debug)]
-pub struct TagQuery {
- pub page: Option<u32>,
- pub limit: Option<u32>,
-}
-
-impl TagQuery {
- fn to_string(&self, owner: &str, repo: &str) -> String {
- format!(
- "repos/{owner}/{repo}/tags?page={}&limit={}",
- self.page.map(|page| page.to_string()).unwrap_or_default(),
- self.limit.map(|page| page.to_string()).unwrap_or_default(),
- )
- }
-}
-
-#[derive(serde::Deserialize, Debug, PartialEq)]
-pub struct CommitMeta {
- #[serde(with = "time::serde::rfc3339")]
- pub created: time::OffsetDateTime,
- pub url: Url,
- pub sha: String,
-}
-
-#[derive(serde::Deserialize, Debug, PartialEq)]
-pub struct ExternalTracker {
- #[serde(rename = "external_tracker_format")]
- pub format: String,
- #[serde(rename = "external_tracker_regexp_pattern")]
- pub regexp_pattern: String,
- #[serde(rename = "external_tracker_style")]
- pub style: String,
- #[serde(rename = "external_tracker_url")]
- pub url: Url,
-}
-
-#[derive(serde::Deserialize, Debug, PartialEq)]
-pub struct InternalTracker {
- pub allow_only_contributors_to_track_time: bool,
- pub enable_issue_dependencies: bool,
- pub enable_time_tracker: bool,
-}
-
-#[derive(serde::Deserialize, Debug, PartialEq)]
-pub struct ExternalWiki {
- #[serde(rename = "external_wiki_url")]
- pub url: Url,
-}
-
-#[derive(serde::Deserialize, Debug, PartialEq)]
-pub struct Permission {
- pub admin: bool,
- pub pull: bool,
- pub push: bool,
-}
-
-#[derive(serde::Deserialize, Debug, PartialEq)]
-pub struct RepoTransfer {
- pub doer: User,
- pub recipient: User,
- pub teams: Vec<Team>,
-}
diff --git a/src/user.rs b/src/user.rs
deleted file mode 100644
index a99a5e2..0000000
--- a/src/user.rs
+++ /dev/null
@@ -1,59 +0,0 @@
-use super::*;
-
-/// User operations.
-impl Forgejo {
- /// Returns info about the authorized user.
- pub async fn myself(&self) -> Result<User, ForgejoError> {
- self.get("user").await
- }
-
- /// Returns info about the specified user.
- pub async fn get_user(&self, user: &str) -> Result<Option<User>, ForgejoError> {
- self.get_opt(&format!("users/{user}/")).await
- }
-
- /// Gets the list of users that follow the specified user.
- pub async fn get_followers(&self, user: &str) -> Result<Option<Vec<User>>, ForgejoError> {
- self.get_opt(&format!("users/{user}/followers/")).await
- }
-
- /// Gets the list of users the specified user is following.
- pub async fn get_following(&self, user: &str) -> Result<Option<Vec<User>>, ForgejoError> {
- self.get_opt(&format!("users/{user}/following/")).await
- }
-}
-
-#[derive(serde::Deserialize, Debug, PartialEq)]
-pub struct User {
- pub active: bool,
- pub avatar_url: Url,
- #[serde(with = "time::serde::rfc3339")]
- pub created: time::OffsetDateTime,
- pub description: String,
- pub email: String,
- pub followers_count: u64,
- pub following_count: u64,
- pub full_name: String,
- pub id: u64,
- pub is_admin: bool,
- pub language: String,
- #[serde(with = "time::serde::rfc3339")]
- pub last_login: time::OffsetDateTime,
- pub location: String,
- pub login: String,
- pub login_name: String,
- pub prohibit_login: bool,
- pub restricted: bool,
- pub starred_repos_count: u64,
- pub website: String,
-}
-
-#[derive(serde::Deserialize, Debug, PartialEq)]
-pub enum UserVisibility {
- #[serde(rename = "public")]
- Public,
- #[serde(rename = "limited")]
- Limited,
- #[serde(rename = "private")]
- Private,
-}