Skip to main content

wp_goji_patch/
boards.rs

1//! Interfaces for accessing and managing boards
2
3// Third party
4use url::form_urlencoded;
5
6// Ours
7use crate::{Jira, Result, SearchOptions};
8
9#[derive(Debug)]
10pub struct Boards {
11    jira: Jira,
12}
13
14#[derive(Deserialize, Debug, Clone)]
15pub struct Board {
16    #[serde(rename = "self")]
17    pub self_link: String,
18    pub id: u64,
19    pub name: String,
20    #[serde(rename = "type")]
21    pub type_name: String,
22}
23
24#[derive(Deserialize, Debug)]
25pub struct BoardResults {
26    #[serde(rename = "maxResults")]
27    pub max_results: u64,
28    #[serde(rename = "startAt")]
29    pub start_at: u64,
30    #[serde(rename = "isLast")]
31    pub is_last: bool,
32    pub values: Vec<Board>,
33}
34
35impl Boards {
36    pub fn new(jira: &Jira) -> Boards {
37        Boards { jira: jira.clone() }
38    }
39
40    /// Get a single board
41    ///
42    /// See this [jira docs](https://docs.atlassian.com/jira-software/REST/7.0.4/#agile/1.0/board-getBoard)
43    /// for more information
44    pub fn get<I>(&self, id: I) -> Result<Board>
45    where
46        I: Into<String>,
47    {
48        self.jira.get("agile", &format!("/board/{}", id.into()))
49    }
50
51    /// Returns a single page of board results
52    ///
53    /// See the [jira docs](https://docs.atlassian.com/jira-software/REST/latest/#agile/1.0/board-getAllBoards)
54    /// for more information
55    pub fn list(&self, options: &SearchOptions) -> Result<BoardResults> {
56        let mut path = vec!["/board".to_owned()];
57        let query_options = options.serialize().unwrap_or_default();
58        let query = form_urlencoded::Serializer::new(query_options).finish();
59
60        path.push(query);
61
62        self.jira
63            .get::<BoardResults>("agile", path.join("?").as_ref())
64    }
65
66    /// Returns a type which may be used to iterate over consecutive pages of results
67    ///
68    /// See the [jira docs](https://docs.atlassian.com/jira-software/REST/latest/#agile/1.0/board-getAllBoards)
69    /// for more information
70    pub fn iter<'a>(&self, options: &'a SearchOptions) -> Result<BoardsIter<'a>> {
71        BoardsIter::new(options, &self.jira)
72    }
73}
74
75/// Provides an iterator over multiple pages of search results
76#[derive(Debug)]
77pub struct BoardsIter<'a> {
78    jira: Jira,
79    results: BoardResults,
80    search_options: &'a SearchOptions,
81}
82
83impl<'a> BoardsIter<'a> {
84    fn new(options: &'a SearchOptions, jira: &Jira) -> Result<Self> {
85        let results = jira.boards().list(options)?;
86        Ok(BoardsIter {
87            jira: jira.clone(),
88            results,
89            search_options: options,
90        })
91    }
92
93    fn more(&self) -> bool {
94        !self.results.is_last
95    }
96}
97
98impl<'a> Iterator for BoardsIter<'a> {
99    type Item = Board;
100    fn next(&mut self) -> Option<Board> {
101        self.results.values.pop().or_else(|| {
102            if self.more() {
103                match self.jira.boards().list(
104                    &self
105                        .search_options
106                        .as_builder()
107                        .max_results(self.results.max_results)
108                        .start_at(self.results.start_at + self.results.max_results)
109                        .build(),
110                ) {
111                    Ok(new_results) => {
112                        self.results = new_results;
113                        self.results.values.pop()
114                    }
115                    _ => None,
116                }
117            } else {
118                None
119            }
120        })
121    }
122}