1use super::meta::AudioStyleId;
4use crate::api::endpoints::PathPart;
5use chrono::{DateTime, Utc};
6use serde::{Deserialize, Serialize};
7#[cfg(feature = "backend")]
8use sqlx::postgres::PgRow;
9
10pub mod user {
12 use macros::make_path_parts;
13 use serde::{Deserialize, Serialize};
14
15 use super::AudioId;
16 use crate::api::endpoints::PathPart;
17
18 make_path_parts!(UserAudioListPath => "/v1/user/me/audio");
19
20 #[derive(Serialize, Deserialize, Debug)]
22 pub struct UserAudioListResponse {
23 pub audio_files: Vec<UserAudioResponse>,
25 }
26
27 make_path_parts!(UserAudioGetPath => "/v1/user/me/audio/{}" => AudioId);
28
29 #[derive(Serialize, Deserialize, Debug)]
31 pub struct UserAudioResponse {
32 pub metadata: UserAudio,
34 }
35
36 make_path_parts!(UserAudioCreatePath => "/v1/user/me/audio");
37
38 #[derive(Serialize, Deserialize, Debug)]
40 pub struct UserAudio {
41 pub id: AudioId,
43 }
45
46 make_path_parts!(UserAudioUploadPath => "/v1/user/me/audio/{}/raw" => AudioId);
47
48 #[derive(Serialize, Deserialize, Debug)]
50 pub struct UserAudioUploadRequest {
51 pub file_size: usize,
54 }
55
56 #[derive(Serialize, Deserialize, Debug)]
58 pub struct UserAudioUploadResponse {
59 pub session_uri: String,
61 }
62
63 make_path_parts!(UserAudioDeletePath => "/v1/user/me/audio/{}" => AudioId);
64}
65
66wrap_uuid! {
67 pub struct AudioId
69}
70
71#[derive(Serialize, Deserialize, Copy, Clone, Debug)]
73#[cfg_attr(feature = "backend", derive(sqlx::Type))]
74#[repr(i16)]
75pub enum AudioKind {
76 Mp3 = 0,
78}
79
80#[derive(Serialize, Deserialize, Debug)]
82pub struct AudioResponse {
83 pub metadata: AudioMetadata,
85}
86
87#[derive(Serialize, Deserialize, Debug)]
89pub struct AudioMetadata {
90 pub id: AudioId,
92
93 pub name: String,
95
96 pub description: String,
98
99 pub is_premium: bool,
101
102 pub publish_at: Option<DateTime<Utc>>,
104
105 pub styles: Vec<AudioStyleId>,
107
108 pub kind: AudioKind,
110
111 pub is_looping: bool,
113
114 pub created_at: DateTime<Utc>,
116
117 pub updated_at: Option<DateTime<Utc>>,
119}
120
121#[cfg(feature = "backend")]
123impl<'r> sqlx::FromRow<'r, PgRow> for AudioMetadata {
124 fn from_row(row: &'r PgRow) -> Result<Self, sqlx::Error> {
125 let DbAudio {
126 id,
127 kind,
128 name,
129 description,
130 is_premium,
131 publish_at,
132 styles,
133 is_looping,
134 created_at,
135 updated_at,
136 } = DbAudio::from_row(row)?;
137
138 Ok(Self {
139 id,
140 kind,
141 name,
142 description,
143 is_premium,
144 publish_at,
145 styles: styles.into_iter().map(|(it,)| it).collect(),
146 is_looping,
147 created_at,
148 updated_at,
149 })
150 }
151}
152
153#[cfg_attr(feature = "backend", derive(sqlx::FromRow))]
154#[cfg(feature = "backend")]
155struct DbAudio {
156 pub id: AudioId,
157 pub kind: AudioKind,
158 pub name: String,
159 pub description: String,
160 pub is_premium: bool,
161 pub publish_at: Option<DateTime<Utc>>,
162 pub styles: Vec<(AudioStyleId,)>,
163 pub is_looping: bool,
164 pub created_at: DateTime<Utc>,
165 pub updated_at: Option<DateTime<Utc>>,
166}