2 ast::{self, edit::AstNodeEdit},
6 use crate::{AssistContext, AssistId, AssistKind, Assists};
8 // Assist: unwrap_tuple
10 // Unwrap the tuple to different variables.
13 // # //- minicore: result
15 // $0let (foo, bar) = ("Foo", "Bar");
25 pub(crate) fn unwrap_tuple(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
26 let let_kw = ctx.find_token_syntax_at_offset(T![let])?;
27 let let_stmt = let_kw.parent().and_then(ast::LetStmt::cast)?;
28 let indent_level = let_stmt.indent_level().0 as usize;
29 let pat = let_stmt.pat()?;
30 let ty = let_stmt.ty();
31 let init = let_stmt.initializer()?;
33 // This only applies for tuple patterns, types, and initializers.
34 let tuple_pat = match pat {
35 ast::Pat::TuplePat(pat) => pat,
38 let tuple_ty = ty.and_then(|it| match it {
39 ast::Type::TupleType(ty) => Some(ty),
42 let tuple_init = match init {
43 ast::Expr::TupleExpr(expr) => expr,
47 if tuple_pat.fields().count() != tuple_init.fields().count() {
50 if let Some(tys) = &tuple_ty {
51 if tuple_pat.fields().count() != tys.fields().count() {
56 let parent = let_kw.parent()?;
59 AssistId("unwrap_tuple", AssistKind::RefactorRewrite),
63 let indents = " ".repeat(indent_level);
65 // If there is an ascribed type, insert that type for each declaration,
66 // otherwise, omit that type.
67 if let Some(tys) = tuple_ty {
68 let mut zipped_decls = String::new();
69 for (pat, ty, expr) in
70 itertools::izip!(tuple_pat.fields(), tys.fields(), tuple_init.fields())
72 zipped_decls.push_str(&format!("{indents}let {pat}: {ty} = {expr};\n"))
74 edit.replace(parent.text_range(), zipped_decls.trim());
76 let mut zipped_decls = String::new();
77 for (pat, expr) in itertools::izip!(tuple_pat.fields(), tuple_init.fields()) {
78 zipped_decls.push_str(&format!("{indents}let {pat} = {expr};\n"));
80 edit.replace(parent.text_range(), zipped_decls.trim());
88 use crate::tests::check_assist;
98 $0let (foo, bar) = ("Foo", "Bar");
113 $0let (foo, bar, baz) = ("Foo", "Bar", "Baz");
127 fn unwrap_tuple_with_types() {
132 $0let (foo, bar): (u8, i32) = (5, 10);
147 $0let (foo, bar, baz): (u8, i32, f64) = (5, 10, 17.5);