Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add std::str::Chars remaining() function #12395

Closed
mneumann opened this issue Feb 19, 2014 · 7 comments
Closed

Add std::str::Chars remaining() function #12395

mneumann opened this issue Feb 19, 2014 · 7 comments

Comments

@mneumann
Copy link
Contributor

impl<'a> Chars<'a> {
  fn remaining(&self) -> 'a &str { self.string }
}

This is quite useful when scanning strings, especially when more flexibility is needed. For example, the following example uses slice_from which is not always safe as it uses byte offsets (but using char offsets would be O(n) and I want to avoid it!).

// This code basically parses a markdown horizontal rule.

let item: char = '*';

// Counts the number of items
let mut cnt: uint = 0;
// Counts the consumed spaces (and the final NL)
let mut spc: uint = 0;

for ch in string.chars() {
    if      ch == item { cnt += 1; }
    else if ch == '\n'  { spc += 1; break; }
    else if ch == ' '   { spc += 1; }
    else               { return None; }
}

if cnt >= 3 {
    // return sucess and the remaining string to continue parsing!
    Some(string.slice_from(cnt + spc))
} else {
    None
}

Instead when something like remaining() would exist, the code could be rewritten as:

let item = '*';

// Counts the number of items
let mut cnt: uint = 0;

let iter = string.chars();
for ch in iter {
    if ch == item { cnt += 1; }
    else if ch == '\n' { break; }
    else if ch == ' ' {}
    else { return None; }
}

if cnt >= 3 {
    Some(iter.remaining())
} else {
    None
}

This comes in very useful and is also more efficient! Iterators are not always enough, so that's why I do not want to pass iterators around and instead work on string slices.

@mneumann
Copy link
Contributor Author

Not only this is more efficient (no need to count twice), but also safe (slice_from() can fail) and much much cleaner.

@emberian
Copy link
Member

@mneumann pull request? 😄

@mneumann
Copy link
Contributor Author

@cmr: I think we'd want that for all related Iterators where it makes sense as well, no?

@treeman
Copy link
Contributor

treeman commented Sep 2, 2014

Triage bump.

@mneumann what's the status on this? I believe this might need an RFC?

@bluss
Copy link
Member

bluss commented Sep 2, 2014

@mneumann .char_indices() can do a lot for you.

playpen link

fn main() {
    let s = "find α-particles";
    let mut start = s.len();
    for (i, c) in s.char_indices() {
        if c == 'p' {
            start = i;
            break;
        }
    }
    println!("remaining={}", s.slice_from(start));
}

@mneumann
Copy link
Contributor Author

mneumann commented Sep 2, 2014

@bluss: Thanks. That works of course. Closing for now.

@mneumann mneumann closed this as completed Sep 2, 2014
@bluss
Copy link
Member

bluss commented Sep 2, 2014

Fwiw, if this is implemented you could even call it .as_slice(). Might be confusing, but that's what it does -- the iterator (the range it represents) as slice.

bors added a commit to rust-lang-ci/rust that referenced this issue Jul 25, 2022
fix: f32 and f64 representation during lowering

should fix rust-lang#12380
flip1995 pushed a commit to flip1995/rust that referenced this issue Mar 7, 2024
[`let_underscore_untyped`]: fix false positive on async function

changelog: [`let_underscore_untyped`]: fix false positive on async function

Fix rust-lang#12395
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants