rosu_render/request/
render.rs1use std::future::IntoFuture;
2
3use crate::{
4 model::{RenderAdded, RenderOptions, RenderSkinOption},
5 routing::Route,
6 util::multipart::Form,
7 ClientError, OrdrClient,
8};
9
10use super::{OrdrFuture, Request};
11
12enum ReplaySource<'a> {
13 File(&'a [u8]),
14 Url(&'a str),
15}
16
17#[must_use]
21pub struct CommissionRender<'a> {
22 ordr: &'a OrdrClient,
23 replay_source: ReplaySource<'a>,
24 username: &'a str,
25 skin: &'a RenderSkinOption<'a>,
26 options: Option<&'a RenderOptions>,
27}
28
29impl<'a> CommissionRender<'a> {
30 pub(crate) const fn with_file(
31 ordr: &'a OrdrClient,
32 replay_file: &'a [u8],
33 username: &'a str,
34 skin: &'a RenderSkinOption<'a>,
35 ) -> Self {
36 Self {
37 ordr,
38 replay_source: ReplaySource::File(replay_file),
39 username,
40 skin,
41 options: None,
42 }
43 }
44
45 pub(crate) const fn with_url(
46 ordr: &'a OrdrClient,
47 replay_url: &'a str,
48 username: &'a str,
49 skin: &'a RenderSkinOption<'a>,
50 ) -> Self {
51 Self {
52 ordr,
53 replay_source: ReplaySource::Url(replay_url),
54 username,
55 skin,
56 options: None,
57 }
58 }
59
60 pub fn options(mut self, options: &'a RenderOptions) -> Self {
62 self.options = Some(options);
63
64 self
65 }
66}
67
68impl IntoFuture for &mut CommissionRender<'_> {
69 type Output = Result<RenderAdded, ClientError>;
70 type IntoFuture = OrdrFuture<RenderAdded>;
71
72 fn into_future(self) -> Self::IntoFuture {
73 let missing_resolution = self.options.is_none();
74
75 let mut form = self.options.map_or_else(Form::new, Form::serialize);
76
77 if missing_resolution {
78 form.push_text("resolution", RenderOptions::DEFAULT_RESOLUTION.as_str());
79 }
80
81 match self.replay_source {
82 ReplaySource::File(bytes) => form.push_replay("replayFile", bytes),
83 ReplaySource::Url(url) => form.push_text("replayURL", url),
84 };
85
86 form.push_text("username", self.username);
87
88 match self.skin {
89 RenderSkinOption::Official { name } => {
90 form.push_text("skin", name.as_ref())
91 .push_text("customSkin", "false");
92 }
93 RenderSkinOption::Custom { id } => {
94 form.push_text("skin", id.to_string())
95 .push_text("customSkin", "true");
96 }
97 }
98
99 if let Some(verification) = self.ordr.verification() {
100 form.push_text("verificationKey", verification.as_str());
101 }
102
103 self.ordr
104 .request(Request::builder(Route::Render).form(form).build())
105 }
106}
107
108impl IntoFuture for CommissionRender<'_> {
109 type Output = Result<RenderAdded, ClientError>;
110 type IntoFuture = OrdrFuture<RenderAdded>;
111
112 fn into_future(mut self) -> Self::IntoFuture {
113 (&mut self).into_future()
114 }
115}