development
rs 73 lines 2.31 KB
Raw
1 use {
2 crate::{cli::IssueCommand, context::Ctx, ui},
3 anyhow::{anyhow, Result},
4 sigit_si_api::State,
5 };
6
7 pub async fn run(ctx: &Ctx, command: IssueCommand) -> Result<()> {
8 ctx.require_token()?;
9
10 match command {
11 IssueCommand::List { repo, state, query } => list(ctx, repo, state, query).await,
12 IssueCommand::View { number, repo } => view(ctx, number, repo).await,
13 IssueCommand::Create { title, body, repo } => create(ctx, title, body, repo).await,
14 IssueCommand::Comment { number, body, repo } => comment(ctx, number, body, repo).await,
15 }
16 }
17
18 async fn list(ctx: &Ctx, repo: Option<String>, state: String, query: Option<String>) -> Result<()> {
19 let slug = ctx.resolve_repo(repo)?;
20 let state = parse_state(&state)?;
21 let issues = ctx
22 .client
23 .issues(&slug.to_string(), state, query.as_deref())
24 .await?;
25 ui::emit(ctx.json, &issues, |issues| ui::render::issues(issues))
26 }
27
28 async fn view(ctx: &Ctx, number: i64, repo: Option<String>) -> Result<()> {
29 let slug = ctx.resolve_repo(repo)?;
30 let issue = ctx.client.issue(&slug.to_string(), number).await?;
31 ui::emit(ctx.json, &issue, ui::render::issue_detail)
32 }
33
34 async fn create(
35 ctx: &Ctx,
36 title: String,
37 body: Option<String>,
38 repo: Option<String>,
39 ) -> Result<()> {
40 let slug = ctx.resolve_repo(repo)?;
41 let created = ctx
42 .client
43 .create_issue(&slug.to_string(), &title, body.as_deref())
44 .await?;
45
46 ui::emit(ctx.json, &created, |created| {
47 ui::success(format!("Opened issue #{}.", created.number));
48 println!(" {}", created.url);
49 })
50 }
51
52 async fn comment(ctx: &Ctx, number: i64, body: String, repo: Option<String>) -> Result<()> {
53 let slug = ctx.resolve_repo(repo)?;
54 let comment = ctx
55 .client
56 .add_comment(&slug.to_string(), number, &body)
57 .await?;
58 ui::emit(ctx.json, &comment, |comment| {
59 ui::success(format!("Commented on #{number}."));
60 println!(" {}", comment.url);
61 })
62 }
63
64 fn parse_state(input: &str) -> Result<State> {
65 match input.to_ascii_lowercase().as_str() {
66 "open" => Ok(State::Open),
67 "closed" => Ok(State::Closed),
68 "all" => Ok(State::All),
69 other => Err(anyhow!(
70 "Unknown state {other:?}. Expected one of: open, closed, all."
71 )),
72 }
73 }