diff options
author | Aleksey Kladov <[email protected]> | 2020-03-28 10:01:25 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2020-03-28 10:01:25 +0000 |
commit | b764c38436fcb9426eb7da3be4f5fbcd63b316f5 (patch) | |
tree | a599f1ffff953040a0c2bb635b33b0f6a57e5e59 /crates | |
parent | a1fea0d34ee8f3436aefd87d4c133a7ff50ffbb0 (diff) |
Start stdx
This crate will hold everything to small to be worth publishing
Diffstat (limited to 'crates')
-rw-r--r-- | crates/ra_assists/Cargo.toml | 4 | ||||
-rw-r--r-- | crates/ra_assists/src/handlers/add_custom_impl.rs | 14 | ||||
-rw-r--r-- | crates/ra_assists/src/handlers/add_impl.rs | 9 | ||||
-rw-r--r-- | crates/ra_assists/src/handlers/add_new.rs | 39 | ||||
-rw-r--r-- | crates/ra_assists/src/handlers/introduce_variable.rs | 4 | ||||
-rw-r--r-- | crates/ra_ide/Cargo.toml | 4 | ||||
-rw-r--r-- | crates/ra_ide/src/completion/presentation.rs | 45 | ||||
-rw-r--r-- | crates/ra_ide/src/diagnostics.rs | 18 | ||||
-rw-r--r-- | crates/ra_ide/src/display/function_signature.rs | 18 | ||||
-rw-r--r-- | crates/ra_ide/src/display/short_label.rs | 4 | ||||
-rw-r--r-- | crates/stdx/Cargo.toml | 11 | ||||
-rw-r--r-- | crates/stdx/src/lib.rs | 75 |
12 files changed, 157 insertions, 88 deletions
diff --git a/crates/ra_assists/Cargo.toml b/crates/ra_assists/Cargo.toml index a87f4052a..3bcf58ba4 100644 --- a/crates/ra_assists/Cargo.toml +++ b/crates/ra_assists/Cargo.toml | |||
@@ -8,12 +8,12 @@ authors = ["rust-analyzer developers"] | |||
8 | doctest = false | 8 | doctest = false |
9 | 9 | ||
10 | [dependencies] | 10 | [dependencies] |
11 | format-buf = "1.0.0" | ||
12 | join_to_string = "0.1.3" | ||
13 | rustc-hash = "1.1.0" | 11 | rustc-hash = "1.1.0" |
14 | itertools = "0.9.0" | 12 | itertools = "0.9.0" |
15 | either = "1.5.3" | 13 | either = "1.5.3" |
16 | 14 | ||
15 | stdx = { path = "../stdx" } | ||
16 | |||
17 | ra_syntax = { path = "../ra_syntax" } | 17 | ra_syntax = { path = "../ra_syntax" } |
18 | ra_text_edit = { path = "../ra_text_edit" } | 18 | ra_text_edit = { path = "../ra_text_edit" } |
19 | ra_fmt = { path = "../ra_fmt" } | 19 | ra_fmt = { path = "../ra_fmt" } |
diff --git a/crates/ra_assists/src/handlers/add_custom_impl.rs b/crates/ra_assists/src/handlers/add_custom_impl.rs index dd2bed25a..15f9b216b 100644 --- a/crates/ra_assists/src/handlers/add_custom_impl.rs +++ b/crates/ra_assists/src/handlers/add_custom_impl.rs | |||
@@ -1,17 +1,13 @@ | |||
1 | //! FIXME: write short doc here | ||
2 | |||
3 | use join_to_string::join; | ||
4 | use ra_syntax::{ | 1 | use ra_syntax::{ |
5 | ast::{self, AstNode}, | 2 | ast::{self, AstNode}, |
6 | Direction, SmolStr, | 3 | Direction, SmolStr, |
7 | SyntaxKind::{IDENT, WHITESPACE}, | 4 | SyntaxKind::{IDENT, WHITESPACE}, |
8 | TextRange, TextUnit, | 5 | TextRange, TextUnit, |
9 | }; | 6 | }; |
7 | use stdx::SepBy; | ||
10 | 8 | ||
11 | use crate::{Assist, AssistCtx, AssistId}; | 9 | use crate::{Assist, AssistCtx, AssistId}; |
12 | 10 | ||
13 | const DERIVE_TRAIT: &str = "derive"; | ||
14 | |||
15 | // Assist: add_custom_impl | 11 | // Assist: add_custom_impl |
16 | // | 12 | // |
17 | // Adds impl block for derived trait. | 13 | // Adds impl block for derived trait. |
@@ -38,7 +34,7 @@ pub(crate) fn add_custom_impl(ctx: AssistCtx) -> Option<Assist> { | |||
38 | .descendants_with_tokens() | 34 | .descendants_with_tokens() |
39 | .filter(|t| t.kind() == IDENT) | 35 | .filter(|t| t.kind() == IDENT) |
40 | .find_map(|i| i.into_token()) | 36 | .find_map(|i| i.into_token()) |
41 | .filter(|t| *t.text() == DERIVE_TRAIT)? | 37 | .filter(|t| *t.text() == "derive")? |
42 | .text() | 38 | .text() |
43 | .clone(); | 39 | .clone(); |
44 | 40 | ||
@@ -63,8 +59,7 @@ pub(crate) fn add_custom_impl(ctx: AssistCtx) -> Option<Assist> { | |||
63 | .filter(|t| t != trait_token.text()) | 59 | .filter(|t| t != trait_token.text()) |
64 | .collect::<Vec<SmolStr>>(); | 60 | .collect::<Vec<SmolStr>>(); |
65 | let has_more_derives = !new_attr_input.is_empty(); | 61 | let has_more_derives = !new_attr_input.is_empty(); |
66 | let new_attr_input = | 62 | let new_attr_input = new_attr_input.iter().sep_by(", ").surround_with("(", ")").to_string(); |
67 | join(new_attr_input.iter()).separator(", ").surround_with("(", ")").to_string(); | ||
68 | let new_attr_input_len = new_attr_input.len(); | 63 | let new_attr_input_len = new_attr_input.len(); |
69 | 64 | ||
70 | let mut buf = String::new(); | 65 | let mut buf = String::new(); |
@@ -100,9 +95,10 @@ pub(crate) fn add_custom_impl(ctx: AssistCtx) -> Option<Assist> { | |||
100 | 95 | ||
101 | #[cfg(test)] | 96 | #[cfg(test)] |
102 | mod tests { | 97 | mod tests { |
103 | use super::*; | ||
104 | use crate::helpers::{check_assist, check_assist_not_applicable}; | 98 | use crate::helpers::{check_assist, check_assist_not_applicable}; |
105 | 99 | ||
100 | use super::*; | ||
101 | |||
106 | #[test] | 102 | #[test] |
107 | fn add_custom_impl_for_unique_input() { | 103 | fn add_custom_impl_for_unique_input() { |
108 | check_assist( | 104 | check_assist( |
diff --git a/crates/ra_assists/src/handlers/add_impl.rs b/crates/ra_assists/src/handlers/add_impl.rs index afae7d385..6622eadb2 100644 --- a/crates/ra_assists/src/handlers/add_impl.rs +++ b/crates/ra_assists/src/handlers/add_impl.rs | |||
@@ -1,9 +1,8 @@ | |||
1 | use format_buf::format; | ||
2 | use join_to_string::join; | ||
3 | use ra_syntax::{ | 1 | use ra_syntax::{ |
4 | ast::{self, AstNode, NameOwner, TypeParamsOwner}, | 2 | ast::{self, AstNode, NameOwner, TypeParamsOwner}, |
5 | TextUnit, | 3 | TextUnit, |
6 | }; | 4 | }; |
5 | use stdx::{format_to, SepBy}; | ||
7 | 6 | ||
8 | use crate::{Assist, AssistCtx, AssistId}; | 7 | use crate::{Assist, AssistCtx, AssistId}; |
9 | 8 | ||
@@ -36,7 +35,7 @@ pub(crate) fn add_impl(ctx: AssistCtx) -> Option<Assist> { | |||
36 | let mut buf = String::new(); | 35 | let mut buf = String::new(); |
37 | buf.push_str("\n\nimpl"); | 36 | buf.push_str("\n\nimpl"); |
38 | if let Some(type_params) = &type_params { | 37 | if let Some(type_params) = &type_params { |
39 | format!(buf, "{}", type_params.syntax()); | 38 | format_to!(buf, "{}", type_params.syntax()); |
40 | } | 39 | } |
41 | buf.push_str(" "); | 40 | buf.push_str(" "); |
42 | buf.push_str(name.text().as_str()); | 41 | buf.push_str(name.text().as_str()); |
@@ -47,7 +46,9 @@ pub(crate) fn add_impl(ctx: AssistCtx) -> Option<Assist> { | |||
47 | .map(|it| it.text().clone()); | 46 | .map(|it| it.text().clone()); |
48 | let type_params = | 47 | let type_params = |
49 | type_params.type_params().filter_map(|it| it.name()).map(|it| it.text().clone()); | 48 | type_params.type_params().filter_map(|it| it.name()).map(|it| it.text().clone()); |
50 | join(lifetime_params.chain(type_params)).surround_with("<", ">").to_buf(&mut buf); | 49 | |
50 | let generic_params = lifetime_params.chain(type_params).sep_by(", "); | ||
51 | format_to!(buf, "<{}>", generic_params) | ||
51 | } | 52 | } |
52 | buf.push_str(" {\n"); | 53 | buf.push_str(" {\n"); |
53 | edit.set_cursor(start_offset + TextUnit::of_str(&buf)); | 54 | edit.set_cursor(start_offset + TextUnit::of_str(&buf)); |
diff --git a/crates/ra_assists/src/handlers/add_new.rs b/crates/ra_assists/src/handlers/add_new.rs index 729a223e0..240b19fa3 100644 --- a/crates/ra_assists/src/handlers/add_new.rs +++ b/crates/ra_assists/src/handlers/add_new.rs | |||
@@ -1,14 +1,11 @@ | |||
1 | use std::fmt::Write; | ||
2 | |||
3 | use format_buf::format; | ||
4 | use hir::Adt; | 1 | use hir::Adt; |
5 | use join_to_string::join; | ||
6 | use ra_syntax::{ | 2 | use ra_syntax::{ |
7 | ast::{ | 3 | ast::{ |
8 | self, AstNode, NameOwner, StructKind, TypeAscriptionOwner, TypeParamsOwner, VisibilityOwner, | 4 | self, AstNode, NameOwner, StructKind, TypeAscriptionOwner, TypeParamsOwner, VisibilityOwner, |
9 | }, | 5 | }, |
10 | TextUnit, T, | 6 | TextUnit, T, |
11 | }; | 7 | }; |
8 | use stdx::{format_to, SepBy}; | ||
12 | 9 | ||
13 | use crate::{Assist, AssistCtx, AssistId}; | 10 | use crate::{Assist, AssistCtx, AssistId}; |
14 | 11 | ||
@@ -53,24 +50,22 @@ pub(crate) fn add_new(ctx: AssistCtx) -> Option<Assist> { | |||
53 | buf.push('\n'); | 50 | buf.push('\n'); |
54 | } | 51 | } |
55 | 52 | ||
56 | let vis = strukt.visibility().map(|v| format!("{} ", v.syntax())); | 53 | let vis = strukt.visibility().map(|v| format!("{} ", v)); |
57 | let vis = vis.as_deref().unwrap_or(""); | 54 | let vis = vis.as_deref().unwrap_or(""); |
58 | write!(&mut buf, " {}fn new(", vis).unwrap(); | ||
59 | |||
60 | join(field_list.fields().filter_map(|f| { | ||
61 | Some(format!("{}: {}", f.name()?.syntax().text(), f.ascribed_type()?.syntax().text())) | ||
62 | })) | ||
63 | .separator(", ") | ||
64 | .to_buf(&mut buf); | ||
65 | 55 | ||
66 | buf.push_str(") -> Self { Self {"); | 56 | let params = field_list |
67 | 57 | .fields() | |
68 | join(field_list.fields().filter_map(|f| Some(f.name()?.syntax().text()))) | 58 | .filter_map(|f| { |
69 | .separator(", ") | 59 | Some(format!( |
70 | .surround_with(" ", " ") | 60 | "{}: {}", |
71 | .to_buf(&mut buf); | 61 | f.name()?.syntax().text(), |
62 | f.ascribed_type()?.syntax().text() | ||
63 | )) | ||
64 | }) | ||
65 | .sep_by(", "); | ||
66 | let fields = field_list.fields().filter_map(|f| f.name()).sep_by(", "); | ||
72 | 67 | ||
73 | buf.push_str("} }"); | 68 | format_to!(buf, " {}fn new({}) -> Self {{ Self {{ {} }} }}", vis, params, fields); |
74 | 69 | ||
75 | let (start_offset, end_offset) = impl_def | 70 | let (start_offset, end_offset) = impl_def |
76 | .and_then(|impl_def| { | 71 | .and_then(|impl_def| { |
@@ -103,7 +98,7 @@ fn generate_impl_text(strukt: &ast::StructDef, code: &str) -> String { | |||
103 | let mut buf = String::with_capacity(code.len()); | 98 | let mut buf = String::with_capacity(code.len()); |
104 | buf.push_str("\n\nimpl"); | 99 | buf.push_str("\n\nimpl"); |
105 | if let Some(type_params) = &type_params { | 100 | if let Some(type_params) = &type_params { |
106 | format!(buf, "{}", type_params.syntax()); | 101 | format_to!(buf, "{}", type_params.syntax()); |
107 | } | 102 | } |
108 | buf.push_str(" "); | 103 | buf.push_str(" "); |
109 | buf.push_str(strukt.name().unwrap().text().as_str()); | 104 | buf.push_str(strukt.name().unwrap().text().as_str()); |
@@ -114,10 +109,10 @@ fn generate_impl_text(strukt: &ast::StructDef, code: &str) -> String { | |||
114 | .map(|it| it.text().clone()); | 109 | .map(|it| it.text().clone()); |
115 | let type_params = | 110 | let type_params = |
116 | type_params.type_params().filter_map(|it| it.name()).map(|it| it.text().clone()); | 111 | type_params.type_params().filter_map(|it| it.name()).map(|it| it.text().clone()); |
117 | join(lifetime_params.chain(type_params)).surround_with("<", ">").to_buf(&mut buf); | 112 | format_to!(buf, "<{}>", lifetime_params.chain(type_params).sep_by(", ")) |
118 | } | 113 | } |
119 | 114 | ||
120 | format!(&mut buf, " {{\n{}\n}}\n", code); | 115 | format_to!(buf, " {{\n{}\n}}\n", code); |
121 | 116 | ||
122 | buf | 117 | buf |
123 | } | 118 | } |
diff --git a/crates/ra_assists/src/handlers/introduce_variable.rs b/crates/ra_assists/src/handlers/introduce_variable.rs index b453c51fb..1edbdc14c 100644 --- a/crates/ra_assists/src/handlers/introduce_variable.rs +++ b/crates/ra_assists/src/handlers/introduce_variable.rs | |||
@@ -1,4 +1,3 @@ | |||
1 | use format_buf::format; | ||
2 | use ra_syntax::{ | 1 | use ra_syntax::{ |
3 | ast::{self, AstNode}, | 2 | ast::{self, AstNode}, |
4 | SyntaxKind::{ | 3 | SyntaxKind::{ |
@@ -7,6 +6,7 @@ use ra_syntax::{ | |||
7 | }, | 6 | }, |
8 | SyntaxNode, TextUnit, | 7 | SyntaxNode, TextUnit, |
9 | }; | 8 | }; |
9 | use stdx::format_to; | ||
10 | use test_utils::tested_by; | 10 | use test_utils::tested_by; |
11 | 11 | ||
12 | use crate::{Assist, AssistCtx, AssistId}; | 12 | use crate::{Assist, AssistCtx, AssistId}; |
@@ -52,7 +52,7 @@ pub(crate) fn introduce_variable(ctx: AssistCtx) -> Option<Assist> { | |||
52 | buf.push_str("let var_name = "); | 52 | buf.push_str("let var_name = "); |
53 | TextUnit::of_str("let ") | 53 | TextUnit::of_str("let ") |
54 | }; | 54 | }; |
55 | format!(buf, "{}", expr.syntax()); | 55 | format_to!(buf, "{}", expr.syntax()); |
56 | let full_stmt = ast::ExprStmt::cast(anchor_stmt.clone()); | 56 | let full_stmt = ast::ExprStmt::cast(anchor_stmt.clone()); |
57 | let is_full_stmt = if let Some(expr_stmt) = &full_stmt { | 57 | let is_full_stmt = if let Some(expr_stmt) = &full_stmt { |
58 | Some(expr.syntax().clone()) == expr_stmt.expr().map(|e| e.syntax().clone()) | 58 | Some(expr.syntax().clone()) == expr_stmt.expr().map(|e| e.syntax().clone()) |
diff --git a/crates/ra_ide/Cargo.toml b/crates/ra_ide/Cargo.toml index 36eec0e60..b4a29b81b 100644 --- a/crates/ra_ide/Cargo.toml +++ b/crates/ra_ide/Cargo.toml | |||
@@ -12,14 +12,14 @@ wasm = [] | |||
12 | 12 | ||
13 | [dependencies] | 13 | [dependencies] |
14 | either = "1.5.3" | 14 | either = "1.5.3" |
15 | format-buf = "1.0.0" | ||
16 | indexmap = "1.3.2" | 15 | indexmap = "1.3.2" |
17 | itertools = "0.9.0" | 16 | itertools = "0.9.0" |
18 | join_to_string = "0.1.3" | ||
19 | log = "0.4.8" | 17 | log = "0.4.8" |
20 | rustc-hash = "1.1.0" | 18 | rustc-hash = "1.1.0" |
21 | rand = { version = "0.7.3", features = ["small_rng"] } | 19 | rand = { version = "0.7.3", features = ["small_rng"] } |
22 | 20 | ||
21 | stdx = { path = "../stdx" } | ||
22 | |||
23 | ra_syntax = { path = "../ra_syntax" } | 23 | ra_syntax = { path = "../ra_syntax" } |
24 | ra_text_edit = { path = "../ra_text_edit" } | 24 | ra_text_edit = { path = "../ra_text_edit" } |
25 | ra_db = { path = "../ra_db" } | 25 | ra_db = { path = "../ra_db" } |
diff --git a/crates/ra_ide/src/completion/presentation.rs b/crates/ra_ide/src/completion/presentation.rs index 253848602..60f1b83f3 100644 --- a/crates/ra_ide/src/completion/presentation.rs +++ b/crates/ra_ide/src/completion/presentation.rs | |||
@@ -1,15 +1,14 @@ | |||
1 | //! This modules takes care of rendering various definitions as completion items. | 1 | //! This modules takes care of rendering various definitions as completion items. |
2 | 2 | ||
3 | use hir::{Docs, HasAttrs, HasSource, HirDisplay, ScopeDef, StructKind, Type}; | 3 | use hir::{Docs, HasAttrs, HasSource, HirDisplay, ScopeDef, StructKind, Type}; |
4 | use join_to_string::join; | ||
5 | use ra_syntax::ast::NameOwner; | 4 | use ra_syntax::ast::NameOwner; |
5 | use stdx::SepBy; | ||
6 | use test_utils::tested_by; | 6 | use test_utils::tested_by; |
7 | 7 | ||
8 | use crate::completion::{ | ||
9 | CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, Completions, | ||
10 | }; | ||
11 | |||
12 | use crate::{ | 8 | use crate::{ |
9 | completion::{ | ||
10 | CompletionContext, CompletionItem, CompletionItemKind, CompletionKind, Completions, | ||
11 | }, | ||
13 | display::{const_label, macro_label, type_label, FunctionSignature}, | 12 | display::{const_label, macro_label, type_label, FunctionSignature}, |
14 | RootDatabase, | 13 | RootDatabase, |
15 | }; | 14 | }; |
@@ -221,13 +220,13 @@ impl Completions { | |||
221 | builder = builder.trigger_call_info(); | 220 | builder = builder.trigger_call_info(); |
222 | let snippet = if ctx.options.add_call_argument_snippets { | 221 | let snippet = if ctx.options.add_call_argument_snippets { |
223 | let to_skip = if has_self_param { 1 } else { 0 }; | 222 | let to_skip = if has_self_param { 1 } else { 0 }; |
224 | let function_params_snippet = join( | 223 | let function_params_snippet = function_signature |
225 | function_signature.parameter_names.iter().skip(to_skip).enumerate().map( | 224 | .parameter_names |
226 | |(index, param_name)| format!("${{{}:{}}}", index + 1, param_name), | 225 | .iter() |
227 | ), | 226 | .skip(to_skip) |
228 | ) | 227 | .enumerate() |
229 | .separator(", ") | 228 | .map(|(index, param_name)| format!("${{{}:{}}}", index + 1, param_name)) |
230 | .to_string(); | 229 | .sep_by(", "); |
231 | format!("{}({})$0", name, function_params_snippet) | 230 | format!("{}({})$0", name, function_params_snippet) |
232 | } else { | 231 | } else { |
233 | format!("{}($0)", name) | 232 | format!("{}($0)", name) |
@@ -281,18 +280,16 @@ impl Completions { | |||
281 | .into_iter() | 280 | .into_iter() |
282 | .map(|field| (field.name(ctx.db), field.signature_ty(ctx.db))); | 281 | .map(|field| (field.name(ctx.db), field.signature_ty(ctx.db))); |
283 | let detail = match variant.kind(ctx.db) { | 282 | let detail = match variant.kind(ctx.db) { |
284 | StructKind::Tuple | StructKind::Unit => { | 283 | StructKind::Tuple | StructKind::Unit => detail_types |
285 | join(detail_types.map(|(_, t)| t.display(ctx.db).to_string())) | 284 | .map(|(_, t)| t.display(ctx.db).to_string()) |
286 | .separator(", ") | 285 | .sep_by(", ") |
287 | .surround_with("(", ")") | 286 | .surround_with("(", ")") |
288 | .to_string() | 287 | .to_string(), |
289 | } | 288 | StructKind::Record => detail_types |
290 | StructKind::Record => { | 289 | .map(|(n, t)| format!("{}: {}", n, t.display(ctx.db).to_string())) |
291 | join(detail_types.map(|(n, t)| format!("{}: {}", n, t.display(ctx.db).to_string()))) | 290 | .sep_by(", ") |
292 | .separator(", ") | 291 | .surround_with("{ ", " }") |
293 | .surround_with("{ ", " }") | 292 | .to_string(), |
294 | .to_string() | ||
295 | } | ||
296 | }; | 293 | }; |
297 | CompletionItem::new(CompletionKind::Reference, ctx.source_range(), name.to_string()) | 294 | CompletionItem::new(CompletionKind::Reference, ctx.source_range(), name.to_string()) |
298 | .kind(CompletionItemKind::EnumVariant) | 295 | .kind(CompletionItemKind::EnumVariant) |
diff --git a/crates/ra_ide/src/diagnostics.rs b/crates/ra_ide/src/diagnostics.rs index a10e642db..c1d7ddaf2 100644 --- a/crates/ra_ide/src/diagnostics.rs +++ b/crates/ra_ide/src/diagnostics.rs | |||
@@ -200,8 +200,8 @@ fn check_struct_shorthand_initialization( | |||
200 | #[cfg(test)] | 200 | #[cfg(test)] |
201 | mod tests { | 201 | mod tests { |
202 | use insta::assert_debug_snapshot; | 202 | use insta::assert_debug_snapshot; |
203 | use join_to_string::join; | ||
204 | use ra_syntax::SourceFile; | 203 | use ra_syntax::SourceFile; |
204 | use stdx::SepBy; | ||
205 | use test_utils::assert_eq_text; | 205 | use test_utils::assert_eq_text; |
206 | 206 | ||
207 | use crate::mock_analysis::{analysis_and_position, single_file}; | 207 | use crate::mock_analysis::{analysis_and_position, single_file}; |
@@ -254,16 +254,12 @@ mod tests { | |||
254 | .map(|it| it.len() - it.trim_start().len()) | 254 | .map(|it| it.len() - it.trim_start().len()) |
255 | .next() | 255 | .next() |
256 | .expect("empty fixture"); | 256 | .expect("empty fixture"); |
257 | let after = join(after.lines().filter_map(|line| { | 257 | let after = after |
258 | if line.len() > margin { | 258 | .lines() |
259 | Some(&line[margin..]) | 259 | .filter_map(|line| if line.len() > margin { Some(&line[margin..]) } else { None }) |
260 | } else { | 260 | .sep_by("\n") |
261 | None | 261 | .suffix("\n") |
262 | } | 262 | .to_string(); |
263 | })) | ||
264 | .separator("\n") | ||
265 | .suffix("\n") | ||
266 | .to_string(); | ||
267 | 263 | ||
268 | assert_eq_text!(&after, &actual); | 264 | assert_eq_text!(&after, &actual); |
269 | assert!( | 265 | assert!( |
diff --git a/crates/ra_ide/src/display/function_signature.rs b/crates/ra_ide/src/display/function_signature.rs index ec1bbd5a0..b967a6816 100644 --- a/crates/ra_ide/src/display/function_signature.rs +++ b/crates/ra_ide/src/display/function_signature.rs | |||
@@ -1,12 +1,14 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use std::fmt::{self, Display}; | 3 | use std::{ |
4 | convert::From, | ||
5 | fmt::{self, Display}, | ||
6 | }; | ||
4 | 7 | ||
5 | use hir::{Docs, Documentation, HasSource, HirDisplay}; | 8 | use hir::{Docs, Documentation, HasSource, HirDisplay}; |
6 | use join_to_string::join; | ||
7 | use ra_ide_db::RootDatabase; | 9 | use ra_ide_db::RootDatabase; |
8 | use ra_syntax::ast::{self, AstNode, NameOwner, VisibilityOwner}; | 10 | use ra_syntax::ast::{self, AstNode, NameOwner, VisibilityOwner}; |
9 | use std::convert::From; | 11 | use stdx::SepBy; |
10 | 12 | ||
11 | use crate::display::{generic_parameters, where_predicates}; | 13 | use crate::display::{generic_parameters, where_predicates}; |
12 | 14 | ||
@@ -227,21 +229,17 @@ impl Display for FunctionSignature { | |||
227 | } | 229 | } |
228 | 230 | ||
229 | if !self.generic_parameters.is_empty() { | 231 | if !self.generic_parameters.is_empty() { |
230 | join(self.generic_parameters.iter()) | 232 | write!(f, "{}", self.generic_parameters.iter().sep_by(", ").surround_with("<", ">"))?; |
231 | .separator(", ") | ||
232 | .surround_with("<", ">") | ||
233 | .to_fmt(f)?; | ||
234 | } | 233 | } |
235 | 234 | ||
236 | join(self.parameters.iter()).separator(", ").surround_with("(", ")").to_fmt(f)?; | 235 | write!(f, "{}", self.parameters.iter().sep_by(", ").surround_with("(", ")"))?; |
237 | 236 | ||
238 | if let Some(t) = &self.ret_type { | 237 | if let Some(t) = &self.ret_type { |
239 | write!(f, " -> {}", t)?; | 238 | write!(f, " -> {}", t)?; |
240 | } | 239 | } |
241 | 240 | ||
242 | if !self.where_predicates.is_empty() { | 241 | if !self.where_predicates.is_empty() { |
243 | write!(f, "\nwhere ")?; | 242 | write!(f, "\nwhere {}", self.where_predicates.iter().sep_by(",\n "))?; |
244 | join(self.where_predicates.iter()).separator(",\n ").to_fmt(f)?; | ||
245 | } | 243 | } |
246 | 244 | ||
247 | Ok(()) | 245 | Ok(()) |
diff --git a/crates/ra_ide/src/display/short_label.rs b/crates/ra_ide/src/display/short_label.rs index 9ffc9b980..4b081bf6c 100644 --- a/crates/ra_ide/src/display/short_label.rs +++ b/crates/ra_ide/src/display/short_label.rs | |||
@@ -1,7 +1,7 @@ | |||
1 | //! FIXME: write short doc here | 1 | //! FIXME: write short doc here |
2 | 2 | ||
3 | use format_buf::format; | ||
4 | use ra_syntax::ast::{self, AstNode, NameOwner, TypeAscriptionOwner, VisibilityOwner}; | 3 | use ra_syntax::ast::{self, AstNode, NameOwner, TypeAscriptionOwner, VisibilityOwner}; |
4 | use stdx::format_to; | ||
5 | 5 | ||
6 | pub(crate) trait ShortLabel { | 6 | pub(crate) trait ShortLabel { |
7 | fn short_label(&self) -> Option<String>; | 7 | fn short_label(&self) -> Option<String>; |
@@ -80,7 +80,7 @@ where | |||
80 | let mut buf = short_label_from_node(node, prefix)?; | 80 | let mut buf = short_label_from_node(node, prefix)?; |
81 | 81 | ||
82 | if let Some(type_ref) = node.ascribed_type() { | 82 | if let Some(type_ref) = node.ascribed_type() { |
83 | format!(buf, ": {}", type_ref.syntax()); | 83 | format_to!(buf, ": {}", type_ref.syntax()); |
84 | } | 84 | } |
85 | 85 | ||
86 | Some(buf) | 86 | Some(buf) |
diff --git a/crates/stdx/Cargo.toml b/crates/stdx/Cargo.toml new file mode 100644 index 000000000..f9e380c10 --- /dev/null +++ b/crates/stdx/Cargo.toml | |||
@@ -0,0 +1,11 @@ | |||
1 | [package] | ||
2 | name = "stdx" | ||
3 | version = "0.1.0" | ||
4 | authors = ["rust-analyzer developers"] | ||
5 | edition = "2018" | ||
6 | |||
7 | [lib] | ||
8 | doctest = false | ||
9 | |||
10 | [dependencies] | ||
11 | # Think twice before adding anything here | ||
diff --git a/crates/stdx/src/lib.rs b/crates/stdx/src/lib.rs new file mode 100644 index 000000000..a01ca6d4d --- /dev/null +++ b/crates/stdx/src/lib.rs | |||
@@ -0,0 +1,75 @@ | |||
1 | //! Missing batteries for standard libraries. | ||
2 | |||
3 | use std::{cell::Cell, fmt}; | ||
4 | |||
5 | /// Appends formatted string to a `String`. | ||
6 | #[macro_export] | ||
7 | macro_rules! format_to { | ||
8 | (&buf:expr) => (); | ||
9 | ($buf:expr, $lit:literal $($arg:tt)*) => { | ||
10 | { use ::std::fmt::Write as _; let _ = ::std::write!($buf, $lit $($arg)*); } | ||
11 | }; | ||
12 | } | ||
13 | |||
14 | pub trait SepBy: Sized { | ||
15 | /// Returns an `impl fmt::Display`, which joins elements via a separator. | ||
16 | fn sep_by<'a>(self, sep: &'a str) -> SepByBuilder<'a, Self>; | ||
17 | } | ||
18 | |||
19 | impl<I> SepBy for I | ||
20 | where | ||
21 | I: Iterator, | ||
22 | I::Item: fmt::Display, | ||
23 | { | ||
24 | fn sep_by<'a>(self, sep: &'a std::primitive::str) -> SepByBuilder<'a, Self> { | ||
25 | SepByBuilder::new(sep, self) | ||
26 | } | ||
27 | } | ||
28 | |||
29 | pub struct SepByBuilder<'a, I> { | ||
30 | sep: &'a str, | ||
31 | prefix: &'a str, | ||
32 | suffix: &'a str, | ||
33 | iter: Cell<Option<I>>, | ||
34 | } | ||
35 | |||
36 | impl<'a, I> SepByBuilder<'a, I> { | ||
37 | fn new(sep: &'a str, iter: I) -> SepByBuilder<'a, I> { | ||
38 | SepByBuilder { sep, prefix: "", suffix: "", iter: Cell::new(Some(iter)) } | ||
39 | } | ||
40 | |||
41 | pub fn prefix(mut self, prefix: &'a str) -> Self { | ||
42 | self.prefix = prefix; | ||
43 | self | ||
44 | } | ||
45 | |||
46 | pub fn suffix(mut self, suffix: &'a str) -> Self { | ||
47 | self.suffix = suffix; | ||
48 | self | ||
49 | } | ||
50 | |||
51 | /// Set both suffix and prefix. | ||
52 | pub fn surround_with(self, prefix: &'a str, suffix: &'a str) -> Self { | ||
53 | self.prefix(prefix).suffix(suffix) | ||
54 | } | ||
55 | } | ||
56 | |||
57 | impl<I> fmt::Display for SepByBuilder<'_, I> | ||
58 | where | ||
59 | I: Iterator, | ||
60 | I::Item: fmt::Display, | ||
61 | { | ||
62 | fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
63 | f.write_str(self.prefix)?; | ||
64 | let mut first = true; | ||
65 | for item in self.iter.take().unwrap() { | ||
66 | if !first { | ||
67 | f.write_str(self.sep)?; | ||
68 | } | ||
69 | first = false; | ||
70 | fmt::Display::fmt(&item, f)?; | ||
71 | } | ||
72 | f.write_str(self.suffix)?; | ||
73 | Ok(()) | ||
74 | } | ||
75 | } | ||