Skip to main content

migrations_macros/
embed_migrations.rs

1use 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: String) -> proc_macro2::TokenStream {
9    let migrations_path_opt = if path.is_empty() {
10        None
11    } else {
12        Some(path.replace('"', ""))
13    };
14    let migrations_expr = migration_directory_from_given_path(migrations_path_opt.as_deref())
15        .unwrap_or_else(|_| {
16            {
    ::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:?}")
17        });
18    let embedded_migrations =
19        migration_literals_from_path(&migrations_expr).expect("Failed to read migration literals");
20
21    {
    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! {
22        diesel_migrations::EmbeddedMigrations::new(&[#(#embedded_migrations,)*])
23    }
24}
25
26fn migration_literals_from_path(
27    path: &Path,
28) -> Result<Vec<proc_macro2::TokenStream>, Box<dyn Error>> {
29    let mut migrations = migrations_directories(path)?.collect::<Result<Vec<_>, _>>()?;
30
31    migrations.sort_by_key(DirEntry::path);
32
33    Ok(migrations
34        .into_iter()
35        .map(|e| migration_literal_from_path(&e.path()))
36        .collect())
37}
38
39fn migration_literal_from_path(path: &Path) -> proc_macro2::TokenStream {
40    let name = path
41        .file_name()
42        .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:?}`"))
43        .to_string_lossy();
44    if version_from_string(&name).is_none() {
45        {
    ::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!(
46            "Invalid migration directory: the directory's name should be \
47             <timestamp>_<name_of_migration>, and it should contain \
48             up.sql and optionally down.sql."
49        );
50    }
51    let up_sql_path = path.join("up.sql");
52    let up_sql_path = up_sql_path.to_str();
53    let down_sql_path = path.join("down.sql");
54    let metadata = TomlMetadata::read_from_file(&path.join("metadata.toml")).unwrap_or_default();
55    let run_in_transaction = metadata.run_in_transaction;
56
57    let down_sql = match down_sql_path.metadata() {
58        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 },
59        _ => {
60            let down_sql_path = down_sql_path.to_str();
61            {
    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)) }
62        }
63    };
64
65    {
    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(
66        include_str!(#up_sql_path),
67        #down_sql,
68        diesel_migrations::EmbeddedName::new(#name),
69        diesel_migrations::TomlMetadataWrapper::new(#run_in_transaction)
70    ))
71}