Merge pull request 'fill in Repository
struct fields' (#14) from full-repo-struct into main
Reviewed-on: https://codeberg.org/Cyborus/forgejo-api/pulls/14
This commit is contained in:
commit
5ea0c4d9f3
50
src/issue.rs
50
src/issue.rs
|
@ -200,61 +200,13 @@ pub struct Comment {
|
||||||
pub issue_url: Url,
|
pub issue_url: Url,
|
||||||
pub original_author: String,
|
pub original_author: String,
|
||||||
pub original_author_id: u64,
|
pub original_author_id: u64,
|
||||||
#[serde(deserialize_with = "none_if_blank_url")]
|
#[serde(deserialize_with = "crate::none_if_blank_url")]
|
||||||
pub pull_request_url: Option<Url>,
|
pub pull_request_url: Option<Url>,
|
||||||
#[serde(with = "time::serde::rfc3339")]
|
#[serde(with = "time::serde::rfc3339")]
|
||||||
pub updated_at: time::OffsetDateTime,
|
pub updated_at: time::OffsetDateTime,
|
||||||
pub user: User,
|
pub user: User,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn none_if_blank_url<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Result<Option<Url>, D::Error> {
|
|
||||||
use serde::de::{Error, Unexpected, Visitor};
|
|
||||||
use std::fmt;
|
|
||||||
|
|
||||||
struct EmptyUrlVisitor;
|
|
||||||
|
|
||||||
impl<'de> Visitor<'de> for EmptyUrlVisitor
|
|
||||||
{
|
|
||||||
type Value = Option<Url>;
|
|
||||||
|
|
||||||
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
formatter.write_str("option")
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_unit<E>(self) -> Result<Self::Value, E>
|
|
||||||
where
|
|
||||||
E: Error,
|
|
||||||
{
|
|
||||||
Ok(None)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_none<E>(self) -> Result<Self::Value, E>
|
|
||||||
where
|
|
||||||
E: Error,
|
|
||||||
{
|
|
||||||
Ok(None)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
|
|
||||||
where
|
|
||||||
E: Error,
|
|
||||||
{
|
|
||||||
if s.is_empty() {
|
|
||||||
return Ok(None);
|
|
||||||
}
|
|
||||||
Url::parse(s).map_err(|err| {
|
|
||||||
let err_s = format!("{}", err);
|
|
||||||
Error::invalid_value(Unexpected::Str(s), &err_s.as_str())
|
|
||||||
}).map(Some)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
deserializer.deserialize_str(EmptyUrlVisitor)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Default, Debug)]
|
#[derive(Default, Debug)]
|
||||||
pub struct IssueQuery {
|
pub struct IssueQuery {
|
||||||
pub state: Option<State>,
|
pub state: Option<State>,
|
||||||
|
|
53
src/lib.rs
53
src/lib.rs
|
@ -8,10 +8,12 @@ pub struct Forgejo {
|
||||||
client: Client,
|
client: Client,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mod organization;
|
||||||
mod issue;
|
mod issue;
|
||||||
mod repository;
|
mod repository;
|
||||||
mod user;
|
mod user;
|
||||||
|
|
||||||
|
pub use organization::*;
|
||||||
pub use issue::*;
|
pub use issue::*;
|
||||||
pub use repository::*;
|
pub use repository::*;
|
||||||
pub use user::*;
|
pub use user::*;
|
||||||
|
@ -156,3 +158,54 @@ struct ErrorMessage {
|
||||||
// intentionally ignored, no need for now
|
// intentionally ignored, no need for now
|
||||||
// url: Url
|
// url: Url
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Forgejo can return blank strings for URLs. This handles that by deserializing
|
||||||
|
// that as `None`
|
||||||
|
fn none_if_blank_url<'de, D: serde::Deserializer<'de>>(deserializer: D) -> Result<Option<Url>, D::Error> {
|
||||||
|
use serde::de::{Error, Unexpected, Visitor};
|
||||||
|
use std::fmt;
|
||||||
|
|
||||||
|
struct EmptyUrlVisitor;
|
||||||
|
|
||||||
|
impl<'de> Visitor<'de> for EmptyUrlVisitor
|
||||||
|
{
|
||||||
|
type Value = Option<Url>;
|
||||||
|
|
||||||
|
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
formatter.write_str("option")
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_unit<E>(self) -> Result<Self::Value, E>
|
||||||
|
where
|
||||||
|
E: Error,
|
||||||
|
{
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_none<E>(self) -> Result<Self::Value, E>
|
||||||
|
where
|
||||||
|
E: Error,
|
||||||
|
{
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
|
||||||
|
where
|
||||||
|
E: Error,
|
||||||
|
{
|
||||||
|
if s.is_empty() {
|
||||||
|
return Ok(None);
|
||||||
|
}
|
||||||
|
Url::parse(s).map_err(|err| {
|
||||||
|
let err_s = format!("{}", err);
|
||||||
|
Error::invalid_value(Unexpected::Str(s), &err_s.as_str())
|
||||||
|
}).map(Some)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
deserializer.deserialize_str(EmptyUrlVisitor)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
30
src/organization.rs
Normal file
30
src/organization.rs
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
use std::collections::BTreeMap;
|
||||||
|
use crate::*;
|
||||||
|
|
||||||
|
#[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>,
|
||||||
|
}
|
|
@ -3,12 +3,12 @@ use super::*;
|
||||||
/// Repository operations.
|
/// Repository operations.
|
||||||
impl Forgejo {
|
impl Forgejo {
|
||||||
/// Gets info about the specified repository.
|
/// Gets info about the specified repository.
|
||||||
pub async fn get_repo(&self, user: &str, repo: &str) -> Result<Option<Repo>, ForgejoError> {
|
pub async fn get_repo(&self, user: &str, repo: &str) -> Result<Option<Repository>, ForgejoError> {
|
||||||
self.get_opt(&format!("repos/{user}/{repo}/")).await
|
self.get_opt(&format!("repos/{user}/{repo}/")).await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a repository.
|
/// Creates a repository.
|
||||||
pub async fn create_repo(&self, repo: CreateRepoOption) -> Result<Repo, ForgejoError> {
|
pub async fn create_repo(&self, repo: CreateRepoOption) -> Result<Repository, ForgejoError> {
|
||||||
self.post("user/repos", &repo).await
|
self.post("user/repos", &repo).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,17 +216,68 @@ impl Forgejo {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(serde::Deserialize, Debug, PartialEq)]
|
#[derive(serde::Deserialize, Debug, PartialEq)]
|
||||||
pub struct Repo {
|
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,
|
pub clone_url: Url,
|
||||||
#[serde(with = "time::serde::rfc3339")]
|
#[serde(with = "time::serde::rfc3339")]
|
||||||
pub created_at: time::OffsetDateTime,
|
pub created_at: time::OffsetDateTime,
|
||||||
|
pub default_allow_maintainer_edit: bool,
|
||||||
pub default_branch: String,
|
pub default_branch: String,
|
||||||
|
pub default_delete_branch_after_merge: bool,
|
||||||
|
pub default_merge_style: String,
|
||||||
pub description: String,
|
pub description: String,
|
||||||
|
pub empty: bool,
|
||||||
|
pub external_tracker: Option<ExternalTracker>,
|
||||||
|
pub external_wiki: Option<ExternalWiki>,
|
||||||
pub fork: bool,
|
pub fork: bool,
|
||||||
pub forks_count: u64,
|
pub forks_count: u64,
|
||||||
pub full_name: String,
|
pub full_name: String,
|
||||||
|
pub has_actions: bool,
|
||||||
|
pub has_issues: bool,
|
||||||
|
pub has_packages: bool,
|
||||||
|
pub has_projects: bool,
|
||||||
|
pub has_pull_request: 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_issue_count: u64,
|
||||||
|
pub open_pr_counter: u64,
|
||||||
|
pub original_url: Url,
|
||||||
pub owner: User,
|
pub owner: User,
|
||||||
|
pub permissions: Permission,
|
||||||
|
pub private: bool,
|
||||||
|
pub release_counter: u64,
|
||||||
|
pub repo_transfer: Option<RepoTransfer>,
|
||||||
|
pub size: u64,
|
||||||
|
pub ssh_url: Url,
|
||||||
|
pub starts_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)]
|
#[derive(serde::Deserialize, Debug, PartialEq)]
|
||||||
|
@ -324,7 +375,7 @@ pub struct PrBranchInfo {
|
||||||
pub label: String,
|
pub label: String,
|
||||||
#[serde(rename = "ref")]
|
#[serde(rename = "ref")]
|
||||||
pub _ref: String,
|
pub _ref: String,
|
||||||
pub repo: Repo,
|
pub repo: Repository,
|
||||||
pub repo_id: u64,
|
pub repo_id: u64,
|
||||||
pub sha: String,
|
pub sha: String,
|
||||||
}
|
}
|
||||||
|
@ -571,3 +622,43 @@ pub struct CommitMeta {
|
||||||
pub url: Url,
|
pub url: Url,
|
||||||
pub sha: String,
|
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>,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue