1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
use std::future::IntoFuture;

use serde::Serialize;

use crate::{model::RenderList, routing::Route, ClientError, OrdrClient};

use super::{OrdrFuture, Request};

#[derive(Serialize)]
struct GetRenderListFields<'a> {
    #[serde(rename = "pageSize")]
    page_size: Option<u32>,
    page: Option<u32>,
    #[serde(rename = "ordrUsername")]
    ordr_username: Option<&'a str>,
    #[serde(rename = "replayUsername")]
    replay_username: Option<&'a str>,
    #[serde(rename = "renderID")]
    render_id: Option<u32>,
    #[serde(rename = "nobots")]
    no_bots: Option<bool>,
    link: Option<&'a str>,
    #[serde(rename = "beatmapsetid")]
    mapset_id: Option<u32>,
}

/// Get a [`RenderList`].
#[must_use]
pub struct GetRenderList<'a> {
    ordr: &'a OrdrClient,
    fields: GetRenderListFields<'a>,
}

impl<'a> GetRenderList<'a> {
    pub(crate) const fn new(ordr: &'a OrdrClient) -> Self {
        Self {
            ordr,
            fields: GetRenderListFields {
                page_size: None,
                page: None,
                ordr_username: None,
                replay_username: None,
                render_id: None,
                no_bots: None,
                link: None,
                mapset_id: None,
            },
        }
    }

    /// The number of renders the query will return you in the page. If not specified, 50 is the default.
    pub fn page_size(&mut self, page_size: u32) -> &mut Self {
        self.fields.page_size = Some(page_size);
        self.fields.page.get_or_insert(1);

        self
    }

    /// The page.
    pub fn page(&mut self, page: u32) -> &mut Self {
        self.fields.page = Some(page);

        self
    }

    /// Search by o!rdr username, can be used at the same time as [`replay_username`].
    ///
    /// [`replay_username`]: GetRenderList::replay_username
    pub fn ordr_username(&mut self, ordr_username: &'a str) -> &mut Self {
        self.fields.ordr_username = Some(ordr_username);

        self
    }

    /// Search by replay username, can be used at the same time as [`ordr_username`].
    ///
    /// [`ordr_username`]: GetRenderList::ordr_username
    pub fn replay_username(&mut self, replay_username: &'a str) -> &mut Self {
        self.fields.replay_username = Some(replay_username);

        self
    }

    /// The render ID of a render.
    pub fn render_id(&mut self, render_id: u32) -> &mut Self {
        self.fields.render_id = Some(render_id);

        self
    }

    /// Hide bots from the returned render query.
    pub fn no_bots(&mut self, no_bots: bool) -> &mut Self {
        self.fields.no_bots = Some(no_bots);

        self
    }

    /// The path of a shortlink (for example `pov8n` for `https://link.issou.best/pov8n`)
    pub fn link(&mut self, link: &'a str) -> &mut Self {
        self.fields.link = Some(link);

        self
    }

    /// Get renders with this specific beatmapset ID
    pub fn mapset_id(&mut self, mapset_id: u32) -> &mut Self {
        self.fields.mapset_id = Some(mapset_id);

        self
    }
}

impl IntoFuture for &mut GetRenderList<'_> {
    type Output = Result<RenderList, ClientError>;
    type IntoFuture = OrdrFuture<RenderList>;

    fn into_future(self) -> Self::IntoFuture {
        match Request::builder(Route::RenderList).query(&self.fields) {
            Ok(builder) => self.ordr.request(builder.build()),
            Err(err) => OrdrFuture::error(err),
        }
    }
}

impl IntoFuture for GetRenderList<'_> {
    type Output = Result<RenderList, ClientError>;
    type IntoFuture = OrdrFuture<RenderList>;

    fn into_future(mut self) -> Self::IntoFuture {
        (&mut self).into_future()
    }
}