Skip to content

Commit 666cbd3

Browse files
committed
fix enum migrations
1 parent ddb48dc commit 666cbd3

File tree

6 files changed

+79
-33
lines changed

6 files changed

+79
-33
lines changed

.github/workflows/ci.yml

+2-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,8 @@ jobs:
6161
- run: rustup self update
6262
- run: cd refinery_core && cargo test --all-features -- --test-threads 1
6363
- run: cd refinery && cargo build --all-features
64-
- run: cd refinery_macros && cargo test --features=enums
64+
- run: cd refinery_macros && cargo test --all-features
65+
- run: cd refinery_macros && cargo test --features enums enum_fn
6566
- run: cd refinery_cli && cargo test
6667

6768
test-sqlite:

examples/Cargo.toml

+2-1
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,11 @@ edition = "2021"
1010

1111
[features]
1212
enums = ["refinery/enums"]
13+
int8-versions = ["refinery/int8-versions"]
1314

1415
[dependencies]
1516
refinery = { path = "../refinery", features = ["rusqlite"] }
1617
rusqlite = "0.31"
1718
barrel = { version = "0.7", features = ["sqlite3"] }
1819
log = "0.4"
19-
env_logger = "0.11"
20+
env_logger = "0.11"

refinery/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ tiberius-config = ["refinery-core/tiberius", "refinery-core/tiberius-config"]
2525
serde = ["refinery-core/serde"]
2626
toml = ["refinery-core/toml"]
2727
enums = ["refinery-macros/enums"]
28-
int8-versions = ["refinery-core/int8-versions"]
28+
int8-versions = ["refinery-core/int8-versions", "refinery-macros/int8-versions"]
2929

3030
[dependencies]
3131
refinery-core = { version = "0.8.14", path = "../refinery_core" }

refinery/tests/postgres.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ mod postgres {
189189
fn applies_migration_int8() {
190190
run_test(|| {
191191
let mut client = Client::connect(&db_uri(), NoTls).unwrap();
192-
let report = int8::migrations::runner().run(&mut client).unwrap();
192+
let report = embedded::migrations::runner().run(&mut client).unwrap();
193193

194194
let applied_migrations = report.applied_migrations();
195195

refinery_macros/Cargo.toml

+3-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ repository = "https://github.com/rust-db/refinery"
99
edition = "2018"
1010

1111
[features]
12-
enums = []
12+
enums = ["dep:heck"]
13+
int8-versions = ["refinery-core/int8-versions"]
1314

1415
[lib]
1516
proc-macro = true
@@ -20,7 +21,7 @@ quote = "1"
2021
syn = "2"
2122
proc-macro2 = "1"
2223
regex = "1"
23-
heck = "0.5"
24+
heck = { version = "0.5", optional = true }
2425

2526
[dev-dependencies]
2627
tempfile = "3"

refinery_macros/src/lib.rs

+70-27
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! Contains Refinery macros that are used to import and embed migration files.
22
#![recursion_limit = "128"]
33

4+
#[cfg(feature = "enums")]
45
use heck::ToUpperCamelCase;
56
use proc_macro::TokenStream;
67
use proc_macro2::{Span as Span2, TokenStream as TokenStream2};
@@ -32,38 +33,53 @@ fn migration_fn_quoted<T: ToTokens>(_migrations: Vec<T>) -> TokenStream2 {
3233
result
3334
}
3435

36+
#[cfg(feature = "enums")]
3537
fn migration_enum_quoted(migration_names: &[impl AsRef<str>]) -> TokenStream2 {
36-
if cfg!(feature = "enums") {
37-
let mut variants = Vec::new();
38-
let mut discriminants = Vec::new();
39-
40-
for m in migration_names {
41-
let m = m.as_ref();
42-
let (_, version, name) = refinery_core::parse_migration_name(m)
43-
.unwrap_or_else(|e| panic!("Couldn't parse migration filename '{}': {:?}", m, e));
44-
let variant = Ident::new(name.to_upper_camel_case().as_str(), Span2::call_site());
45-
variants.push(quote! { #variant(Migration) = #version });
46-
discriminants.push(quote! { #version => Self::#variant(migration) });
38+
use refinery_core::SchemaVersion;
39+
40+
let mut variants = Vec::new();
41+
let mut discriminants = Vec::new();
42+
43+
for m in migration_names {
44+
let m = m.as_ref();
45+
let (_, version, name) = refinery_core::parse_migration_name(m)
46+
.unwrap_or_else(|e| panic!("Couldn't parse migration filename '{}': {:?}", m, e));
47+
let version: SchemaVersion = version;
48+
let variant = Ident::new(name.to_upper_camel_case().as_str(), Span2::call_site());
49+
variants.push(quote! { #variant(Migration) = #version });
50+
discriminants.push(quote! { #version => Self::#variant(migration) });
51+
}
52+
discriminants.push(quote! { v => panic!("Invalid migration version '{}'", v) });
53+
54+
#[cfg(feature = "int8-versions")]
55+
let embedded = quote! {
56+
#[repr(i64)]
57+
#[derive(Debug)]
58+
pub enum EmbeddedMigration {
59+
#(#variants),*
4760
}
48-
discriminants.push(quote! { v => panic!("Invalid migration version '{}'", v) });
61+
};
4962

50-
let result = quote! {
51-
#[derive(Debug)]
52-
pub enum EmbeddedMigration {
53-
#(#variants),*
54-
}
63+
#[cfg(not(feature = "int8-versions"))]
64+
let embedded = quote! {
65+
#[repr(i32)]
66+
#[derive(Debug)]
67+
pub enum EmbeddedMigration {
68+
#(#variants),*
69+
}
70+
};
71+
72+
quote! {
73+
74+
#embedded
5575

56-
impl From<Migration> for EmbeddedMigration {
57-
fn from(migration: Migration) -> Self {
58-
match migration.version() as SchemaVersion {
59-
#(#discriminants),*
60-
}
76+
impl From<Migration> for EmbeddedMigration {
77+
fn from(migration: Migration) -> Self {
78+
match migration.version() as SchemaVersion {
79+
#(#discriminants),*
6180
}
6281
}
63-
};
64-
result
65-
} else {
66-
quote!()
82+
}
6783
}
6884
}
6985

@@ -123,7 +139,11 @@ pub fn embed_migrations(input: TokenStream) -> TokenStream {
123139
}
124140

125141
let fnq = migration_fn_quoted(_migrations);
142+
#[cfg(feature = "enums")]
126143
let enums = migration_enum_quoted(migration_filenames.as_slice());
144+
#[cfg(not(feature = "enums"))]
145+
let enums = quote!();
146+
127147
(quote! {
128148
pub mod migrations {
129149
#(#migrations_mods)*
@@ -138,10 +158,33 @@ pub fn embed_migrations(input: TokenStream) -> TokenStream {
138158
mod tests {
139159
use super::{migration_fn_quoted, quote};
140160

161+
#[cfg(all(feature = "enums", feature = "int8-versions"))]
162+
#[test]
163+
fn test_enum_fn_i8() {
164+
let expected = concat! {
165+
"# [repr (i64)] ",
166+
"# [derive (Debug)] ",
167+
"pub enum EmbeddedMigration { ",
168+
"Foo (Migration) = 1i64 , ",
169+
"BarBaz (Migration) = 3i64 ",
170+
"} ",
171+
"impl From < Migration > for EmbeddedMigration { ",
172+
"fn from (migration : Migration) -> Self { ",
173+
"match migration . version () as SchemaVersion { ",
174+
"1i64 => Self :: Foo (migration) , ",
175+
"3i64 => Self :: BarBaz (migration) , ",
176+
"v => panic ! (\"Invalid migration version '{}'\" , v) ",
177+
"} } }"
178+
};
179+
let enums = super::migration_enum_quoted(&["V1__foo", "U3__barBAZ"]).to_string();
180+
assert_eq!(expected, enums);
181+
}
182+
183+
#[cfg(all(feature = "enums", not(feature = "int8-versions")))]
141184
#[test]
142-
#[cfg(feature = "enums")]
143185
fn test_enum_fn() {
144186
let expected = concat! {
187+
"# [repr (i32)] ",
145188
"# [derive (Debug)] ",
146189
"pub enum EmbeddedMigration { ",
147190
"Foo (Migration) = 1i32 , ",

0 commit comments

Comments
 (0)