From be49547b446cba240f8f2a9592284e77d4a6896f Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 30 Jul 2020 22:19:58 +0200 Subject: Use split_once polyfill --- crates/ra_project_model/src/cfg_flag.rs | 4 ++-- crates/rust-analyzer/src/cli/analysis_bench.rs | 21 ++++++++++----------- crates/rust-analyzer/src/handlers.rs | 4 ++-- crates/stdx/src/lib.rs | 15 ++++++++++++--- crates/test_utils/src/fixture.rs | 8 ++++---- 5 files changed, 30 insertions(+), 22 deletions(-) diff --git a/crates/ra_project_model/src/cfg_flag.rs b/crates/ra_project_model/src/cfg_flag.rs index 1bc5d4832..bd50056c6 100644 --- a/crates/ra_project_model/src/cfg_flag.rs +++ b/crates/ra_project_model/src/cfg_flag.rs @@ -4,7 +4,7 @@ use std::str::FromStr; use ra_cfg::CfgOptions; -use stdx::split_delim; +use stdx::split_once; #[derive(Clone, Eq, PartialEq, Debug)] pub enum CfgFlag { @@ -15,7 +15,7 @@ pub enum CfgFlag { impl FromStr for CfgFlag { type Err = String; fn from_str(s: &str) -> Result { - let res = match split_delim(s, '=') { + let res = match split_once(s, '=') { Some((key, value)) => { if !(value.starts_with('"') && value.ends_with('"')) { return Err(format!("Invalid cfg ({:?}), value should be in quotes", s)); diff --git a/crates/rust-analyzer/src/cli/analysis_bench.rs b/crates/rust-analyzer/src/cli/analysis_bench.rs index 076184ad6..13a106638 100644 --- a/crates/rust-analyzer/src/cli/analysis_bench.rs +++ b/crates/rust-analyzer/src/cli/analysis_bench.rs @@ -2,7 +2,7 @@ use std::{env, path::Path, str::FromStr, sync::Arc, time::Instant}; -use anyhow::{format_err, Result}; +use anyhow::{bail, format_err, Result}; use ra_db::{ salsa::{Database, Durability}, FileId, @@ -30,19 +30,18 @@ pub struct Position { impl FromStr for Position { type Err = anyhow::Error; fn from_str(s: &str) -> Result { - let (path_line, column) = rsplit_at_char(s, ':')?; - let (path, line) = rsplit_at_char(path_line, ':')?; - let path = env::current_dir().unwrap().join(path); - let path = AbsPathBuf::assert(path); - Ok(Position { path, line: line.parse()?, column: column.parse()? }) + let mut split = s.rsplitn(3, ':'); + match (split.next(), split.next(), split.next()) { + (Some(column), Some(line), Some(path)) => { + let path = env::current_dir().unwrap().join(path); + let path = AbsPathBuf::assert(path); + Ok(Position { path, line: line.parse()?, column: column.parse()? }) + } + _ => bail!("position should be in file:line:column format: {:?}", s), + } } } -fn rsplit_at_char(s: &str, c: char) -> Result<(&str, &str)> { - let idx = s.rfind(c).ok_or_else(|| format_err!("no `{}` in {}", c, s))?; - Ok((&s[..idx], &s[idx + 1..])) -} - pub fn analysis_bench( verbosity: Verbosity, path: &Path, diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs index 62ed6880b..e73b3a211 100644 --- a/crates/rust-analyzer/src/handlers.rs +++ b/crates/rust-analyzer/src/handlers.rs @@ -26,7 +26,7 @@ use ra_project_model::TargetKind; use ra_syntax::{algo, ast, AstNode, SyntaxKind, TextRange, TextSize}; use serde::{Deserialize, Serialize}; use serde_json::to_value; -use stdx::{format_to, split_delim}; +use stdx::{format_to, split_once}; use crate::{ cargo_target_spec::CargoTargetSpec, @@ -865,7 +865,7 @@ pub(crate) fn handle_resolve_code_action( .map(|it| it.into_iter().filter_map(from_proto::assist_kind).collect()); let assists = snap.analysis.resolved_assists(&snap.config.assist, frange)?; - let (id_string, index) = split_delim(¶ms.id, ':').unwrap(); + let (id_string, index) = split_once(¶ms.id, ':').unwrap(); let index = index.parse::().unwrap(); let assist = &assists[index]; assert!(assist.assist.id.0 == id_string); diff --git a/crates/stdx/src/lib.rs b/crates/stdx/src/lib.rs index ea0e6b949..b65875c96 100644 --- a/crates/stdx/src/lib.rs +++ b/crates/stdx/src/lib.rs @@ -109,9 +109,18 @@ pub fn replace(buf: &mut String, from: char, to: &str) { *buf = buf.replace(from, to) } -pub fn split_delim(haystack: &str, delim: char) -> Option<(&str, &str)> { - let idx = haystack.find(delim)?; - Some((&haystack[..idx], &haystack[idx + delim.len_utf8()..])) +// https://github.com/rust-lang/rust/issues/74773 +pub fn split_once(haystack: &str, delim: char) -> Option<(&str, &str)> { + let mut split = haystack.splitn(2, delim); + let prefix = split.next()?; + let suffix = split.next()?; + Some((prefix, suffix)) +} +pub fn rsplit_once(haystack: &str, delim: char) -> Option<(&str, &str)> { + let mut split = haystack.rsplitn(2, delim); + let suffix = split.next()?; + let prefix = split.next()?; + Some((prefix, suffix)) } pub fn trim_indent(mut text: &str) -> String { diff --git a/crates/test_utils/src/fixture.rs b/crates/test_utils/src/fixture.rs index ed764046b..e40b61a94 100644 --- a/crates/test_utils/src/fixture.rs +++ b/crates/test_utils/src/fixture.rs @@ -2,7 +2,7 @@ //! rust-analyzer database from a single string. use rustc_hash::FxHashMap; -use stdx::{lines_with_ends, split_delim, trim_indent}; +use stdx::{lines_with_ends, split_once, trim_indent}; #[derive(Debug, Eq, PartialEq)] pub struct Fixture { @@ -71,14 +71,14 @@ impl Fixture { let mut cfg_key_values = Vec::new(); let mut env = FxHashMap::default(); for component in components[1..].iter() { - let (key, value) = split_delim(component, ':').unwrap(); + let (key, value) = split_once(component, ':').unwrap(); match key { "crate" => krate = Some(value.to_string()), "deps" => deps = value.split(',').map(|it| it.to_string()).collect(), "edition" => edition = Some(value.to_string()), "cfg" => { for entry in value.split(',') { - match split_delim(entry, '=') { + match split_once(entry, '=') { Some((k, v)) => cfg_key_values.push((k.to_string(), v.to_string())), None => cfg_atoms.push(entry.to_string()), } @@ -86,7 +86,7 @@ impl Fixture { } "env" => { for key in value.split(',') { - if let Some((k, v)) = split_delim(key, '=') { + if let Some((k, v)) = split_once(key, '=') { env.insert(k.into(), v.into()); } } -- cgit v1.2.3