1use url::form_urlencoded;
5
6use 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 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 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 pub fn iter<'a>(&self, options: &'a SearchOptions) -> Result<BoardsIter<'a>> {
71 BoardsIter::new(options, &self.jira)
72 }
73}
74
75#[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}