#grapheme #unicode #string #index

gstring

String with support for Unicode graphemes

30 releases (12 breaking)

Uses new Rust 2024

0.13.2 Nov 14, 2025
0.13.0 Oct 27, 2025
0.11.0 May 13, 2025
0.9.0 Mar 5, 2025
0.3.1 Dec 14, 2024

#1934 in Text processing


Used in 2 crates

MIT license

41KB
479 lines

String with support for Unicode graphemes

use gstring::*;

const S: &str = "a\u{310}e\u{301}o\u{308}\u{332}";

// Create a GString
let mut s = GString::from(S);
assert_eq!(s, S);
assert_eq!(s.graphemes(), &["a\u{310}", "e\u{301}", "o\u{308}\u{332}"]);
assert_eq!(s.len(), 3);
assert!(!s.is_empty());
assert_eq!(s.chars(), &['a', '\u{310}', 'e', '\u{301}', 'o', '\u{308}', '\u{332}']);
assert_eq!(s.bytes(), &[0x61, 0xcc, 0x90, 0x65, 0xcc, 0x81, 0x6f, 0xcc, 0x88, 0xcc, 0xb2]);

// Insert a &str
s.insert(0, "i\u{301}u\u{301}");
assert_eq!(s, "i\u{301}u\u{301}a\u{310}e\u{301}o\u{308}\u{332}");

// Remove a grapheme at an index
assert_eq!(s.remove(1), "u\u{301}");
assert_eq!(s, "i\u{301}a\u{310}e\u{301}o\u{308}\u{332}");

// Push a &str
s.push("i\u{301}u\u{301}");
assert_eq!(s, "i\u{301}a\u{310}e\u{301}o\u{308}\u{332}i\u{301}u\u{301}");

// Pop last grapheme
assert_eq!(s.pop().unwrap(), "u\u{301}");
assert_eq!(s, "i\u{301}a\u{310}e\u{301}o\u{308}\u{332}i\u{301}");

// Slice
assert_eq!(s.slice(1..4), "a\u{310}e\u{301}o\u{308}\u{332}");

// Splice
assert_eq!(s.splice(1..4, ""), "a\u{310}e\u{301}o\u{308}\u{332}");
assert_eq!(s, "i\u{301}i\u{301}");

// Drain
assert_eq!(s.drain(..), "i\u{301}i\u{301}");
assert_eq!(s, "");

Dependencies

~0.7–1.4MB
~27K SLoC