# How to get a substring of a String

**URL:** <https://users.rust-lang.org/t/how-to-get-a-substring-of-a-string/1351>\
**Category:** help\
**Created:** [May 14, 2015, 7:48pm UTC](https://users.rust-lang.org/t/how-to-get-a-substring-of-a-string/1351 "2015-05-14T19:48:04Z")\
**Posts on this page:** 1\
**Showing post:** 11

<div class="post-metadata">

**Author:** ![carlomilanesi](https://sea1.discourse-cdn.com/flex019/user_avatar/users.rust-lang.org/carlomilanesi/32/24581_2.png) [@carlomilanesi](https://users.rust-lang.org/u/carlomilanesi)\
**Post date:** [February 2, 2019, 2:52pm UTC](https://users.rust-lang.org/t/how-to-get-a-substring-of-a-string/1351/11 "2019-02-02T14:52:36Z")

</div>

This code implements both substring-ing and string-slicing, and should never panic:

```
use std::ops::{Bound, RangeBounds};

trait StringUtils {
    fn substring(&self, start: usize, len: usize) -> &str;
    fn slice(&self, range: impl RangeBounds<usize>) -> &str;
}

impl StringUtils for str {
    fn substring(&self, start: usize, len: usize) -> &str {
        let mut char_pos = 0;
        let mut byte_start = 0;
        let mut it = self.chars();
        loop {
            if char_pos == start { break; }
            if let Some(c) = it.next() {
                char_pos += 1;
                byte_start += c.len_utf8();
            }
            else { break; }
        }
        char_pos = 0;
        let mut byte_end = byte_start;
        loop {
            if char_pos == len { break; }
            if let Some(c) = it.next() {
                char_pos += 1;
                byte_end += c.len_utf8();
            }
            else { break; }
        }
        &self[byte_start..byte_end]
    }
    fn slice(&self, range: impl RangeBounds<usize>) -> &str {
        let start = match range.start_bound() {
            Bound::Included(bound) | Bound::Excluded(bound) => *bound,
            Bound::Unbounded => 0,
        };
        let len = match range.end_bound() {
            Bound::Included(bound) => *bound + 1,
            Bound::Excluded(bound) => *bound,
            Bound::Unbounded => self.len(),
        } - start;
        self.substring(start, len)
    }
}

fn main() {
    let s = "abcdèfghij";
    // All three statements should print:
    // "abcdè, abcdèfghij, dèfgh, dèfghij."
    println!("{}, {}, {}, {}.",
        s.substring(0, 5),
        s.substring(0, 50),
        s.substring(3, 5),
        s.substring(3, 50));
    println!("{}, {}, {}, {}.",
        s.slice(..5),
        s.slice(..50),
        s.slice(3..8),
        s.slice(3..));
    println!("{}, {}, {}, {}.",
        s.slice(..=4),
        s.slice(..=49),
        s.slice(3..=7),
        s.slice(3..));
}

```

---

_[View the full topic](https://users.rust-lang.org/t/how-to-get-a-substring-of-a-string/1351)._
