mirror of
https://github.com/launchbadge/sqlx.git
synced 2025-10-02 15:25:32 +00:00
Add mixedCase and CamelCase to rename-all, added rename-all to FromRow
This commit is contained in:
parent
e584618041
commit
00a999145f
@ -33,6 +33,8 @@ pub enum RenameAll {
|
||||
UpperCase,
|
||||
ScreamingSnakeCase,
|
||||
KebabCase,
|
||||
MixedCase,
|
||||
CamelCase,
|
||||
}
|
||||
|
||||
pub struct SqlxContainerAttributes {
|
||||
@ -77,7 +79,8 @@ pub fn parse_container_attributes(input: &[Attribute]) -> syn::Result<SqlxContai
|
||||
"UPPERCASE" => RenameAll::UpperCase,
|
||||
"SCREAMING_SNAKE_CASE" => RenameAll::ScreamingSnakeCase,
|
||||
"kebab-case" => RenameAll::KebabCase,
|
||||
|
||||
"mixedCase" => RenameAll::MixedCase,
|
||||
"CamelCase" => RenameAll::CamelCase,
|
||||
_ => fail!(meta, "unexpected value for rename_all"),
|
||||
};
|
||||
|
||||
|
@ -10,7 +10,7 @@ pub(crate) use r#type::expand_derive_type;
|
||||
pub(crate) use row::expand_derive_from_row;
|
||||
|
||||
use self::attributes::RenameAll;
|
||||
use heck::{KebabCase, ShoutySnakeCase, SnakeCase};
|
||||
use heck::{KebabCase, ShoutySnakeCase, SnakeCase, CamelCase, MixedCase};
|
||||
use std::iter::FromIterator;
|
||||
use syn::DeriveInput;
|
||||
|
||||
@ -35,5 +35,8 @@ pub(crate) fn rename_all(s: &str, pattern: RenameAll) -> String {
|
||||
RenameAll::UpperCase => s.to_uppercase(),
|
||||
RenameAll::ScreamingSnakeCase => s.to_shouty_snake_case(),
|
||||
RenameAll::KebabCase => s.to_kebab_case(),
|
||||
RenameAll::MixedCase => s.to_mixed_case(),
|
||||
RenameAll::CamelCase => s.to_camel_case(),
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ use syn::{
|
||||
Fields, FieldsNamed, FieldsUnnamed, Lifetime, Stmt,
|
||||
};
|
||||
|
||||
use super::attributes::parse_child_attributes;
|
||||
use super::{attributes::{parse_child_attributes, parse_container_attributes}, rename_all};
|
||||
|
||||
pub fn expand_derive_from_row(input: &DeriveInput) -> syn::Result<proc_macro2::TokenStream> {
|
||||
match &input.data {
|
||||
@ -69,13 +69,21 @@ fn expand_derive_from_row_struct(
|
||||
|
||||
let (impl_generics, _, where_clause) = generics.split_for_impl();
|
||||
|
||||
let container_attributes = parse_container_attributes(&input.attrs)?;
|
||||
|
||||
let reads = fields.iter().filter_map(|field| -> Option<Stmt> {
|
||||
|
||||
|
||||
let id = &field.ident.as_ref()?;
|
||||
let attributes = parse_child_attributes(&field.attrs).unwrap();
|
||||
let id_s = match attributes.rename {
|
||||
Some(rename) => rename,
|
||||
None => id.to_string().trim_start_matches("r#").to_owned(),
|
||||
};
|
||||
let id_s = attributes.rename
|
||||
.or_else(|| Some(id.to_string().trim_start_matches("r#").to_owned()))
|
||||
.map(|s| match container_attributes.rename_all {
|
||||
Some(pattern) => rename_all(&s, pattern),
|
||||
None => s
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
let ty = &field.ty;
|
||||
|
||||
if attributes.default {
|
||||
|
@ -67,13 +67,29 @@ enum ColorScreamingSnake {
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, sqlx::Type)]
|
||||
#[sqlx(rename = "color-kebab-case")]
|
||||
#[sqlx(rename = "color_kebab_case")]
|
||||
#[sqlx(rename_all = "kebab-case")]
|
||||
enum ColorKebabCase {
|
||||
RedGreen,
|
||||
BlueBlack,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, sqlx::Type)]
|
||||
#[sqlx(rename = "color_mixed_case")]
|
||||
#[sqlx(rename_all = "mixedCase")]
|
||||
enum ColorMixedCase {
|
||||
RedGreen,
|
||||
BlueBlack,
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, sqlx::Type)]
|
||||
#[sqlx(rename = "color_camel_case")]
|
||||
#[sqlx(rename_all = "CamelCase")]
|
||||
enum ColorCamelCase {
|
||||
RedGreen,
|
||||
BlueBlack,
|
||||
}
|
||||
|
||||
// "Strong" enum can map to a custom type
|
||||
#[derive(PartialEq, Debug, sqlx::Type)]
|
||||
#[sqlx(rename = "mood")]
|
||||
@ -141,13 +157,19 @@ DROP TYPE IF EXISTS color_lower CASCADE;
|
||||
DROP TYPE IF EXISTS color_snake CASCADE;
|
||||
DROP TYPE IF EXISTS color_upper CASCADE;
|
||||
DROP TYPE IF EXISTS color_screaming_snake CASCADE;
|
||||
DROP TYPE IF EXISTS "color-kebab-case" CASCADE;
|
||||
DROP TYPE IF EXISTS color_kebab_case CASCADE;
|
||||
DROP TYPE IF EXISTS color_mixed_case CASCADE;
|
||||
DROP TYPE IF EXISTS color_camel_case CASCADE;
|
||||
|
||||
|
||||
CREATE TYPE color_lower AS ENUM ( 'red', 'green', 'blue' );
|
||||
CREATE TYPE color_snake AS ENUM ( 'red_green', 'blue_black' );
|
||||
CREATE TYPE color_upper AS ENUM ( 'RED', 'GREEN', 'BLUE' );
|
||||
CREATE TYPE color_screaming_snake AS ENUM ( 'RED_GREEN', 'BLUE_BLACK' );
|
||||
CREATE TYPE "color-kebab-case" AS ENUM ( 'red-green', 'blue-black' );
|
||||
CREATE TYPE color_kebab_case" AS ENUM ( 'red-green', 'blue-black' );
|
||||
CREATE TYPE color_mixed_case AS ENUM ( 'redGreen', 'blueBlack' );
|
||||
CREATE TYPE color_camel_case AS ENUM ( 'RedGreen', 'BlueBlack' );
|
||||
|
||||
|
||||
CREATE TABLE people (
|
||||
id serial PRIMARY KEY,
|
||||
@ -276,7 +298,7 @@ SELECT id, mood FROM people WHERE id = $1
|
||||
|
||||
let rec: (bool, ColorKebabCase) = sqlx::query_as(
|
||||
"
|
||||
SELECT $1 = 'red-green'::\"color-kebab-case\", $1
|
||||
SELECT $1 = 'red-green'::color_kebab_case, $1
|
||||
",
|
||||
)
|
||||
.bind(&ColorKebabCase::RedGreen)
|
||||
@ -286,6 +308,30 @@ SELECT id, mood FROM people WHERE id = $1
|
||||
assert!(rec.0);
|
||||
assert_eq!(rec.1, ColorKebabCase::RedGreen);
|
||||
|
||||
let rec: (bool, ColorMixedCase) = sqlx::query_as(
|
||||
"
|
||||
SELECT $1 = 'redGreen'::color_mixed_case, $1
|
||||
",
|
||||
)
|
||||
.bind(&ColorMixedCase::RedGreen)
|
||||
.fetch_one(&mut conn)
|
||||
.await?;
|
||||
|
||||
assert!(rec.0);
|
||||
assert_eq!(rec.1, ColorMixedCase::RedGreen);
|
||||
|
||||
let rec: (bool, ColorCamelCase) = sqlx::query_as(
|
||||
"
|
||||
SELECT $1 = 'RedGreen'::color_camel_case, $1
|
||||
",
|
||||
)
|
||||
.bind(&ColorCamelCase::RedGreen)
|
||||
.fetch_one(&mut conn)
|
||||
.await?;
|
||||
|
||||
assert!(rec.0);
|
||||
assert_eq!(rec.1, ColorCamelCase::RedGreen);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -426,6 +472,34 @@ async fn test_from_row_with_rename() -> anyhow::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(feature = "macros")]
|
||||
#[sqlx_macros::test]
|
||||
async fn test_from_row_with_rename_all() -> anyhow::Result<()> {
|
||||
#[derive(Debug, sqlx::FromRow)]
|
||||
#[sqlx(rename_all = "mixedCase")]
|
||||
struct AccountKeyword {
|
||||
user_id: i32,
|
||||
user_name: String,
|
||||
user_surname: String,
|
||||
}
|
||||
|
||||
let mut conn = new::<Postgres>().await?;
|
||||
|
||||
let account: AccountKeyword = sqlx::query_as(
|
||||
r#"SELECT * from (VALUES (1, 'foo', 'bar')) accounts(userId, userName, userSurname)"#
|
||||
)
|
||||
.fetch_one(&mut conn)
|
||||
.await?;
|
||||
println!("{:?}", account);
|
||||
|
||||
assert_eq!(1, account.user_id);
|
||||
assert_eq!("foo", account.user_name);
|
||||
assert_eq!("bar8", account.user_surname);
|
||||
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(feature = "macros")]
|
||||
#[sqlx_macros::test]
|
||||
async fn test_from_row_tuple() -> anyhow::Result<()> {
|
||||
|
Loading…
x
Reference in New Issue
Block a user