shared/domain/audio.rs
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 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
//! Types for audio files.
use super::meta::AudioStyleId;
use crate::api::endpoints::PathPart;
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
#[cfg(feature = "backend")]
use sqlx::postgres::PgRow;
/// Types for user audio library.
pub mod user {
use macros::make_path_parts;
use serde::{Deserialize, Serialize};
use super::AudioId;
use crate::api::endpoints::PathPart;
make_path_parts!(UserAudioListPath => "/v1/user/me/audio");
/// Response for listing.
#[derive(Serialize, Deserialize, Debug)]
pub struct UserAudioListResponse {
/// the audio files returned.
pub audio_files: Vec<UserAudioResponse>,
}
make_path_parts!(UserAudioGetPath => "/v1/user/me/audio/{}" => AudioId);
/// Response for getting a single audio file.
#[derive(Serialize, Deserialize, Debug)]
pub struct UserAudioResponse {
/// The audio file's metadata.
pub metadata: UserAudio,
}
make_path_parts!(UserAudioCreatePath => "/v1/user/me/audio");
/// Over the wire representation of an audio file's metadata.
#[derive(Serialize, Deserialize, Debug)]
pub struct UserAudio {
/// The audio file's ID.
pub id: AudioId,
// more fields to be added
}
make_path_parts!(UserAudioUploadPath => "/v1/user/me/audio/{}/raw" => AudioId);
/// Request indicating the size of an image for upload.
#[derive(Serialize, Deserialize, Debug)]
pub struct UserAudioUploadRequest {
/// The size of the audio to be uploaded in bytes. Allows the API server to check that the file size is
/// within limits and as a verification at GCS that the entire file was uploaded
pub file_size: usize,
}
/// URL to upload an audio. Supports resumable uploading.
#[derive(Serialize, Deserialize, Debug)]
pub struct UserAudioUploadResponse {
/// The session URI used for uploading, including the query for uploader ID
pub session_uri: String,
}
make_path_parts!(UserAudioDeletePath => "/v1/user/me/audio/{}" => AudioId);
}
wrap_uuid! {
/// Wrapper type around [`Uuid`](Uuid), represents the ID of an audio file.
pub struct AudioId
}
/// Represents different kinds of audio.
#[derive(Serialize, Deserialize, Copy, Clone, Debug)]
#[cfg_attr(feature = "backend", derive(sqlx::Type))]
#[repr(i16)]
pub enum AudioKind {
/// Audio is an Mp3
Mp3 = 0,
}
/// Response for getting a single audio file.
#[derive(Serialize, Deserialize, Debug)]
pub struct AudioResponse {
/// The audio's metadata.
pub metadata: AudioMetadata,
}
/// Over the wire representation of an audio file's metadata.
#[derive(Serialize, Deserialize, Debug)]
pub struct AudioMetadata {
/// The audio's ID.
pub id: AudioId,
/// The name of the audio.
pub name: String,
/// The description of the audio file.
pub description: String,
/// Is the audio premium?
pub is_premium: bool,
/// When the audio should be considered published (if at all).
pub publish_at: Option<DateTime<Utc>>,
/// The styles associated with the audio file.
pub styles: Vec<AudioStyleId>,
/// What kind of audio this is.
pub kind: AudioKind,
/// Should the audio loop?
pub is_looping: bool,
/// When the audio was originally created.
pub created_at: DateTime<Utc>,
/// When the audio was last updated.
pub updated_at: Option<DateTime<Utc>>,
}
// HACK: can't get `Vec<_>` directly from the DB. See `[crate::domain::image::ImageMetadata]`
#[cfg(feature = "backend")]
impl<'r> sqlx::FromRow<'r, PgRow> for AudioMetadata {
fn from_row(row: &'r PgRow) -> Result<Self, sqlx::Error> {
let DbAudio {
id,
kind,
name,
description,
is_premium,
publish_at,
styles,
is_looping,
created_at,
updated_at,
} = DbAudio::from_row(row)?;
Ok(Self {
id,
kind,
name,
description,
is_premium,
publish_at,
styles: styles.into_iter().map(|(it,)| it).collect(),
is_looping,
created_at,
updated_at,
})
}
}
#[cfg_attr(feature = "backend", derive(sqlx::FromRow))]
#[cfg(feature = "backend")]
struct DbAudio {
pub id: AudioId,
pub kind: AudioKind,
pub name: String,
pub description: String,
pub is_premium: bool,
pub publish_at: Option<DateTime<Utc>>,
pub styles: Vec<(AudioStyleId,)>,
pub is_looping: bool,
pub created_at: DateTime<Utc>,
pub updated_at: Option<DateTime<Utc>>,
}