455 lines
11 KiB
Rust
455 lines
11 KiB
Rust
use gotcha_gitea::{
|
|
Client, DEFAULT_PAGE_SIZE as PAGE_SIZE, IssueQuery, RepositoryId, api_date, diff, models,
|
|
};
|
|
|
|
use crate::{
|
|
domain::{
|
|
HistoryCommit, HomeData, IssueDetails, IssueDraft, IssueEditorData, IssueFilter,
|
|
MilestoneDetails, MilestoneDraft, Page, PullDetails, RepositoryData, Server,
|
|
},
|
|
presentation::compact_date,
|
|
};
|
|
|
|
pub async fn load_repositories(server: &Server, page: i32) -> Result<Page<RepositoryData>, String> {
|
|
let page = client(server)?
|
|
.owned_repositories_page(page, PAGE_SIZE)
|
|
.await
|
|
.map_err(message)?;
|
|
Ok(Page {
|
|
has_more: page.has_more,
|
|
items: page
|
|
.items
|
|
.into_iter()
|
|
.filter_map(|repository| {
|
|
Some(RepositoryData {
|
|
owner: repository.owner?.login?,
|
|
name: repository.name?,
|
|
description: repository
|
|
.description
|
|
.filter(|text| !text.is_empty())
|
|
.unwrap_or_else(|| "No description".into()),
|
|
language: repository
|
|
.language
|
|
.filter(|text| !text.is_empty())
|
|
.unwrap_or_else(|| "Unknown language".into()),
|
|
open_issues: repository.open_issues_count.unwrap_or_default(),
|
|
updated: compact_date(repository.updated_at.as_deref()),
|
|
default_branch: repository.default_branch.unwrap_or_else(|| "main".into()),
|
|
})
|
|
})
|
|
.collect(),
|
|
})
|
|
}
|
|
|
|
pub async fn load_issues(
|
|
server: &Server,
|
|
owner: &str,
|
|
repository: &str,
|
|
status: &str,
|
|
filter: &IssueFilter,
|
|
page: i32,
|
|
) -> Result<Page<models::Issue>, String> {
|
|
client(server)?
|
|
.issues(
|
|
&scope(owner, repository)?,
|
|
&IssueQuery {
|
|
state: status.into(),
|
|
labels: (!filter.labels.is_empty())
|
|
.then(|| filter.labels.iter().cloned().collect::<Vec<_>>().join(",")),
|
|
milestones: (!filter.milestone.is_empty()).then(|| filter.milestone.clone()),
|
|
keyword: (!filter.search_text.is_empty()).then(|| filter.search_text.clone()),
|
|
page,
|
|
limit: PAGE_SIZE,
|
|
..Default::default()
|
|
},
|
|
)
|
|
.await
|
|
.map_err(message)
|
|
}
|
|
|
|
pub async fn load_milestones_page(
|
|
server: &Server,
|
|
owner: &str,
|
|
repository: &str,
|
|
page: i32,
|
|
) -> Result<Page<models::Milestone>, String> {
|
|
client(server)?
|
|
.milestones_page(&scope(owner, repository)?, page, PAGE_SIZE)
|
|
.await
|
|
.map_err(message)
|
|
}
|
|
|
|
pub async fn load_labels(
|
|
server: &Server,
|
|
owner: &str,
|
|
repository: &str,
|
|
) -> Result<Vec<models::Label>, String> {
|
|
client(server)?
|
|
.labels(&scope(owner, repository)?)
|
|
.await
|
|
.map_err(message)
|
|
}
|
|
|
|
pub async fn load_milestones(
|
|
server: &Server,
|
|
owner: &str,
|
|
repository: &str,
|
|
) -> Result<Vec<models::Milestone>, String> {
|
|
client(server)?
|
|
.milestones(&scope(owner, repository)?)
|
|
.await
|
|
.map_err(message)
|
|
}
|
|
|
|
pub async fn load_milestone(
|
|
server: &Server,
|
|
owner: &str,
|
|
repository: &str,
|
|
id: i64,
|
|
page: i32,
|
|
) -> Result<MilestoneDetails, String> {
|
|
client(server)?
|
|
.milestone_details(&scope(owner, repository)?, id, page)
|
|
.await
|
|
.map_err(message)
|
|
}
|
|
|
|
pub async fn load_milestone_editor(
|
|
server: &Server,
|
|
owner: &str,
|
|
repository: &str,
|
|
id: i64,
|
|
) -> Result<models::Milestone, String> {
|
|
client(server)?
|
|
.milestone(&scope(owner, repository)?, id)
|
|
.await
|
|
.map_err(message)
|
|
}
|
|
|
|
pub async fn save_milestone(
|
|
server: &Server,
|
|
owner: &str,
|
|
repository: &str,
|
|
id: Option<i64>,
|
|
draft: MilestoneDraft,
|
|
) -> Result<models::Milestone, String> {
|
|
client(server)?
|
|
.save_milestone(
|
|
&scope(owner, repository)?,
|
|
id,
|
|
gotcha_gitea::MilestoneDraft {
|
|
title: draft.title,
|
|
description: draft.description,
|
|
due_on: draft.due_date.map(api_date),
|
|
state: if draft.closed { "closed" } else { "open" }.into(),
|
|
},
|
|
)
|
|
.await
|
|
.map_err(message)
|
|
}
|
|
|
|
pub async fn set_milestone_closed(
|
|
server: &Server,
|
|
owner: &str,
|
|
repository: &str,
|
|
id: i64,
|
|
closed: bool,
|
|
) -> Result<(), String> {
|
|
client(server)?
|
|
.set_milestone_closed(&scope(owner, repository)?, id, closed)
|
|
.await
|
|
.map(|_| ())
|
|
.map_err(message)
|
|
}
|
|
|
|
pub async fn delete_milestone(
|
|
server: &Server,
|
|
owner: &str,
|
|
repository: &str,
|
|
id: i64,
|
|
) -> Result<(), String> {
|
|
client(server)?
|
|
.delete_milestone(&scope(owner, repository)?, &id.to_string())
|
|
.await
|
|
.map_err(message)
|
|
}
|
|
|
|
pub async fn load_pulls(
|
|
server: &Server,
|
|
status: &str,
|
|
milestone: &str,
|
|
search_text: &str,
|
|
page: i32,
|
|
) -> Result<Page<models::Issue>, String> {
|
|
client(server)?
|
|
.search_pulls(
|
|
status,
|
|
(!milestone.is_empty()).then_some(milestone),
|
|
(!search_text.is_empty()).then_some(search_text),
|
|
page,
|
|
PAGE_SIZE,
|
|
)
|
|
.await
|
|
.map_err(message)
|
|
}
|
|
|
|
pub async fn load_pull_milestones(server: &Server) -> Result<Vec<String>, String> {
|
|
client(server)?.pull_milestones().await.map_err(message)
|
|
}
|
|
|
|
pub async fn load_branches(
|
|
server: &Server,
|
|
owner: &str,
|
|
repository: &str,
|
|
default_branch: &str,
|
|
) -> Result<Vec<String>, String> {
|
|
client(server)?
|
|
.branches(&scope(owner, repository)?, default_branch)
|
|
.await
|
|
.map_err(message)
|
|
}
|
|
|
|
pub async fn load_repository_contents(
|
|
server: &Server,
|
|
owner: &str,
|
|
repository: &str,
|
|
path: &str,
|
|
) -> Result<Vec<models::ContentsResponse>, String> {
|
|
client(server)?
|
|
.repository_contents(&scope(owner, repository)?, path)
|
|
.await
|
|
.map_err(message)
|
|
}
|
|
|
|
pub async fn load_repository_file(
|
|
server: &Server,
|
|
owner: &str,
|
|
repository: &str,
|
|
path: &str,
|
|
) -> Result<Vec<u8>, String> {
|
|
client(server)?
|
|
.repository_file(&scope(owner, repository)?, path)
|
|
.await
|
|
.map_err(message)
|
|
}
|
|
|
|
pub async fn load_branch_commits(
|
|
server: &Server,
|
|
owner: &str,
|
|
repository: &str,
|
|
branch: &str,
|
|
path: Option<&str>,
|
|
pages: u32,
|
|
) -> Result<Page<HistoryCommit>, String> {
|
|
client(server)?
|
|
.branch_history(&scope(owner, repository)?, branch, path, pages)
|
|
.await
|
|
.map_err(message)
|
|
}
|
|
|
|
pub async fn load_all_commits(
|
|
server: &Server,
|
|
owner: &str,
|
|
repository: &str,
|
|
branches: &[String],
|
|
path: Option<&str>,
|
|
pages: u32,
|
|
) -> Result<Page<HistoryCommit>, String> {
|
|
client(server)?
|
|
.all_history(&scope(owner, repository)?, branches, path, pages)
|
|
.await
|
|
.map_err(message)
|
|
}
|
|
|
|
pub async fn load_issue(
|
|
server: &Server,
|
|
owner: &str,
|
|
repository: &str,
|
|
number: i64,
|
|
_page: i32,
|
|
) -> Result<IssueDetails, String> {
|
|
client(server)?
|
|
.issue_details(&scope(owner, repository)?, number)
|
|
.await
|
|
.map_err(message)
|
|
}
|
|
|
|
pub async fn save_issue_comment(
|
|
server: &Server,
|
|
owner: &str,
|
|
repository: &str,
|
|
number: i64,
|
|
comment_id: Option<i64>,
|
|
body: String,
|
|
) -> Result<(), String> {
|
|
client(server)?
|
|
.save_issue_comment(&scope(owner, repository)?, number, comment_id, body)
|
|
.await
|
|
.map(|_| ())
|
|
.map_err(message)
|
|
}
|
|
|
|
pub async fn load_issue_editor(
|
|
server: &Server,
|
|
owner: &str,
|
|
repository: &str,
|
|
number: Option<i64>,
|
|
) -> Result<IssueEditorData, String> {
|
|
client(server)?
|
|
.issue_editor(&scope(owner, repository)?, number)
|
|
.await
|
|
.map_err(message)
|
|
}
|
|
|
|
pub async fn create_issue(
|
|
server: &Server,
|
|
owner: &str,
|
|
repository: &str,
|
|
draft: IssueDraft,
|
|
) -> Result<models::Issue, String> {
|
|
client(server)?
|
|
.create_issue_draft(&scope(owner, repository)?, shared_issue_draft(draft))
|
|
.await
|
|
.map_err(message)
|
|
}
|
|
|
|
pub async fn edit_issue(
|
|
server: &Server,
|
|
owner: &str,
|
|
repository: &str,
|
|
number: i64,
|
|
draft: IssueDraft,
|
|
) -> Result<models::Issue, String> {
|
|
client(server)?
|
|
.edit_issue_draft(
|
|
&scope(owner, repository)?,
|
|
number,
|
|
shared_issue_draft(draft),
|
|
)
|
|
.await
|
|
.map_err(message)
|
|
}
|
|
|
|
pub async fn set_issue_closed(
|
|
server: &Server,
|
|
owner: &str,
|
|
repository: &str,
|
|
number: i64,
|
|
closed: bool,
|
|
) -> Result<(), String> {
|
|
client(server)?
|
|
.set_issue_state(
|
|
&scope(owner, repository)?,
|
|
&[number],
|
|
if closed { "closed" } else { "open" },
|
|
)
|
|
.await
|
|
.map(|_| ())
|
|
.map_err(message)
|
|
}
|
|
|
|
pub async fn delete_issue(
|
|
server: &Server,
|
|
owner: &str,
|
|
repository: &str,
|
|
number: i64,
|
|
) -> Result<(), String> {
|
|
client(server)?
|
|
.delete_issue(&scope(owner, repository)?, number)
|
|
.await
|
|
.map_err(message)
|
|
}
|
|
|
|
pub async fn load_pull(
|
|
server: &Server,
|
|
owner: &str,
|
|
repository: &str,
|
|
number: i64,
|
|
page: i32,
|
|
) -> Result<PullDetails, String> {
|
|
client(server)?
|
|
.pull_details(&scope(owner, repository)?, number, page)
|
|
.await
|
|
.map_err(message)
|
|
}
|
|
|
|
pub async fn load_commit(
|
|
server: &Server,
|
|
owner: &str,
|
|
repository: &str,
|
|
sha: &str,
|
|
) -> Result<models::Commit, String> {
|
|
client(server)?
|
|
.commit(&scope(owner, repository)?, sha)
|
|
.await
|
|
.map_err(message)
|
|
}
|
|
|
|
pub async fn load_commit_diff(
|
|
server: &Server,
|
|
owner: &str,
|
|
repository: &str,
|
|
sha: &str,
|
|
path: &str,
|
|
) -> Result<diff::Parsed, String> {
|
|
let client = client(server)?;
|
|
let diff = client
|
|
.commit_diff(&scope(owner, repository)?, sha)
|
|
.await
|
|
.map_err(message)?;
|
|
Ok(diff::parse_file(&diff, path))
|
|
}
|
|
|
|
pub async fn load_pull_diff(
|
|
server: &Server,
|
|
owner: &str,
|
|
repository: &str,
|
|
number: i64,
|
|
path: &str,
|
|
) -> Result<diff::Parsed, String> {
|
|
let client = client(server)?;
|
|
let diff = client
|
|
.pull_diff(&scope(owner, repository)?, number)
|
|
.await
|
|
.map_err(message)?;
|
|
Ok(diff::parse_file(&diff, path))
|
|
}
|
|
|
|
pub async fn load_home(
|
|
server: &Server,
|
|
page: i32,
|
|
filter: gotcha_gitea::ActivityFilter,
|
|
) -> Result<HomeData, String> {
|
|
client(server)?.home(page, filter).await.map_err(message)
|
|
}
|
|
|
|
pub async fn load_activities(server: &Server, page: i32) -> Result<Page<models::Activity>, String> {
|
|
client(server)?
|
|
.activities(page, gotcha_gitea::ActivityFilter::All)
|
|
.await
|
|
.map_err(message)
|
|
}
|
|
|
|
fn client(server: &Server) -> Result<Client, String> {
|
|
Client::with_provider(&server.url, Some(&server.token), server.provider).map_err(message)
|
|
}
|
|
|
|
fn scope(owner: &str, repository: &str) -> Result<RepositoryId, String> {
|
|
RepositoryId::new(owner, repository).map_err(message)
|
|
}
|
|
|
|
fn shared_issue_draft(draft: IssueDraft) -> gotcha_gitea::IssueDraft {
|
|
gotcha_gitea::IssueDraft {
|
|
title: draft.title,
|
|
body: draft.body,
|
|
label_ids: draft.label_ids,
|
|
milestone_id: draft.milestone_id,
|
|
due_date: draft.due_date.map(api_date),
|
|
closed: draft.closed,
|
|
}
|
|
}
|
|
|
|
fn message(error: impl std::fmt::Display) -> String {
|
|
error.to_string()
|
|
}
|