Hack for sqlx to insert enums into varchar, but case still wrong

This commit is contained in:
Brandon Thomas committed 2023-01-11 00:33:39 -05:00
1 parent a1510d45b2
commit 43c890b27c
9 files changed
+174 -57

No files matched your search

@@ -1,7 +1,7 @@
use anyhow::anyhow;
use container_common::anyhow_result::AnyhowResult;
use enums::core::visibility::Visibility;
use reusable_types::db::enums::media_upload_type::MediaUploadType;
use enums::files::media_upload_type::MediaUploadType;
use reusable_types::db::payloads::MediaUploadDetails;
use sqlx::MySqlPool;
use tokens::files::media_upload::MediaUploadToken;
@@ -86,7 +86,7 @@ SET
args.token,
args.uuid_idempotency_token,
"audio", // TODO: args.media_type,
args.media_type,
/*args.maybe_original_filename,
args.original_file_size_bytes,
args.original_duration_millis,
@@ -19,7 +19,7 @@ use http_server_common::response::serialize_as_json_error::serialize_as_json_err
use log::{info, warn, log};
use regex::Regex;
use reusable_types::db::enums::generic_download_type::GenericDownloadType;
use reusable_types::db::enums::media_upload_type::MediaUploadType;
use enums::files::media_upload_type::MediaUploadType;
use reusable_types::db::payloads::MediaUploadDetails;
use sqlx::error::DatabaseError;
use sqlx::error::Error::Database;
+43
View File
@@ -30,6 +30,33 @@ pub enum Visibility {
// have not yet been migrated to this scheme.
}
impl_string_enum!(Visibility);
// For reference, here's what the serde implementation might be if manually written.
// This may be useful for designing composite types in the future:
//
// use serde::{Deserializer, Serializer};
//
// impl serde::Serialize for UserToken {
// fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
// serializer.serialize_str(&self.0)
// }
// }
//
// impl<'de> serde::Deserialize<'de> for UserToken {
// fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Self, D::Error> {
// let s = String::deserialize(d)?;
// Ok(UserToken(s))
// }
// }
//impl sqlx::Type<MySql> for Visibility {
// fn type_info() -> sqlx_core::database::TypeInfo<MySql> {
// todo!()
// }
//}
impl Default for Visibility {
fn default() -> Self { Self::Public }
}
@@ -87,6 +114,22 @@ mod tests {
assert!(Visibility::from_str("foo").is_err());
}
mod traits {
use crate::core::visibility::Visibility;
#[test]
fn display() {
let visibility = Visibility::Hidden;
assert_eq!(format!("{}", visibility), "hidden".to_string());
}
#[test]
fn debug() {
let visibility = Visibility::Private;
assert_eq!(format!("{:?}", visibility), "private".to_string());
}
}
#[derive(Serialize, Deserialize, PartialEq, Debug)]
struct CompositeType {
visibility: Visibility,
@@ -0,0 +1,93 @@
use sqlx::Type;
use serde::Deserialize;
use serde::Serialize;
use sqlx_core::database::HasArguments;
use sqlx_core::encode::IsNull;
use sqlx_core::mysql::MySql;
/// Used in the `media_uploads` table in a `VARCHAR` field.
///
/// DO NOT CHANGE VALUES WITHOUT A MIGRATION STRATEGY.
//#[derive(Clone, Copy, Eq, PartialEq, Debug, Deserialize, Serialize, sqlx::Type)]
#[derive(Clone, Copy, Eq, PartialEq, Debug, Deserialize, Serialize)]
#[serde(rename_all = "lowercase")]
//#[sqlx(rename_all = "lowercase")]
pub enum MediaUploadType {
#[serde(rename = "audio")]
//#[sqlx(rename = "audio")]
Audio,
#[serde(rename = "video")]
//#[sqlx(rename = "video")]
Video,
}
// Solution adapted from https://github.com/launchbadge/sqlx/discussions/1502
impl Type<sqlx::MySql> for MediaUploadType {
fn type_info() -> sqlx::mysql::MySqlTypeInfo {
String::type_info()
}
}
impl<'q> sqlx::Encode<'q, sqlx::MySql> for MediaUploadType {
fn encode_by_ref(&self, buf: &mut <MySql as HasArguments<'q>>::ArgumentBuffer) -> IsNull {
self.to_string().encode_by_ref(buf)
}
}
impl<'r> sqlx::Decode<'r, sqlx::MySql> for MediaUploadType {
fn decode(
value: sqlx::mysql::MySqlValueRef<'r>,
) -> Result<Self, sqlx::error::BoxDynError> {
let string = String::decode(value)?;
let value = MediaUploadType::from_str(&string)?;
//let value = string.parse()?;
Ok(value)
}
}
impl_string_enum!(MediaUploadType);
/// NB: Legacy API for older code.
impl MediaUploadType {
pub fn to_str(&self) -> &'static str {
match self {
Self::Audio => "audio",
Self::Video => "video",
}
}
pub fn from_str(value: &str) -> Result<Self, String> {
match value {
"audio" => Ok(Self::Audio),
"video" => Ok(Self::Video),
_ => Err(format!("invalid value: {:?}", value)),
}
}
}
#[cfg(test)]
mod tests {
use crate::files::media_upload_type::MediaUploadType;
use crate::test_helpers::assert_serialization;
#[test]
fn test_serialization() {
assert_serialization(MediaUploadType::Audio, "audio");
assert_serialization(MediaUploadType::Video, "video");
}
#[test]
fn test_to_str() {
assert_eq!(MediaUploadType::Audio.to_str(), "audio");
assert_eq!(MediaUploadType::Video.to_str(), "video");
}
#[test]
fn test_from_str() {
assert_eq!(MediaUploadType::from_str("audio").unwrap(), MediaUploadType::Audio);
assert_eq!(MediaUploadType::from_str("video").unwrap(), MediaUploadType::Video);
assert!(MediaUploadType::from_str("foo").is_err());
}
}
+1
View File
@@ -0,0 +1 @@
pub mod media_upload_type;
+4
View File
@@ -21,6 +21,10 @@
#[macro_use] extern crate serde_derive;
#[macro_use]
mod macros;
#[cfg(test)] pub mod test_helpers;
pub mod core;
pub mod files;
+30
View File
@@ -0,0 +1,30 @@
// Default methods for string enum types.
macro_rules! impl_string_enum {
($t:ident) => {
// // Constructors and accessors.
// impl $t {
// #[inline]
// pub fn new(value: String) -> Self {
// $t(value)
// }
//
// #[inline]
// pub fn new_from_str(value: &str) -> Self {
// $t(value.to_string())
// }
//
// #[inline]
// pub fn as_str(&self) -> &str {
// &self.0
// }
// }
// Display trait.
impl std::fmt::Display for $t {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{:?}", self)
}
}
}
}
@@ -1,53 +0,0 @@
/// Used in the `media_uploads` table.
///
/// DO NOT CHANGE VALUES WITHOUT A MIGRATION STRATEGY.
#[derive(Clone, Copy, Eq, PartialEq, Debug, Deserialize, Serialize, sqlx::Type)]
#[serde(rename_all = "lowercase")]
#[sqlx(rename_all = "lowercase")]
pub enum MediaUploadType {
Audio,
Video,
}
/// NB: Legacy API for older code.
impl MediaUploadType {
pub fn to_str(&self) -> &'static str {
match self {
Self::Audio => "audio",
Self::Video => "video",
}
}
pub fn from_str(value: &str) -> Result<Self, String> {
match value {
"audio" => Ok(Self::Audio),
"video" => Ok(Self::Video),
_ => Err(format!("invalid value: {:?}", value)),
}
}
}
#[cfg(test)]
mod tests {
use crate::db::enums::media_upload_type::MediaUploadType;
use crate::test_helpers::assert_serialization;
#[test]
fn test_serialization() {
assert_serialization(MediaUploadType::Audio, "audio");
assert_serialization(MediaUploadType::Video, "video");
}
#[test]
fn test_to_str() {
assert_eq!(MediaUploadType::Audio.to_str(), "audio");
assert_eq!(MediaUploadType::Video.to_str(), "video");
}
#[test]
fn test_from_str() {
assert_eq!(MediaUploadType::from_str("audio").unwrap(), MediaUploadType::Audio);
assert_eq!(MediaUploadType::from_str("video").unwrap(), MediaUploadType::Video);
assert!(MediaUploadType::from_str("foo").is_err());
}
}
@@ -3,5 +3,4 @@
pub mod generic_download_type;
pub mod generic_inference_type;
pub mod media_upload_type;
pub mod vocoder_type;