ide_assists/handlers/
move_from_mod_rs.rs1use ide_db::{assists::AssistId, base_db::AnchoredPathBuf};
2use syntax::{AstNode, ToSmolStr, ast};
3
4use crate::{
5 assist_context::{AssistContext, Assists},
6 utils::trimmed_text_range,
7};
8
9pub(crate) fn move_from_mod_rs(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
24 let source_file = ctx.find_node_at_offset::<ast::SourceFile>()?;
25 let module = ctx.sema.file_to_module_def(ctx.vfs_file_id())?;
26 let trimmed_selected_range = trimmed_text_range(&source_file, ctx.selection_trimmed());
28 let trimmed_file_range = trimmed_text_range(&source_file, source_file.syntax().text_range());
29 if !module.is_mod_rs(ctx.db()) {
30 cov_mark::hit!(not_mod_rs);
31 return None;
32 }
33 if trimmed_selected_range != trimmed_file_range {
34 cov_mark::hit!(not_all_selected);
35 return None;
36 }
37
38 let target = source_file.syntax().text_range();
39 let module_name = module.name(ctx.db())?.as_str().to_smolstr();
40 let path = format!("../{module_name}.rs");
41 let dst = AnchoredPathBuf { anchor: ctx.vfs_file_id(), path };
42 acc.add(
43 AssistId::refactor("move_from_mod_rs"),
44 format!("Convert {module_name}/mod.rs to {module_name}.rs"),
45 target,
46 |builder| {
47 builder.move_file(ctx.vfs_file_id(), dst);
48 },
49 )
50}
51
52#[cfg(test)]
53mod tests {
54 use crate::tests::{check_assist, check_assist_not_applicable};
55
56 use super::*;
57
58 #[test]
59 fn trivial() {
60 check_assist(
61 move_from_mod_rs,
62 r#"
63//- /main.rs
64mod a;
65//- /a/mod.rs
66$0fn t() {}
67$0"#,
68 r#"
69//- /a.rs
70fn t() {}
71"#,
72 );
73 }
74
75 #[test]
76 fn must_select_all_file() {
77 cov_mark::check!(not_all_selected);
78 check_assist_not_applicable(
79 move_from_mod_rs,
80 r#"
81//- /main.rs
82mod a;
83//- /a/mod.rs
84fn t() {}$0
85"#,
86 );
87 cov_mark::check!(not_all_selected);
88 check_assist_not_applicable(
89 move_from_mod_rs,
90 r#"
91//- /main.rs
92mod a;
93//- /a/mod.rs
94$0fn$0 t() {}
95"#,
96 );
97 }
98
99 #[test]
100 fn cannot_move_not_mod_rs() {
101 cov_mark::check!(not_mod_rs);
102 check_assist_not_applicable(
103 move_from_mod_rs,
104 r#"//- /main.rs
105mod a;
106//- /a.rs
107$0fn t() {}$0
108"#,
109 );
110 }
111
112 #[test]
113 fn cannot_downgrade_main_and_lib_rs() {
114 check_assist_not_applicable(
115 move_from_mod_rs,
116 r#"//- /main.rs
117$0fn t() {}$0
118"#,
119 );
120 check_assist_not_applicable(
121 move_from_mod_rs,
122 r#"//- /lib.rs
123$0fn t() {}$0
124"#,
125 );
126 }
127}