misc: initial code
This commit is contained in:
11
crates/codetaker-gitea/Cargo.toml
Normal file
11
crates/codetaker-gitea/Cargo.toml
Normal file
@@ -0,0 +1,11 @@
|
||||
[package]
|
||||
name = "codetaker-gitea"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
chrono.workspace = true
|
||||
reqwest.workspace = true
|
||||
serde.workspace = true
|
||||
serde_json.workspace = true
|
||||
serde_urlencoded.workspace = true
|
||||
30383
crates/codetaker-gitea/schema.json
Normal file
30383
crates/codetaker-gitea/schema.json
Normal file
File diff suppressed because it is too large
Load Diff
628
crates/codetaker-gitea/src/lib.rs
Normal file
628
crates/codetaker-gitea/src/lib.rs
Normal file
@@ -0,0 +1,628 @@
|
||||
use chrono::{DateTime, Utc};
|
||||
use reqwest::StatusCode;
|
||||
use serde::de::DeserializeOwned;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
pub type GiteaResult<T> = Result<T, GiteaError>;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum GiteaError {
|
||||
Http(reqwest::Error),
|
||||
Api { status: StatusCode, body: String },
|
||||
}
|
||||
|
||||
impl std::fmt::Display for GiteaError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::Http(err) => write!(f, "http error: {err}"),
|
||||
Self::Api { status, body } => write!(f, "gitea api error {status}: {body}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for GiteaError {}
|
||||
|
||||
impl From<reqwest::Error> for GiteaError {
|
||||
fn from(value: reqwest::Error) -> Self {
|
||||
Self::Http(value)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct GiteaClient {
|
||||
http: reqwest::Client,
|
||||
api_base: String,
|
||||
token: Option<String>,
|
||||
}
|
||||
|
||||
impl GiteaClient {
|
||||
pub fn new(instance_base_url: impl Into<String>) -> Self {
|
||||
let base = instance_base_url.into().trim_end_matches('/').to_owned();
|
||||
let api_base = if base.ends_with("/api/v1") {
|
||||
base
|
||||
} else {
|
||||
format!("{base}/api/v1")
|
||||
};
|
||||
Self {
|
||||
http: reqwest::Client::new(),
|
||||
api_base,
|
||||
token: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_token(mut self, token: impl Into<String>) -> Self {
|
||||
self.token = Some(token.into());
|
||||
self
|
||||
}
|
||||
|
||||
pub fn with_http_client(mut self, http: reqwest::Client) -> Self {
|
||||
self.http = http;
|
||||
self
|
||||
}
|
||||
|
||||
pub async fn list_pull_requests(
|
||||
&self,
|
||||
owner: &str,
|
||||
repo: &str,
|
||||
query: &ListPullRequestsQuery,
|
||||
) -> GiteaResult<Vec<PullRequest>> {
|
||||
let path = format!("/repos/{owner}/{repo}/pulls");
|
||||
self.get_json(&path, query).await
|
||||
}
|
||||
|
||||
pub async fn get_pull_request(
|
||||
&self,
|
||||
owner: &str,
|
||||
repo: &str,
|
||||
index: i64,
|
||||
) -> GiteaResult<PullRequest> {
|
||||
let path = format!("/repos/{owner}/{repo}/pulls/{index}");
|
||||
self.get_json_no_query(&path).await
|
||||
}
|
||||
|
||||
pub async fn edit_pull_request(
|
||||
&self,
|
||||
owner: &str,
|
||||
repo: &str,
|
||||
index: i64,
|
||||
body: &EditPullRequestOption,
|
||||
) -> GiteaResult<PullRequest> {
|
||||
let path = format!("/repos/{owner}/{repo}/pulls/{index}");
|
||||
self.send_json(self.request(reqwest::Method::PATCH, &path).json(body))
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn list_pull_request_commits(
|
||||
&self,
|
||||
owner: &str,
|
||||
repo: &str,
|
||||
index: i64,
|
||||
query: &ListPullRequestCommitsQuery,
|
||||
) -> GiteaResult<Vec<Commit>> {
|
||||
let path = format!("/repos/{owner}/{repo}/pulls/{index}/commits");
|
||||
self.get_json(&path, query).await
|
||||
}
|
||||
|
||||
pub async fn list_pull_request_files(
|
||||
&self,
|
||||
owner: &str,
|
||||
repo: &str,
|
||||
index: i64,
|
||||
query: &ListPullRequestFilesQuery,
|
||||
) -> GiteaResult<Vec<ChangedFile>> {
|
||||
let path = format!("/repos/{owner}/{repo}/pulls/{index}/files");
|
||||
self.get_json(&path, query).await
|
||||
}
|
||||
|
||||
pub async fn list_pull_reviews(
|
||||
&self,
|
||||
owner: &str,
|
||||
repo: &str,
|
||||
index: i64,
|
||||
query: &ListPullReviewsQuery,
|
||||
) -> GiteaResult<Vec<PullReview>> {
|
||||
let path = format!("/repos/{owner}/{repo}/pulls/{index}/reviews");
|
||||
self.get_json(&path, query).await
|
||||
}
|
||||
|
||||
pub async fn create_pull_review(
|
||||
&self,
|
||||
owner: &str,
|
||||
repo: &str,
|
||||
index: i64,
|
||||
body: &CreatePullReviewOptions,
|
||||
) -> GiteaResult<PullReview> {
|
||||
let path = format!("/repos/{owner}/{repo}/pulls/{index}/reviews");
|
||||
self.send_json(self.request(reqwest::Method::POST, &path).json(body))
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn get_pull_review(
|
||||
&self,
|
||||
owner: &str,
|
||||
repo: &str,
|
||||
index: i64,
|
||||
review_id: i64,
|
||||
) -> GiteaResult<PullReview> {
|
||||
let path = format!("/repos/{owner}/{repo}/pulls/{index}/reviews/{review_id}");
|
||||
self.get_json_no_query(&path).await
|
||||
}
|
||||
|
||||
pub async fn submit_pull_review(
|
||||
&self,
|
||||
owner: &str,
|
||||
repo: &str,
|
||||
index: i64,
|
||||
review_id: i64,
|
||||
body: &SubmitPullReviewOptions,
|
||||
) -> GiteaResult<PullReview> {
|
||||
let path = format!("/repos/{owner}/{repo}/pulls/{index}/reviews/{review_id}");
|
||||
self.send_json(self.request(reqwest::Method::POST, &path).json(body))
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn delete_pull_review(
|
||||
&self,
|
||||
owner: &str,
|
||||
repo: &str,
|
||||
index: i64,
|
||||
review_id: i64,
|
||||
) -> GiteaResult<()> {
|
||||
let path = format!("/repos/{owner}/{repo}/pulls/{index}/reviews/{review_id}");
|
||||
self.send_empty(self.request(reqwest::Method::DELETE, &path))
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn dismiss_pull_review(
|
||||
&self,
|
||||
owner: &str,
|
||||
repo: &str,
|
||||
index: i64,
|
||||
review_id: i64,
|
||||
body: &DismissPullReviewOptions,
|
||||
) -> GiteaResult<PullReview> {
|
||||
let path = format!("/repos/{owner}/{repo}/pulls/{index}/reviews/{review_id}/dismissals");
|
||||
self.send_json(self.request(reqwest::Method::POST, &path).json(body))
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn undismiss_pull_review(
|
||||
&self,
|
||||
owner: &str,
|
||||
repo: &str,
|
||||
index: i64,
|
||||
review_id: i64,
|
||||
) -> GiteaResult<PullReview> {
|
||||
let path = format!("/repos/{owner}/{repo}/pulls/{index}/reviews/{review_id}/undismissals");
|
||||
self.send_json(self.request(reqwest::Method::POST, &path))
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn list_pull_review_comments(
|
||||
&self,
|
||||
owner: &str,
|
||||
repo: &str,
|
||||
index: i64,
|
||||
review_id: i64,
|
||||
) -> GiteaResult<Vec<PullReviewComment>> {
|
||||
let path = format!("/repos/{owner}/{repo}/pulls/{index}/reviews/{review_id}/comments");
|
||||
self.get_json_no_query(&path).await
|
||||
}
|
||||
|
||||
pub async fn list_issue_comments(
|
||||
&self,
|
||||
owner: &str,
|
||||
repo: &str,
|
||||
index: i64,
|
||||
query: &ListIssueCommentsQuery,
|
||||
) -> GiteaResult<Vec<Comment>> {
|
||||
let path = format!("/repos/{owner}/{repo}/issues/{index}/comments");
|
||||
self.get_json(&path, query).await
|
||||
}
|
||||
|
||||
pub async fn create_issue_comment(
|
||||
&self,
|
||||
owner: &str,
|
||||
repo: &str,
|
||||
index: i64,
|
||||
body: &CreateIssueCommentOption,
|
||||
) -> GiteaResult<Comment> {
|
||||
let path = format!("/repos/{owner}/{repo}/issues/{index}/comments");
|
||||
self.send_json(self.request(reqwest::Method::POST, &path).json(body))
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn get_issue_comment(
|
||||
&self,
|
||||
owner: &str,
|
||||
repo: &str,
|
||||
comment_id: i64,
|
||||
) -> GiteaResult<Comment> {
|
||||
let path = format!("/repos/{owner}/{repo}/issues/comments/{comment_id}");
|
||||
self.get_json_no_query(&path).await
|
||||
}
|
||||
|
||||
pub async fn edit_issue_comment(
|
||||
&self,
|
||||
owner: &str,
|
||||
repo: &str,
|
||||
comment_id: i64,
|
||||
body: &EditIssueCommentOption,
|
||||
) -> GiteaResult<Comment> {
|
||||
let path = format!("/repos/{owner}/{repo}/issues/comments/{comment_id}");
|
||||
self.send_json(self.request(reqwest::Method::PATCH, &path).json(body))
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn delete_issue_comment(
|
||||
&self,
|
||||
owner: &str,
|
||||
repo: &str,
|
||||
comment_id: i64,
|
||||
) -> GiteaResult<()> {
|
||||
let path = format!("/repos/{owner}/{repo}/issues/comments/{comment_id}");
|
||||
self.send_empty(self.request(reqwest::Method::DELETE, &path))
|
||||
.await
|
||||
}
|
||||
|
||||
fn request(&self, method: reqwest::Method, path: &str) -> reqwest::RequestBuilder {
|
||||
let mut req = self
|
||||
.http
|
||||
.request(method, format!("{}{}", self.api_base, path));
|
||||
if let Some(token) = &self.token {
|
||||
req = req.header("Authorization", format!("token {token}"));
|
||||
}
|
||||
req
|
||||
}
|
||||
|
||||
async fn get_json<Q, T>(&self, path: &str, query: &Q) -> GiteaResult<T>
|
||||
where
|
||||
Q: Serialize + ?Sized,
|
||||
T: DeserializeOwned,
|
||||
{
|
||||
let query_string = serde_urlencoded::to_string(query).map_err(|err| GiteaError::Api {
|
||||
status: StatusCode::BAD_REQUEST,
|
||||
body: format!("failed to encode query parameters: {err}"),
|
||||
})?;
|
||||
let full_path = if query_string.is_empty() {
|
||||
path.to_owned()
|
||||
} else {
|
||||
format!("{path}?{query_string}")
|
||||
};
|
||||
self.send_json(self.request(reqwest::Method::GET, &full_path))
|
||||
.await
|
||||
}
|
||||
|
||||
async fn get_json_no_query<T>(&self, path: &str) -> GiteaResult<T>
|
||||
where
|
||||
T: DeserializeOwned,
|
||||
{
|
||||
self.send_json(self.request(reqwest::Method::GET, path))
|
||||
.await
|
||||
}
|
||||
|
||||
async fn send_json<T>(&self, req: reqwest::RequestBuilder) -> GiteaResult<T>
|
||||
where
|
||||
T: DeserializeOwned,
|
||||
{
|
||||
let resp = req.send().await?;
|
||||
if resp.status().is_success() {
|
||||
return Ok(resp.json::<T>().await?);
|
||||
}
|
||||
|
||||
let status = resp.status();
|
||||
let body = resp.text().await.unwrap_or_default();
|
||||
Err(GiteaError::Api { status, body })
|
||||
}
|
||||
|
||||
async fn send_empty(&self, req: reqwest::RequestBuilder) -> GiteaResult<()> {
|
||||
let resp = req.send().await?;
|
||||
if resp.status().is_success() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let status = resp.status();
|
||||
let body = resp.text().await.unwrap_or_default();
|
||||
Err(GiteaError::Api { status, body })
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize)]
|
||||
pub struct ListPullRequestsQuery {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub base_branch: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub state: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub sort: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub milestone: Option<i64>,
|
||||
#[serde(skip_serializing_if = "Vec::is_empty")]
|
||||
pub labels: Vec<i64>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub poster: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub page: Option<i64>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub limit: Option<i64>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize)]
|
||||
pub struct ListPullRequestCommitsQuery {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub page: Option<i64>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub limit: Option<i64>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub verification: Option<bool>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub files: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize)]
|
||||
pub struct ListPullRequestFilesQuery {
|
||||
#[serde(rename = "skip-to", skip_serializing_if = "Option::is_none")]
|
||||
pub skip_to: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub whitespace: Option<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub page: Option<i64>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub limit: Option<i64>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize)]
|
||||
pub struct ListPullReviewsQuery {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub page: Option<i64>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub limit: Option<i64>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize)]
|
||||
pub struct ListIssueCommentsQuery {
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub since: Option<DateTime<Utc>>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub before: Option<DateTime<Utc>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct User {
|
||||
pub id: Option<i64>,
|
||||
pub login: Option<String>,
|
||||
pub full_name: Option<String>,
|
||||
pub email: Option<String>,
|
||||
pub avatar_url: Option<String>,
|
||||
pub html_url: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Label {
|
||||
pub id: Option<i64>,
|
||||
pub name: Option<String>,
|
||||
pub color: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Milestone {
|
||||
pub id: Option<i64>,
|
||||
pub title: Option<String>,
|
||||
pub state: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Team {
|
||||
pub id: Option<i64>,
|
||||
pub name: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct PrBranchInfo {
|
||||
#[serde(flatten)]
|
||||
pub extra: serde_json::Value,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct PullRequest {
|
||||
pub id: Option<i64>,
|
||||
pub number: Option<i64>,
|
||||
pub title: Option<String>,
|
||||
pub body: Option<String>,
|
||||
pub state: Option<String>,
|
||||
pub draft: Option<bool>,
|
||||
pub merged: Option<bool>,
|
||||
pub mergeable: Option<bool>,
|
||||
pub merge_base: Option<String>,
|
||||
pub merge_commit_sha: Option<String>,
|
||||
pub additions: Option<i64>,
|
||||
pub deletions: Option<i64>,
|
||||
pub changed_files: Option<i64>,
|
||||
pub comments: Option<i64>,
|
||||
pub review_comments: Option<i64>,
|
||||
pub html_url: Option<String>,
|
||||
pub diff_url: Option<String>,
|
||||
pub patch_url: Option<String>,
|
||||
pub url: Option<String>,
|
||||
pub created_at: Option<DateTime<Utc>>,
|
||||
pub updated_at: Option<DateTime<Utc>>,
|
||||
pub closed_at: Option<DateTime<Utc>>,
|
||||
pub merged_at: Option<DateTime<Utc>>,
|
||||
pub due_date: Option<DateTime<Utc>>,
|
||||
pub assignee: Option<User>,
|
||||
pub assignees: Option<Vec<User>>,
|
||||
pub user: Option<User>,
|
||||
pub merged_by: Option<User>,
|
||||
pub base: Option<PrBranchInfo>,
|
||||
pub head: Option<PrBranchInfo>,
|
||||
pub labels: Option<Vec<Label>>,
|
||||
pub milestone: Option<Milestone>,
|
||||
pub requested_reviewers: Option<Vec<User>>,
|
||||
pub requested_reviewers_teams: Option<Vec<Team>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct ChangedFile {
|
||||
pub additions: Option<i64>,
|
||||
pub changes: Option<i64>,
|
||||
pub contents_url: Option<String>,
|
||||
pub deletions: Option<i64>,
|
||||
pub filename: Option<String>,
|
||||
pub html_url: Option<String>,
|
||||
pub previous_filename: Option<String>,
|
||||
pub raw_url: Option<String>,
|
||||
pub status: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Commit {
|
||||
pub sha: Option<String>,
|
||||
pub html_url: Option<String>,
|
||||
pub url: Option<String>,
|
||||
pub author: Option<User>,
|
||||
pub committer: Option<User>,
|
||||
#[serde(default)]
|
||||
pub files: Vec<CommitAffectedFile>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct CommitAffectedFile {
|
||||
pub filename: Option<String>,
|
||||
pub status: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct PullReview {
|
||||
pub id: Option<i64>,
|
||||
pub body: Option<String>,
|
||||
pub state: Option<String>,
|
||||
pub commit_id: Option<String>,
|
||||
pub comments_count: Option<i64>,
|
||||
pub dismissed: Option<bool>,
|
||||
pub stale: Option<bool>,
|
||||
pub official: Option<bool>,
|
||||
pub html_url: Option<String>,
|
||||
pub pull_request_url: Option<String>,
|
||||
pub submitted_at: Option<DateTime<Utc>>,
|
||||
pub updated_at: Option<DateTime<Utc>>,
|
||||
pub user: Option<User>,
|
||||
pub team: Option<Team>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct PullReviewComment {
|
||||
pub id: Option<i64>,
|
||||
pub body: Option<String>,
|
||||
pub path: Option<String>,
|
||||
pub position: Option<u64>,
|
||||
pub original_position: Option<u64>,
|
||||
pub commit_id: Option<String>,
|
||||
pub original_commit_id: Option<String>,
|
||||
pub diff_hunk: Option<String>,
|
||||
pub pull_request_review_id: Option<i64>,
|
||||
pub pull_request_url: Option<String>,
|
||||
pub html_url: Option<String>,
|
||||
pub created_at: Option<DateTime<Utc>>,
|
||||
pub updated_at: Option<DateTime<Utc>>,
|
||||
pub user: Option<User>,
|
||||
pub resolver: Option<User>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Comment {
|
||||
pub id: Option<i64>,
|
||||
pub body: Option<String>,
|
||||
pub html_url: Option<String>,
|
||||
pub issue_url: Option<String>,
|
||||
pub pull_request_url: Option<String>,
|
||||
pub original_author: Option<String>,
|
||||
pub original_author_id: Option<i64>,
|
||||
pub created_at: Option<DateTime<Utc>>,
|
||||
pub updated_at: Option<DateTime<Utc>>,
|
||||
pub user: Option<User>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct ReviewState(pub String);
|
||||
|
||||
impl ReviewState {
|
||||
pub fn approve() -> Self {
|
||||
Self("APPROVE".to_owned())
|
||||
}
|
||||
|
||||
pub fn request_changes() -> Self {
|
||||
Self("REQUEST_CHANGES".to_owned())
|
||||
}
|
||||
|
||||
pub fn comment() -> Self {
|
||||
Self("COMMENT".to_owned())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct CreatePullReviewComment {
|
||||
pub body: Option<String>,
|
||||
pub path: Option<String>,
|
||||
pub new_position: Option<i64>,
|
||||
pub old_position: Option<i64>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct CreatePullReviewOptions {
|
||||
pub body: Option<String>,
|
||||
pub comments: Option<Vec<CreatePullReviewComment>>,
|
||||
pub commit_id: Option<String>,
|
||||
pub event: Option<ReviewState>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct SubmitPullReviewOptions {
|
||||
pub body: Option<String>,
|
||||
pub event: Option<ReviewState>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct DismissPullReviewOptions {
|
||||
pub message: Option<String>,
|
||||
pub priors: Option<bool>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct CreateIssueCommentOption {
|
||||
pub body: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct EditIssueCommentOption {
|
||||
pub body: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||
pub struct CreatePullRequestOption {
|
||||
pub title: Option<String>,
|
||||
pub body: Option<String>,
|
||||
pub head: Option<String>,
|
||||
pub base: Option<String>,
|
||||
pub assignee: Option<String>,
|
||||
pub assignees: Option<Vec<String>>,
|
||||
pub labels: Option<Vec<i64>>,
|
||||
pub milestone: Option<i64>,
|
||||
pub reviewers: Option<Vec<String>>,
|
||||
pub team_reviewers: Option<Vec<String>>,
|
||||
pub due_date: Option<DateTime<Utc>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
||||
pub struct EditPullRequestOption {
|
||||
pub title: Option<String>,
|
||||
pub body: Option<String>,
|
||||
pub base: Option<String>,
|
||||
pub state: Option<String>,
|
||||
pub assignee: Option<String>,
|
||||
pub assignees: Option<Vec<String>>,
|
||||
pub labels: Option<Vec<i64>>,
|
||||
pub milestone: Option<i64>,
|
||||
pub due_date: Option<DateTime<Utc>>,
|
||||
pub unset_due_date: Option<bool>,
|
||||
pub allow_maintainer_edit: Option<bool>,
|
||||
}
|
||||
Reference in New Issue
Block a user