Replace SepBy with Itertools

This commit is contained in:
Aleksey Kladov 2020-08-12 15:04:06 +02:00
parent 42a1692629
commit 1c359ab634
7 changed files with 30 additions and 94 deletions

View file

@ -1,10 +1,10 @@
use itertools::Itertools;
use ra_syntax::{ use ra_syntax::{
ast::{self, AstNode}, ast::{self, AstNode},
Direction, SmolStr, Direction, SmolStr,
SyntaxKind::{IDENT, WHITESPACE}, SyntaxKind::{IDENT, WHITESPACE},
TextRange, TextSize, TextRange, TextSize,
}; };
use stdx::SepBy;
use crate::{ use crate::{
assist_context::{AssistContext, Assists}, assist_context::{AssistContext, Assists},
@ -61,9 +61,9 @@ pub(crate) fn add_custom_impl(acc: &mut Assists, ctx: &AssistContext) -> Option<
.filter(|t| t != trait_token.text()) .filter(|t| t != trait_token.text())
.collect::<Vec<SmolStr>>(); .collect::<Vec<SmolStr>>();
let has_more_derives = !new_attr_input.is_empty(); let has_more_derives = !new_attr_input.is_empty();
let new_attr_input = new_attr_input.iter().sep_by(", ").surround_with("(", ")").to_string();
if has_more_derives { if has_more_derives {
let new_attr_input = format!("({})", new_attr_input.iter().format(", "));
builder.replace(input.syntax().text_range(), new_attr_input); builder.replace(input.syntax().text_range(), new_attr_input);
} else { } else {
let attr_range = attr.syntax().text_range(); let attr_range = attr.syntax().text_range();

View file

@ -1,5 +1,6 @@
use itertools::Itertools;
use ra_syntax::ast::{self, AstNode, GenericParamsOwner, NameOwner}; use ra_syntax::ast::{self, AstNode, GenericParamsOwner, NameOwner};
use stdx::{format_to, SepBy}; use stdx::format_to;
use crate::{AssistContext, AssistId, AssistKind, Assists}; use crate::{AssistContext, AssistId, AssistKind, Assists};
@ -50,7 +51,7 @@ pub(crate) fn generate_impl(acc: &mut Assists, ctx: &AssistContext) -> Option<()
.filter_map(|it| it.name()) .filter_map(|it| it.name())
.map(|it| it.text().clone()); .map(|it| it.text().clone());
let generic_params = lifetime_params.chain(type_params).sep_by(", "); let generic_params = lifetime_params.chain(type_params).format(", ");
format_to!(buf, "<{}>", generic_params) format_to!(buf, "<{}>", generic_params)
} }
match ctx.config.snippet_cap { match ctx.config.snippet_cap {

View file

@ -1,9 +1,10 @@
use hir::Adt; use hir::Adt;
use itertools::Itertools;
use ra_syntax::{ use ra_syntax::{
ast::{self, AstNode, GenericParamsOwner, NameOwner, StructKind, VisibilityOwner}, ast::{self, AstNode, GenericParamsOwner, NameOwner, StructKind, VisibilityOwner},
T, T,
}; };
use stdx::{format_to, SepBy}; use stdx::format_to;
use crate::{AssistContext, AssistId, AssistKind, Assists}; use crate::{AssistContext, AssistId, AssistKind, Assists};
@ -52,8 +53,8 @@ pub(crate) fn generate_new(acc: &mut Assists, ctx: &AssistContext) -> Option<()>
let params = field_list let params = field_list
.fields() .fields()
.filter_map(|f| Some(format!("{}: {}", f.name()?.syntax(), f.ty()?.syntax()))) .filter_map(|f| Some(format!("{}: {}", f.name()?.syntax(), f.ty()?.syntax())))
.sep_by(", "); .format(", ");
let fields = field_list.fields().filter_map(|f| f.name()).sep_by(", "); let fields = field_list.fields().filter_map(|f| f.name()).format(", ");
format_to!(buf, " {}fn new({}) -> Self {{ Self {{ {} }} }}", vis, params, fields); format_to!(buf, " {}fn new({}) -> Self {{ Self {{ {} }} }}", vis, params, fields);
@ -102,7 +103,7 @@ fn generate_impl_text(strukt: &ast::Struct, code: &str) -> String {
.map(|it| it.text().clone()); .map(|it| it.text().clone());
let type_params = let type_params =
type_params.type_params().filter_map(|it| it.name()).map(|it| it.text().clone()); type_params.type_params().filter_map(|it| it.name()).map(|it| it.text().clone());
format_to!(buf, "<{}>", lifetime_params.chain(type_params).sep_by(", ")) format_to!(buf, "<{}>", lifetime_params.chain(type_params).format(", "))
} }
format_to!(buf, " {{\n{}\n}}\n", code); format_to!(buf, " {{\n{}\n}}\n", code);

View file

@ -2,8 +2,8 @@
//! It also handles scoring (sorting) completions. //! It also handles scoring (sorting) completions.
use hir::{Docs, HasAttrs, HasSource, HirDisplay, ModPath, ScopeDef, StructKind, Type}; use hir::{Docs, HasAttrs, HasSource, HirDisplay, ModPath, ScopeDef, StructKind, Type};
use itertools::Itertools;
use ra_syntax::ast::NameOwner; use ra_syntax::ast::NameOwner;
use stdx::SepBy;
use test_utils::mark; use test_utils::mark;
use crate::{ use crate::{
@ -289,16 +289,16 @@ impl Completions {
.map(|field| (field.name(ctx.db), field.signature_ty(ctx.db))); .map(|field| (field.name(ctx.db), field.signature_ty(ctx.db)));
let variant_kind = variant.kind(ctx.db); let variant_kind = variant.kind(ctx.db);
let detail = match variant_kind { let detail = match variant_kind {
StructKind::Tuple | StructKind::Unit => detail_types StructKind::Tuple | StructKind::Unit => format!(
.map(|(_, t)| t.display(ctx.db).to_string()) "({})",
.sep_by(", ") detail_types.map(|(_, t)| t.display(ctx.db).to_string()).format(", ")
.surround_with("(", ")") ),
.to_string(), StructKind::Record => format!(
StructKind::Record => detail_types "{{ {} }}",
.map(|(n, t)| format!("{}: {}", n, t.display(ctx.db).to_string())) detail_types
.sep_by(", ") .map(|(n, t)| format!("{}: {}", n, t.display(ctx.db).to_string()))
.surround_with("{ ", " }") .format(", ")
.to_string(), ),
}; };
let mut res = CompletionItem::new( let mut res = CompletionItem::new(
CompletionKind::Reference, CompletionKind::Reference,
@ -412,11 +412,10 @@ impl Builder {
self = self.trigger_call_info(); self = self.trigger_call_info();
let snippet = match (ctx.config.add_call_argument_snippets, params) { let snippet = match (ctx.config.add_call_argument_snippets, params) {
(true, Params::Named(params)) => { (true, Params::Named(params)) => {
let function_params_snippet = params let function_params_snippet =
.iter() params.iter().enumerate().format_with(", ", |(index, param_name), f| {
.enumerate() f(&format_args!("${{{}:{}}}", index + 1, param_name))
.map(|(index, param_name)| format!("${{{}:{}}}", index + 1, param_name)) });
.sep_by(", ");
format!("{}({})$0", name, function_params_snippet) format!("{}({})$0", name, function_params_snippet)
} }
_ => { _ => {

View file

@ -4,8 +4,8 @@ use std::{collections::BTreeMap, convert::TryFrom};
use ast::{HasQuotes, HasStringValue}; use ast::{HasQuotes, HasStringValue};
use hir::Semantics; use hir::Semantics;
use itertools::Itertools;
use ra_syntax::{ast, AstToken, SyntaxNode, SyntaxToken, TextRange, TextSize}; use ra_syntax::{ast, AstToken, SyntaxNode, SyntaxToken, TextRange, TextSize};
use stdx::SepBy;
use crate::{ use crate::{
call_info::ActiveParameter, Analysis, Highlight, HighlightModifier, HighlightTag, call_info::ActiveParameter, Analysis, Highlight, HighlightModifier, HighlightTag,
@ -129,8 +129,7 @@ pub(super) fn extract_doc_comments(
line[pos..].to_owned() line[pos..].to_owned()
}) })
.sep_by("\n") .join("\n");
.to_string();
if doctest.is_empty() { if doctest.is_empty() {
return None; return None;

View file

@ -1,7 +1,7 @@
//! Various traits that are implemented by ast nodes. //! Various traits that are implemented by ast nodes.
//! //!
//! The implementations are usually trivial, and live in generated.rs //! The implementations are usually trivial, and live in generated.rs
use stdx::SepBy; use itertools::Itertools;
use crate::{ use crate::{
ast::{self, support, AstChildren, AstNode, AstToken}, ast::{self, support, AstChildren, AstNode, AstToken},
@ -119,8 +119,7 @@ impl CommentIter {
// of a line in markdown. // of a line in markdown.
line[pos..end].to_owned() line[pos..end].to_owned()
}) })
.sep_by("\n") .join("\n");
.to_string();
if has_comments { if has_comments {
Some(docs) Some(docs)

View file

@ -1,5 +1,5 @@
//! Missing batteries for standard libraries. //! Missing batteries for standard libraries.
use std::{cell::Cell, fmt, time::Instant}; use std::time::Instant;
mod macros; mod macros;
@ -8,69 +8,6 @@ pub fn is_ci() -> bool {
option_env!("CI").is_some() option_env!("CI").is_some()
} }
pub trait SepBy: Sized {
/// Returns an `impl fmt::Display`, which joins elements via a separator.
fn sep_by(self, sep: &str) -> SepByBuilder<'_, Self>;
}
impl<I> SepBy for I
where
I: Iterator,
I::Item: fmt::Display,
{
fn sep_by(self, sep: &str) -> SepByBuilder<'_, Self> {
SepByBuilder::new(sep, self)
}
}
pub struct SepByBuilder<'a, I> {
sep: &'a str,
prefix: &'a str,
suffix: &'a str,
iter: Cell<Option<I>>,
}
impl<'a, I> SepByBuilder<'a, I> {
fn new(sep: &'a str, iter: I) -> SepByBuilder<'a, I> {
SepByBuilder { sep, prefix: "", suffix: "", iter: Cell::new(Some(iter)) }
}
pub fn prefix(mut self, prefix: &'a str) -> Self {
self.prefix = prefix;
self
}
pub fn suffix(mut self, suffix: &'a str) -> Self {
self.suffix = suffix;
self
}
/// Set both suffix and prefix.
pub fn surround_with(self, prefix: &'a str, suffix: &'a str) -> Self {
self.prefix(prefix).suffix(suffix)
}
}
impl<I> fmt::Display for SepByBuilder<'_, I>
where
I: Iterator,
I::Item: fmt::Display,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.prefix)?;
let mut first = true;
for item in self.iter.take().unwrap() {
if !first {
f.write_str(self.sep)?;
}
first = false;
fmt::Display::fmt(&item, f)?;
}
f.write_str(self.suffix)?;
Ok(())
}
}
#[must_use] #[must_use]
pub fn timeit(label: &'static str) -> impl Drop { pub fn timeit(label: &'static str) -> impl Drop {
struct Guard { struct Guard {