Skip to content

Commit 7e95403

Browse files
tyt2y3Expurple
andauthored
New iden design (#909)
* 1. change unquoted() signature * 2. change quoted() signature * 3. introduce unquoted_static * 4. remove prepare from iden * 5. remove type-sensitive comparison * remove quote from quoted * 6. revamp SeaRc and DynIden * rename to prepare_iden * tweaks * Impl IntoIden for String * improve tests * clippy * const fn is_static_iden hopefully this can get optimized * Apply suggestions from code review Co-authored-by: Dmitrii Aleksandrov <[email protected]> * Update src/types.rs Co-authored-by: Dmitrii Aleksandrov <[email protected]> * dep * fix build --------- Co-authored-by: Dmitrii Aleksandrov <[email protected]>
1 parent 31416f2 commit 7e95403

35 files changed

+491
-474
lines changed

README.md

Lines changed: 12 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -158,18 +158,13 @@ pub enum Character {
158158

159159
// Mapping between Enum variant and its corresponding string value
160160
impl Iden for Character {
161-
fn unquoted(&self, s: &mut dyn std::fmt::Write) {
162-
write!(
163-
s,
164-
"{}",
165-
match self {
166-
Self::Table => "character",
167-
Self::Id => "id",
168-
Self::FontId => "font_id",
169-
Self::FontSize => "font_size",
170-
}
171-
)
172-
.unwrap();
161+
fn unquoted(&self) -> &str {
162+
match self {
163+
Self::Table => "character",
164+
Self::Id => "id",
165+
Self::FontId => "font_id",
166+
Self::FontSize => "font_size",
167+
}
173168
}
174169
}
175170
```
@@ -198,7 +193,7 @@ assert_eq!(Glyph.to_string(), "glyph");
198193

199194
```rust
200195
#[cfg(feature = "derive")]
201-
use sea_query::{enum_def, Iden};
196+
use sea_query::{Iden, enum_def};
202197

203198
#[enum_def]
204199
struct Character {
@@ -476,8 +471,8 @@ assert_eq!(
476471
struct MyFunction;
477472

478473
impl Iden for MyFunction {
479-
fn unquoted(&self, s: &mut dyn Write) {
480-
write!(s, "MY_FUNCTION").unwrap();
474+
fn unquoted(&self) -> &str {
475+
"MY_FUNCTION"
481476
}
482477
}
483478

@@ -574,12 +569,7 @@ assert_eq!(
574569
```rust
575570
let table = Table::alter()
576571
.table(Font::Table)
577-
.add_column(
578-
ColumnDef::new("new_col")
579-
.integer()
580-
.not_null()
581-
.default(100),
582-
)
572+
.add_column(ColumnDef::new("new_col").integer().not_null().default(100))
583573
.to_owned();
584574

585575
assert_eq!(
@@ -621,9 +611,7 @@ assert_eq!(
621611
### Table Rename
622612

623613
```rust
624-
let table = Table::rename()
625-
.table(Font::Table, "font_new")
626-
.to_owned();
614+
let table = Table::rename().table(Font::Table, "font_new").to_owned();
627615

628616
assert_eq!(
629617
table.to_string(MysqlQueryBuilder),

sea-query-derive/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ proc-macro2 = { version = "1", default-features = false }
2323
thiserror = { version = "2", default-features = false }
2424

2525
[dev-dependencies]
26-
trybuild = "1.0"
26+
trybuild = "1.0.86"
2727
sea-query = { version = "1.0.0-rc.1", path = ".." }
2828
strum = { version = "0.25", features = ["derive"] }
2929

sea-query-derive/src/iden/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,11 @@ pub(crate) struct DeriveIden;
1313

1414
impl WriteArm for DeriveIden {
1515
fn variant(variant: TokenStream, name: TokenStream) -> TokenStream {
16-
quote! { Self::#variant => write!(s, "{}", #name).unwrap() }
16+
quote! { Self::#variant => #name }
1717
}
1818

1919
fn flattened(variant: TokenStream, name: &Ident) -> TokenStream {
20-
quote! { Self::#variant => #name.unquoted(s) }
20+
quote! { Self::#variant => #name.unquoted() }
2121
}
2222
}
2323

sea-query-derive/src/iden/write_arm.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use quote::{ToTokens, TokenStreamExt, quote};
77
use syn::{Error, Fields, FieldsNamed, Ident, Variant};
88

99
use super::{attr::IdenAttr, error::ErrorMsg};
10-
use crate::{find_attr, must_be_valid_iden};
10+
use crate::{find_attr, is_static_iden};
1111

1212
pub(crate) trait WriteArm {
1313
fn variant(variant: TokenStream, name: TokenStream) -> TokenStream;
@@ -159,7 +159,7 @@ where
159159
T::variant(variant, name)
160160
}
161161

162-
pub(crate) fn must_be_valid_iden(&self) -> bool {
162+
pub(crate) fn is_static_iden(&self) -> bool {
163163
let name: String = match &self.attr {
164164
Some(a) => match a {
165165
IdenAttr::Rename(name) => name.to_owned(),
@@ -169,7 +169,7 @@ where
169169
None => self.table_or_snake_case(),
170170
};
171171

172-
must_be_valid_iden(&name)
172+
is_static_iden(&name)
173173
}
174174
}
175175

sea-query-derive/src/lib.rs

Lines changed: 43 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ pub fn derive_iden_static(input: TokenStream) -> TokenStream {
107107
.map(IdenVariant::<DeriveIdenStatic>::try_from)
108108
.collect::<syn::Result<Vec<_>>>()
109109
{
110-
Ok(v) => quote! { #(#v),* },
110+
Ok(v) => v,
111111
Err(e) => return e.to_compile_error().into(),
112112
};
113113

@@ -117,7 +117,7 @@ pub fn derive_iden_static(input: TokenStream) -> TokenStream {
117117
impl #sea_query_path::IdenStatic for #ident {
118118
fn as_str(&self) -> &'static str {
119119
match self {
120-
#match_arms
120+
#(#match_arms),*
121121
}
122122
}
123123
}
@@ -149,7 +149,7 @@ fn get_table_name(ident: &proc_macro2::Ident, attrs: Vec<Attribute>) -> Result<S
149149
Ok(table_name)
150150
}
151151

152-
fn must_be_valid_iden(name: &str) -> bool {
152+
fn is_static_iden(name: &str) -> bool {
153153
// can only begin with [a-z_]
154154
name.chars()
155155
.take(1)
@@ -163,24 +163,24 @@ fn impl_iden_for_unit_struct(
163163
) -> proc_macro2::TokenStream {
164164
let sea_query_path = sea_query_path();
165165

166-
let prepare = if must_be_valid_iden(table_name) {
166+
if is_static_iden(table_name) {
167167
quote! {
168-
fn prepare(&self, s: &mut dyn ::std::fmt::Write, q: #sea_query_path::Quote) {
169-
write!(s, "{}", q.left()).unwrap();
170-
self.unquoted(s);
171-
write!(s, "{}", q.right()).unwrap();
168+
impl #sea_query_path::Iden for #ident {
169+
fn quoted(&self) -> std::borrow::Cow<'static, str> {
170+
std::borrow::Cow::Borrowed(#table_name)
171+
}
172+
173+
fn unquoted(&self) -> &str {
174+
#table_name
175+
}
172176
}
173177
}
174178
} else {
175-
quote! {}
176-
};
177-
178-
quote! {
179-
impl #sea_query_path::Iden for #ident {
180-
#prepare
181-
182-
fn unquoted(&self, s: &mut dyn ::std::fmt::Write) {
183-
write!(s, #table_name).unwrap();
179+
quote! {
180+
impl #sea_query_path::Iden for #ident {
181+
fn unquoted(&self) -> &str {
182+
#table_name
183+
}
184184
}
185185
}
186186
}
@@ -196,41 +196,44 @@ where
196196
{
197197
let sea_query_path = sea_query_path();
198198

199-
let mut is_all_valid = true;
199+
let mut is_all_static_iden = true;
200200

201201
let match_arms = match variants
202-
.map(|v| (table_name, v))
203202
.map(|v| {
204-
let v = IdenVariant::<DeriveIden>::try_from(v)?;
205-
is_all_valid &= v.must_be_valid_iden();
203+
let v = IdenVariant::<DeriveIden>::try_from((table_name, v))?;
204+
is_all_static_iden &= v.is_static_iden();
206205
Ok(v)
207206
})
208207
.collect::<syn::Result<Vec<_>>>()
209208
{
210-
Ok(v) => quote! { #(#v),* },
209+
Ok(v) => v,
211210
Err(e) => return e.to_compile_error(),
212211
};
213212

214-
let prepare = if is_all_valid {
213+
if is_all_static_iden {
215214
quote! {
216-
fn prepare(&self, s: &mut dyn ::std::fmt::Write, q: #sea_query_path::Quote) {
217-
write!(s, "{}", q.left()).unwrap();
218-
self.unquoted(s);
219-
write!(s, "{}", q.right()).unwrap();
215+
impl #sea_query_path::Iden for #ident {
216+
fn quoted(&self) -> std::borrow::Cow<'static, str> {
217+
std::borrow::Cow::Borrowed(match self {
218+
#(#match_arms),*
219+
})
220+
}
221+
222+
fn unquoted(&self) -> &str {
223+
match self {
224+
#(#match_arms),*
225+
}
226+
}
220227
}
221228
}
222229
} else {
223-
quote! {}
224-
};
225-
226-
quote! {
227-
impl #sea_query_path::Iden for #ident {
228-
#prepare
229-
230-
fn unquoted(&self, s: &mut dyn ::std::fmt::Write) {
231-
match self {
232-
#match_arms
233-
};
230+
quote! {
231+
impl #sea_query_path::Iden for #ident {
232+
fn unquoted(&self) -> &str {
233+
match self {
234+
#(#match_arms),*
235+
}
236+
}
234237
}
235238
}
236239
}
@@ -359,8 +362,8 @@ pub fn enum_def(args: TokenStream, input: TokenStream) -> TokenStream {
359362
}
360363

361364
impl #import_name::Iden for #enum_name {
362-
fn unquoted(&self, s: &mut dyn sea_query::Write) {
363-
write!(s, "{}", <Self as #import_name::IdenStatic>::as_str(&self)).unwrap();
365+
fn unquoted(&self) -> &str {
366+
<Self as #import_name::IdenStatic>::as_str(&self)
364367
}
365368
}
366369

sea-query-derive/tests/pass-static/flattened_unnamed.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,14 @@ enum Asset {
1010
Creation(CreationInfo),
1111
}
1212

13-
#[derive(Copy, Clone, IdenStatic)]
13+
#[derive(Default, Copy, Clone, IdenStatic)]
1414
enum CreationInfo {
15+
#[default]
1516
UserId,
1617
#[iden = "creation_date"]
1718
Date,
1819
}
1920

20-
impl Default for CreationInfo {
21-
fn default() -> Self {
22-
Self::UserId
23-
}
24-
}
25-
2621
fn main() {
2722
// custom ends up being default string which is an empty string
2823
let expected = ["asset", "id", "asset_name", "user_id", "creation_date"];

sea-query-derive/tests/pass-static/meta_list_renaming_everything.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use sea_query::{Iden, IdenStatic};
1+
use sea_query::{Iden, IntoIden, IdenStatic, MysqlQueryBuilder, PostgresQueryBuilder, QuotedBuilder};
22
use strum::{EnumIter, IntoEnumIterator};
33

44
#[derive(IdenStatic, EnumIter, Copy, Clone)]
@@ -39,10 +39,10 @@ fn main() {
3939
.for_each(|(iden, exp)| assert_eq!(iden, exp));
4040

4141
let mut string = String::new();
42-
Custom::Email(0).prepare(&mut string, '"'.into());
42+
PostgresQueryBuilder.prepare_iden(&Custom::Email(0).into_iden(), &mut string);
4343
assert_eq!(string, "\"EM`ail\"");
4444

4545
let mut string = String::new();
46-
Custom::Email(0).prepare(&mut string, b'`'.into());
46+
MysqlQueryBuilder.prepare_iden(&Custom::Email(0).into_iden(), &mut string);
4747
assert_eq!(string, "`EM``ail`");
4848
}

sea-query-derive/tests/pass-static/simple_unit_struct.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use sea_query::{Iden, IdenStatic};
1+
use sea_query::{Iden, IntoIden, IdenStatic, MysqlQueryBuilder, PostgresQueryBuilder, QuotedBuilder};
22

33
#[derive(Copy, Clone, IdenStatic)]
44
pub struct SomeType;
@@ -12,14 +12,14 @@ fn main() {
1212
assert_eq!(SomeTypeWithRename.to_string(), "Hel`lo");
1313

1414
let mut string = String::new();
15-
SomeType.prepare(&mut string, '"'.into());
15+
PostgresQueryBuilder.prepare_iden(&SomeType.into_iden(), &mut string);
1616
assert_eq!(string, "\"some_type\"");
1717

1818
let mut string = String::new();
19-
SomeTypeWithRename.prepare(&mut string, '"'.into());
19+
PostgresQueryBuilder.prepare_iden(&SomeTypeWithRename.into_iden(), &mut string);
2020
assert_eq!(string, "\"Hel`lo\"");
2121

2222
let mut string = String::new();
23-
SomeTypeWithRename.prepare(&mut string, b'`'.into());
23+
MysqlQueryBuilder.prepare_iden(&SomeTypeWithRename.into_iden(), &mut string);
2424
assert_eq!(string, "`Hel``lo`");
2525
}

sea-query-derive/tests/pass/flattened_named.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use sea_query::Iden;
22
use strum::{EnumIter, IntoEnumIterator};
3+
use std::borrow::Cow;
34

45
#[derive(Copy, Clone, Iden, EnumIter)]
56
enum Asset {
@@ -35,5 +36,6 @@ fn main() {
3536
.zip(expected)
3637
.for_each(|(var, exp)| {
3738
assert_eq!(var.to_string(), exp);
39+
assert_eq!(var.quoted(), Cow::Borrowed(exp));
3840
})
3941
}

sea-query-derive/tests/pass/meta_list_renaming_everything.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
use sea_query::Iden;
1+
use sea_query::{Iden, IntoIden, MysqlQueryBuilder, PostgresQueryBuilder, QuotedBuilder};
22
use strum::{EnumIter, IntoEnumIterator};
3+
use std::borrow::Cow;
34

45
#[derive(Iden, EnumIter)]
56
// Outer iden attributes overrides what's used for "Table"...
@@ -39,10 +40,12 @@ fn main() {
3940
.for_each(|(iden, exp)| assert_eq!(iden, exp));
4041

4142
let mut string = String::new();
42-
Custom::Email("".to_owned()).prepare(&mut string, '"'.into());
43+
PostgresQueryBuilder.prepare_iden(&Custom::Email("".to_owned()).into_iden(), &mut string);
4344
assert_eq!(string, "\"EM`ail\"");
4445

4546
let mut string = String::new();
46-
Custom::Email("".to_owned()).prepare(&mut string, b'`'.into());
47+
MysqlQueryBuilder.prepare_iden(&Custom::Email("".to_owned()).into_iden(), &mut string);
4748
assert_eq!(string, "`EM``ail`");
49+
50+
assert!(matches!(Custom::FirstName.quoted(), Cow::Owned(_)));
4851
}

0 commit comments

Comments
 (0)