rujira 0.4.1

This module provides an API for working with Jira
Documentation
//! This module contains functions for working with sprints.
//!
//! [docs](https://docs.atlassian.com/jira-software/REST/9.17.0/#agile/1.0/sprint)

use crate::agile::{self, REST_BASE};
use reqwest::Method;
use serde_json::Value;

use crate::{api::Rq, error::Error, Rujira};

/// Get sprint by ID
///
/// [docs](https://docs.atlassian.com/jira-software/REST/9.17.0/#agile/1.0/sprint-getSprint)
pub fn get(bot: Rujira, sprint_id: &str) -> Rq {
    Rq::new(bot)
        .uri(&format!("{}/sprint/{sprint_id}", REST_BASE))
        .method(Method::GET)
}

/// Get list of sprints for a board
///
/// [docs](https://docs.atlassian.com/jira-software/REST/9.17.0/#agile/1.0/board/%7BboardId%7D/sprint-getAllSprints)
pub fn list(
    bot: Rujira,
    board_id: &str,
    start_at: Option<u32>,
    max_results: Option<u32>,
    state: Option<&str>,
) -> Rq {
    Rq::new(bot)
        .uri(&format!("{}/board/{board_id}/sprint", REST_BASE))
        .method(Method::GET)
        .apply_if(start_at, |r, v| {
            r.add_params(vec![("startAt", v.to_string().as_str())])
        })
        .apply_if(max_results, |r, v| {
            r.add_params(vec![("maxResults", v.to_string().as_str())])
        })
        .apply_if(state, |r, v| r.add_params(vec![("state", v)]))
}

/// Set issues to a sprint
///
/// [docs](https://docs.atlassian.com/jira-software/REST/9.17.0/#agile/1.0/sprint-moveIssuesToSprint)
pub fn issue(bot: Rujira, sprint_id: &str, payload: serde_json::Value) -> Rq {
    Rq::new(bot)
        .uri(&format!("{}/sprint/{sprint_id}/issue", REST_BASE))
        .method(Method::POST)
        .add_payload("issues", payload)
}

/// Get sprint ID by name
pub async fn id_by_name(bot: Rujira, name: &str, board: &str) -> Result<i64, Error> {
    let board_id = agile::board::id_by_name(bot.clone(), board)
        .await?
        .to_string();
    let list = list(bot, board_id.as_str(), None, None, Some("active"))
        .apply()
        .await?;
    let sprints = list.data["values"].as_array().ok_or(Error::NoData)?;
    let matching_sprint = sprints
        .iter()
        .find(|item| item.get("name").and_then(Value::as_str) == Some(name))
        .ok_or(Error::SprintNotFound(name.to_string()))?;
    let id = matching_sprint["id"]
        .as_i64()
        .ok_or(Error::InvalidSprintId)?;
    Ok(id)
}