migrations_macros/
embed_migrations.rs1use crate::migrations::migration_directory_from_given_path;
2use migrations_internals::{TomlMetadata, migrations_directories, version_from_string};
3use quote::quote;
4use std::error::Error;
5use std::fs::DirEntry;
6use std::path::Path;
7
8pub fn expand(path: Option<syn::LitStr>) -> proc_macro2::TokenStream {
9 let migrations_path_opt = path.map(|l| l.value());
10 let migrations_expr = migration_directory_from_given_path(migrations_path_opt.as_deref())
11 .unwrap_or_else(|_| {
12 {
::core::panicking::panic_fmt(format_args!("Failed to receive migrations dir from {0:?}",
migrations_path_opt));
}panic!("Failed to receive migrations dir from {migrations_path_opt:?}")
13 });
14 let embedded_migrations =
15 migration_literals_from_path(&migrations_expr).expect("Failed to read migration literals");
16
17 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "diesel_migrations");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "EmbeddedMigrations");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "new");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_and(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Bracket,
{
let mut _s = ::quote::__private::TokenStream::new();
{
use ::quote::__private::ext::*;
let has_iter = ::quote::__private::HasIterator::<false>;
#[allow(unused_mut)]
let (mut embedded_migrations, i) =
embedded_migrations.quote_into_iter();
let has_iter = has_iter | i;
<_ as
::quote::__private::CheckHasIterator<true>>::check(has_iter);
while true {
let embedded_migrations =
match embedded_migrations.next() {
Some(_x) => ::quote::__private::RepInterp(_x),
None => break,
};
::quote::ToTokens::to_tokens(&embedded_migrations, &mut _s);
::quote::__private::push_comma(&mut _s);
}
}
_s
});
_s
});
_s
}quote! {
18 diesel_migrations::EmbeddedMigrations::new(&[#(#embedded_migrations,)*])
19 }
20}
21
22fn migration_literals_from_path(
23 path: &Path,
24) -> Result<Vec<proc_macro2::TokenStream>, Box<dyn Error>> {
25 let mut migrations = migrations_directories(path)?.collect::<Result<Vec<_>, _>>()?;
26
27 migrations.sort_by_key(DirEntry::path);
28
29 Ok(migrations
30 .into_iter()
31 .map(|e| migration_literal_from_path(&e.path()))
32 .collect())
33}
34
35fn migration_literal_from_path(path: &Path) -> proc_macro2::TokenStream {
36 let name = path
37 .file_name()
38 .unwrap_or_else(|| {
::core::panicking::panic_fmt(format_args!("Can\'t get file name from path `{0:?}`",
path));
}panic!("Can't get file name from path `{path:?}`"))
39 .to_string_lossy();
40 if version_from_string(&name).is_none() {
41 {
::core::panicking::panic_fmt(format_args!("Invalid migration directory: the directory\'s name should be <timestamp>_<name_of_migration>, and it should contain up.sql and optionally down.sql."));
};panic!(
42 "Invalid migration directory: the directory's name should be \
43 <timestamp>_<name_of_migration>, and it should contain \
44 up.sql and optionally down.sql."
45 );
46 }
47 let up_sql_path = path.join("up.sql");
48 let up_sql_path = up_sql_path.to_str();
49 let down_sql_path = path.join("down.sql");
50 let metadata = TomlMetadata::read_from_file(&path.join("metadata.toml")).unwrap_or_default();
51 let run_in_transaction = metadata.run_in_transaction;
52
53 let down_sql = match down_sql_path.metadata() {
54 Err(e) if e.kind() == std::io::ErrorKind::NotFound => {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "None");
_s
}quote! { None },
55 _ => {
56 let down_sql_path = down_sql_path.to_str();
57 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "Some");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "include_str");
::quote::__private::push_bang(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&down_sql_path, &mut _s);
_s
});
_s
});
_s
}quote! { Some(include_str!(#down_sql_path)) }
58 }
59 };
60
61 {
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "diesel_migrations");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "EmbeddedMigration");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "new");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::__private::push_ident(&mut _s, "include_str");
::quote::__private::push_bang(&mut _s);
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&up_sql_path, &mut _s);
_s
});
::quote::__private::push_comma(&mut _s);
::quote::ToTokens::to_tokens(&down_sql, &mut _s);
::quote::__private::push_comma(&mut _s);
::quote::__private::push_ident(&mut _s, "diesel_migrations");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "EmbeddedName");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "new");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&name, &mut _s);
_s
});
::quote::__private::push_comma(&mut _s);
::quote::__private::push_ident(&mut _s, "diesel_migrations");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "TomlMetadataWrapper");
::quote::__private::push_colon2(&mut _s);
::quote::__private::push_ident(&mut _s, "new");
::quote::__private::push_group(&mut _s,
::quote::__private::Delimiter::Parenthesis,
{
let mut _s = ::quote::__private::TokenStream::new();
::quote::ToTokens::to_tokens(&run_in_transaction, &mut _s);
_s
});
_s
});
_s
}quote!(diesel_migrations::EmbeddedMigration::new(
62 include_str!(#up_sql_path),
63 #down_sql,
64 diesel_migrations::EmbeddedName::new(#name),
65 diesel_migrations::TomlMetadataWrapper::new(#run_in_transaction)
66 ))
67}