mirror of
https://github.com/storytold/artcraft.git
synced 2026-11-03 17:08:13 +00:00
move sqlx impls to reusable macro
This commit is contained in:
1 parent
cb1e092ccd
commit
a34aedc375
3 files changed
+46
-40
No files matched your search
@@ -37,7 +37,7 @@ pub enum Visibility {
|
||||
}
|
||||
|
||||
|
||||
impl_enum_display_and_debug_for_to_str!(Visibility);
|
||||
impl_enum_display_and_debug_using_to_str!(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:
|
||||
|
||||
@@ -1,12 +1,5 @@
|
||||
use serde::Deserialize;
|
||||
use serde::Serialize;
|
||||
use sqlx::Decode;
|
||||
use sqlx::Encode;
|
||||
use sqlx::Type;
|
||||
use sqlx_core::database::HasArguments;
|
||||
use sqlx_core::encode::IsNull;
|
||||
use sqlx_core::error::BoxDynError;
|
||||
use sqlx_core::mysql::{MySql, MySqlTypeInfo, MySqlValueRef};
|
||||
|
||||
#[cfg(test)]
|
||||
use strum::EnumCount;
|
||||
@@ -26,37 +19,8 @@ pub enum MediaUploadType {
|
||||
Video,
|
||||
}
|
||||
|
||||
// This overt approach is being taken because of the following error:
|
||||
// `MySqlDatabaseError { code: Some("HY000"), number: 1210, message: "Incorrect arguments to mysqld_stmt_execute" }`
|
||||
// Basically, sqlx can't turn our enum into a VARCHAR when using #[derive(sqlx::Type)].
|
||||
// We further lose the ability to `#[sqlx(rename_all="lowercase")]`, etc., so our encoder/decoder
|
||||
// need to set the rules.
|
||||
// Solution adapted from https://github.com/launchbadge/sqlx/discussions/1502
|
||||
impl Type<MySql> for MediaUploadType {
|
||||
fn type_info() -> MySqlTypeInfo {
|
||||
String::type_info()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'q> Encode<'q, MySql> for MediaUploadType {
|
||||
fn encode_by_ref(&self, buf: &mut <MySql as HasArguments<'q>>::ArgumentBuffer) -> IsNull {
|
||||
// NB: In the absence of `#[derive(sqlx::Type)]` and `#sqlx(rename_all="lowercase")]`,
|
||||
// this controls the casing of the variants when sent to MySQL.
|
||||
self.to_str().encode_by_ref(buf)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'r> Decode<'r, MySql> for MediaUploadType {
|
||||
fn decode(
|
||||
value: MySqlValueRef<'r>,
|
||||
) -> Result<Self, BoxDynError> {
|
||||
let string = String::decode(value)?;
|
||||
let value = MediaUploadType::from_str(&string)?;
|
||||
Ok(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl_enum_display_and_debug_for_to_str!(MediaUploadType);
|
||||
impl_enum_display_and_debug_using_to_str!(MediaUploadType);
|
||||
impl_enum_sqlx_coders!(MediaUploadType);
|
||||
|
||||
/// NB: Legacy API for older code.
|
||||
impl MediaUploadType {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
/// Implement `Display` and `Debug` for enums that have a `.to_str()` method.
|
||||
/// This ensures that the casing follows whatever `.to_str()` specifies.
|
||||
macro_rules! impl_enum_display_and_debug_for_to_str {
|
||||
macro_rules! impl_enum_display_and_debug_using_to_str {
|
||||
($t:ident) => {
|
||||
|
||||
// Debug trait.
|
||||
@@ -42,3 +42,45 @@ macro_rules! impl_enum_display_and_debug_for_to_str {
|
||||
}
|
||||
}
|
||||
|
||||
/// This overt approach is being taken because of the following error:
|
||||
///
|
||||
/// `MySqlDatabaseError { code: Some("HY000"), number: 1210, message: "Incorrect arguments to mysqld_stmt_execute" }`
|
||||
///
|
||||
/// Basically, sqlx can't turn our enum into a VARCHAR when using #[derive(sqlx::Type)].
|
||||
/// Unfortunately, by not using this, we also lose the ability to `#[sqlx(rename_all="lowercase")]`, etc.,
|
||||
/// so our encoder/decoder need to set the rules.
|
||||
///
|
||||
/// Solution adapted from https://github.com/launchbadge/sqlx/discussions/1502
|
||||
macro_rules! impl_enum_sqlx_coders {
|
||||
($t:ident) => {
|
||||
|
||||
impl sqlx::Type<sqlx_core::mysql::MySql> for $t {
|
||||
fn type_info() -> sqlx_core::mysql::MySqlTypeInfo {
|
||||
String::type_info()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'q> sqlx::Encode<'q, sqlx_core::mysql::MySql> for $t {
|
||||
fn encode_by_ref(
|
||||
&self,
|
||||
buf: &mut <sqlx_core::mysql::MySql as sqlx_core::database::HasArguments<'q>>::ArgumentBuffer
|
||||
) -> sqlx_core::encode::IsNull {
|
||||
// NB: In the absence of `#[derive(sqlx::Type)]` and `#sqlx(rename_all="lowercase")]`,
|
||||
// this controls the casing of the variants when sent to MySQL.
|
||||
self.to_str().encode_by_ref(buf)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'r> sqlx::Decode<'r, sqlx_core::mysql::MySql> for $t {
|
||||
fn decode(
|
||||
value: sqlx_core::mysql::MySqlValueRef<'r>,
|
||||
) -> Result<Self, sqlx_core::error::BoxDynError> {
|
||||
let string = String::decode(value)?;
|
||||
let value = $t::from_str(&string)?;
|
||||
Ok(value)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user