GString

Struct GString 

Source
pub struct GString { /* private fields */ }
Expand description

String with support for Unicode graphemes

Implementations§

Source§

impl GString

Source

pub fn new() -> GString

Create a new empty GString

use gstring::*;

let s = GString::new();

assert_eq!(s, "");
Source

pub fn from(s: &str) -> GString

Create a new GString from a &str

use gstring::*;

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

let s = GString::from(S);

assert_eq!(s, S);
Source

pub fn graphemes(&self) -> &[String]

Return a slice reference to the internal graphemes

use gstring::*;

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

let s = GString::from(S);
let g = s.graphemes();

assert_eq!(g, G);
assert_eq!(g.len(), G.len());
Source

pub fn into_graphemes(self) -> Vec<String>

Consume the GString and convert to a Vec of graphemes

use gstring::*;

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

let g = GString::from(S).into_graphemes();

assert_eq!(g, G);
assert_eq!(g.len(), G.len());
Source

pub fn find(&self, pattern: &GString) -> Option<usize>

Returns the index of the first grapheme of this string slice that matches the pattern

use gstring::*;

let g = GString::from("a\u{310}e\u{301}o\u{308}\u{332}");

assert_eq!(g.find(&GString::from("a\u{310}")), Some(0));
assert_eq!(g.find(&GString::from("e\u{301}")), Some(1));
assert_eq!(g.find(&GString::from("o\u{308}\u{332}")), Some(2));
assert!(g.find(&GString::from("nonexistent")).is_none());
Source

pub fn find_str(&self, pattern: &str) -> Option<usize>

Returns the index of the first grapheme of this string slice that matches the pattern

use gstring::*;

let g = GString::from("a\u{310}e\u{301}o\u{308}\u{332}");

assert_eq!(g.find_str("a\u{310}"), Some(0));
assert_eq!(g.find_str("e\u{301}"), Some(1));
assert_eq!(g.find_str("o\u{308}\u{332}"), Some(2));
assert!(g.find_str("nonexistent").is_none());
Source

pub fn find_from(&self, n: usize, pattern: &GString) -> Option<usize>

Returns the index of the first grapheme of this string slice that matches the pattern after n graphemes

use gstring::*;

let g = GString::from("abc abc");

assert_eq!(g.find_from(0, &GString::from("abc")), Some(0));
assert_eq!(g.find_from(1, &GString::from("abc")), Some(4));
assert!(g.find_from(0, &GString::from("nonexistent")).is_none());
Source

pub fn find_from_str(&self, n: usize, pattern: &str) -> Option<usize>

Returns the index of the first grapheme of this string slice that matches the pattern after n graphemes

use gstring::*;

let g = GString::from("abc abc");

assert_eq!(g.find_from_str(0, "abc"), Some(0));
assert_eq!(g.find_from_str(1, "abc"), Some(4));
assert!(g.find_from_str(0, "nonexistent").is_none());
Source

pub fn find_prev_from(&self, n: usize, pattern: &GString) -> Option<usize>

Returns the index of the first grapheme of this string slice that matches the pattern before n graphemes

use gstring::*;

let g = GString::from("abc abc");

assert_eq!(g.find_prev_from(7, &GString::from("abc")), Some(4));
assert_eq!(g.find_prev_from(4, &GString::from("abc")), Some(0));
assert!(g.find_prev_from(7, &GString::from("nonexistent")).is_none());
Source

pub fn find_prev_from_str(&self, n: usize, pattern: &str) -> Option<usize>

Returns the index of the first grapheme of this string slice that matches the pattern before n graphemes

use gstring::*;

let g = GString::from("abc abc");

assert_eq!(g.find_prev_from_str(7, "abc"), Some(4));
assert_eq!(g.find_prev_from_str(4, "abc"), Some(0));
assert!(g.find_prev_from_str(7, "nonexistent").is_none());
Source

pub fn get(&self, index: usize) -> Option<&String>

Return a reference to the grapheme at index

use gstring::*;

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

let g = GString::from(S);

assert_eq!(g.get(0).unwrap(), "a\u{310}");
assert_eq!(g.get(1).unwrap(), "e\u{301}");
assert_eq!(g.get(2).unwrap(), "o\u{308}\u{332}");
assert!(g.get(3).is_none());
Source

pub fn len(&self) -> usize

Return the count of graphemes

use gstring::*;

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

let s = GString::from(S);
assert_eq!(s.len(), 3);

let s = GString::from("");
assert_eq!(s.len(), 0);
Source

pub fn is_empty(&self) -> bool

Return true if the GString has zero graphemes otherwise return false

use gstring::*;

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

let s = GString::from("");
assert!(s.is_empty());

let s = GString::from(S);
assert!(!s.is_empty());
Source

pub fn chars(&self) -> Vec<char>

Return a Vec of chars

use gstring::*;

const S: &str = "a\u{310}e\u{301}o\u{308}\u{332}";
const C: &[char] = &['a', '\u{310}', 'e', '\u{301}', 'o', '\u{308}', '\u{332}'];

let c = GString::from(S).chars();

assert_eq!(c, C);
assert_eq!(c.len(), C.len());
Source

pub fn bytes(&self) -> Vec<u8>

Return a Vec of u8s

use gstring::*;

const S: &str = "a\u{310}e\u{301}o\u{308}\u{332}";
const B: &[u8] = &[0x61, 0xcc, 0x90, 0x65, 0xcc, 0x81, 0x6f, 0xcc, 0x88, 0xcc, 0xb2];

let b = GString::from(S).bytes();

assert_eq!(b, B);
assert_eq!(b.len(), B.len());
Source

pub fn lines(&self) -> Vec<GString>

Split into lines as a Vec of GStrings

use gstring::*;

assert_eq!(GString::from("abc\ndef").lines(), &["abc\n", "def"]);
assert_eq!(GString::from("abc\n").lines(), &["abc\n", ""]);
assert_eq!(GString::from("\ndef").lines(), &["\n", "def"]);

Note that unlike str::lines, this method includes the original newline graphemes at the end of each line.

Source

pub fn coordinates(&self, position: usize) -> Option<(usize, usize)>

Return the coordinates (row, column) for a given position

use gstring::*;

let g = GString::from("abc\ndef");

assert_eq!(g.coordinates(0), Some((0, 0)));
assert_eq!(g.coordinates(1), Some((0, 1)));
assert_eq!(g.coordinates(2), Some((0, 2)));
assert_eq!(g.coordinates(3), Some((0, 3)));
assert_eq!(g.coordinates(4), Some((1, 0)));
assert_eq!(g.coordinates(5), Some((1, 1)));
assert_eq!(g.coordinates(6), Some((1, 2)));
assert_eq!(g.coordinates(7), Some((1, 3)));
assert_eq!(g.coordinates(8), None);

Note that newlines are located at the end of each line. Also a valid coordinate exists at a GString’s position equal to its length, however no valid coordinate exists for any greater position.

See also the GString::position method.

Source

pub fn position(&self, coordinates: (usize, usize)) -> Option<usize>

Return the position for given coordinates (row, column)

use gstring::*;

/*
  0 1 2 3   column
0 a b c \n
  0 1 2 3   position

  0 1 2 3   column
1 d e f
  4 5 6 7   position
*/

let g = GString::from("abc\ndef");

assert_eq!(g.position((0, 0)), Some(0));
assert_eq!(g.position((0, 1)), Some(1));
assert_eq!(g.position((0, 2)), Some(2));
assert_eq!(g.position((0, 3)), Some(3));
assert_eq!(g.position((0, 4)), None);
assert_eq!(g.position((1, 0)), Some(4));
assert_eq!(g.position((1, 1)), Some(5));
assert_eq!(g.position((1, 2)), Some(6));
assert_eq!(g.position((1, 3)), Some(7));
assert_eq!(g.position((1, 4)), None);
assert_eq!(g.position((2, 0)), None);

let g = GString::from("");

assert_eq!(g.position((0, 0)), Some(0));
assert_eq!(g.position((0, 1)), None);
assert_eq!(g.position((1, 0)), None);

Note that newlines are located at the end of each line. Also a valid coordinate exists at a GString’s position equal to its length, however no valid coordinate exists for any greater position.

See also the GString::coordinates method.

Source

pub fn newlines(&self) -> Vec<usize>

Return the indices of all newlines

use gstring::*;

assert_eq!(GString::from("abc\ndef").newlines(), &[3]);
assert_eq!(GString::from("abc\ndef\n").newlines(), &[3, 7]);
assert_eq!(GString::from("abc").newlines(), &[]);
assert_eq!(GString::from("").newlines(), &[]);
assert_eq!(GString::from("\n").newlines(), &[0]);
assert_eq!(GString::from("\n\n").newlines(), &[0, 1]);
Source

pub fn insert(&mut self, index: usize, string: &str)

Insert a string at an index

use gstring::*;

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

let mut s = GString::from("a\u{310}o\u{308}\u{332}");
s.insert(1, "e\u{301}");

assert_eq!(s, S);
Source

pub fn remove(&mut self, index: usize) -> GString

Remove a grapheme at an index

use gstring::*;

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

let mut s = GString::from(S);

assert_eq!(s.remove(1), "e\u{301}");
assert_eq!(s, "a\u{310}o\u{308}\u{332}");
Source

pub fn push(&mut self, string: &str)

Append a &str

use gstring::*;

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

let mut s = GString::from("a\u{310}e\u{301}");
s.push("o\u{308}\u{332}");

assert_eq!(s, S);
Source

pub fn pop(&mut self) -> Option<GString>

Remove the last grapheme and return it as a new GString

use gstring::*;

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

let mut s = GString::from(S);

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

assert_eq!(s.pop().unwrap(), "e\u{301}");
assert_eq!(s, "a\u{310}");

assert_eq!(s.pop().unwrap(), "a\u{310}");
assert_eq!(s, "");

assert_eq!(s.pop(), None);
assert_eq!(s, "");
Source

pub fn splice<R: RangeBounds<usize>>( &mut self, range: R, replace_with: &str, ) -> GString

Replace a range with a &str

The range can be a a..b Range<usize>, a.. RangeFrom<usize>, ..b RangeTo<usize>, or .. RangeFull.

use gstring::*;

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

let mut s = GString::from(S);

assert_eq!(s.splice(0..2, "e\u{301}a\u{310}"), "a\u{310}e\u{301}");
assert_eq!(s, "e\u{301}a\u{310}o\u{308}\u{332}");

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

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

assert_eq!(s.splice(.., ""), "o\u{308}\u{332}a\u{310}");
assert_eq!(s, "");
Source

pub fn drain<R: RangeBounds<usize>>(&mut self, range: R) -> GString

Remove and return a range of graphemes

The range can be a a..b Range<usize>, a.. RangeFrom<usize>, ..b RangeTo<usize>, or .. RangeFull.

use gstring::*;

let mut s = GString::from("a\u{310}e\u{301}o\u{308}\u{332}a\u{310}e\u{301}");

assert_eq!(s.drain(0..2), "a\u{310}e\u{301}");
assert_eq!(s, "o\u{308}\u{332}a\u{310}e\u{301}");

assert_eq!(s.drain(2..), "e\u{301}");
assert_eq!(s, "o\u{308}\u{332}a\u{310}");

assert_eq!(s.drain(..1), "o\u{308}\u{332}");
assert_eq!(s, "a\u{310}");

assert_eq!(s.drain(..), "a\u{310}");
assert_eq!(s, "");
Source

pub fn slice(&self, range: Range<usize>) -> GString

Create a new GString from an a..b Range<usize>

use gstring::*;

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

let s = GString::from(S);

assert_eq!(s.slice(0..1), "a\u{310}");
assert_eq!(s.slice(1..2), "e\u{301}");
assert_eq!(s.slice(2..3), "o\u{308}\u{332}");
assert_eq!(s.slice(0..2), "a\u{310}e\u{301}");
assert_eq!(s.slice(1..3), "e\u{301}o\u{308}\u{332}");
assert_eq!(s.slice(0..3), S);

See also the GString::index method.

Source

pub fn shape(&self) -> &[usize]

Return a reference to the “shape” of the content

  • Length of the shape: Number of lines
  • Values: Maximum column index for each line (including the newline)
LineCountRow IndexMax Column Index
\n100
a\n211
bc\n322
d\n431
efg\n543
\n650
use gstring::*;

let s = GString::from("\na\nbc\nd\nefg\n");

let shape = s.shape();

assert_eq!(shape, &[0, 1, 2, 1, 3, 0]);

// There are 6 lines
assert_eq!(shape.len(), 6);

// Max column index of the 5th line is 3
assert_eq!(shape[4], 3);
Source

pub fn shape_string(&self) -> String

Generate string showing the row, column, and position for each grapheme

use gstring::*;

let s = GString::from("a\nbc\ndef\nghij");

let d = "  \
  0 1 2 3 4

  0 1
0 a \\n
  0 1

  0 1 2
1 b c \\n
  2 3 4

  0 1 2 3
2 d e f \\n
  5 6 7 8

  0 1 2 3 4
3 g h i j
  0 1 1 1 1
  9 0 1 2 3

";

assert_eq!(s.shape_string(), d);
§Notes
  1. There is a column header at the top to show the column header for the longest row.
  2. Each content row has:
    • Row column header above
    • Row index to the left
    • Position (offset) below
  3. The last row shows the column and position one grapheme past the end.
Source

pub fn iter(&self) -> GStringRefIter<'_>

Create a GStringRefIter for iterating graphemes by reference

use gstring::*;

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

let s = GString::from(S);
let mut i = s.iter();

assert_eq!(i.next().unwrap(), "a\u{310}");
assert_eq!(i.next().unwrap(), "e\u{301}");
assert_eq!(i.next().unwrap(), "o\u{308}\u{332}");
assert_eq!(i.next(), None);

See also the GString::into_iter method.

Source

pub fn into_iter(self) -> GStringIter

Consume the GString and convert into a GStringIter for iterating graphemes

use gstring::*;

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

let s = GString::from(S);
let mut i = s.into_iter();

assert_eq!(i.next().unwrap(), "a\u{310}");
assert_eq!(i.next().unwrap(), "e\u{301}");
assert_eq!(i.next().unwrap(), "o\u{308}\u{332}");
assert_eq!(i.next(), None);

See also the GString::iter method.

Trait Implementations§

Source§

impl Clone for GString

Source§

fn clone(&self) -> GString

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for GString

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Debug print a GString in format, print, println, write, writeln, etc macros

use gstring::*;

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

assert_eq!(
    format!("{:?}", GString::from(S)),
    format!("{:?}", S),
);
Source§

impl Default for GString

Source§

fn default() -> GString

Returns the “default value” for a type. Read more
Source§

impl Display for GString

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Print a GString directly in print, println, eprint, eprintln, and write macros or convert to a String using the format macro to_string method

use gstring::*;

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

let s = GString::from(S);

assert_eq!(format!("{s}"), S);
assert_eq!(format!("{}", s), S);
assert_eq!(s.to_string(), S);
Source§

impl<I> Index<I> for GString
where I: SliceIndex<[String]>,

Source§

fn index(&self, index: I) -> &Self::Output

Index a slice of GString’s graphemes with a usize index, a..b Range<usize>, a.. RangeFrom<usize>, ..b RangeTo<usize>, or .. RangeFull

use gstring::*;

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

let s = GString::from(S);

assert_eq!(&s[0], G[0]);
assert_eq!(&s[1], G[1]);
assert_eq!(&s[2], G[2]);

for start in 0..3 {
    for stop in 1..4 {
        if stop > start {
            assert_eq!(&s[start..stop], G[start..stop].to_vec());
            assert_eq!(&s[..stop], G[..stop].to_vec());
        }
    }
    assert_eq!(&s[start..], G[start..].to_vec());
}
assert_eq!(&s[..], G);

See also the GString::slice method.

Source§

type Output = <I as SliceIndex<[String]>>::Output

The returned type after indexing.
Source§

impl PartialEq<&str> for GString

Source§

fn eq(&self, other: &&str) -> bool

Compare a GString to a &str

use gstring::*;

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

let s = GString::from(S);

assert_eq!(s, S);
assert_ne!(s, "");
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl PartialEq<GString> for &GString

Source§

fn eq(&self, other: &GString) -> bool

Compare a GString to a &GString (or two &GStrings)

use gstring::*;

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

let s1 = GString::from(S);
let s2 = GString::from(S);
let empty = GString::from("");

assert_eq!(&s1, s2);
assert_ne!(&s1, empty);

assert_eq!(&s1, &s2);
assert_ne!(&s1, &empty);
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl PartialEq<String> for GString

Source§

fn eq(&self, other: &String) -> bool

Compare a GString to a String

use gstring::*;

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

let s = GString::from(S);

assert_eq!(s, S.to_string());
assert_ne!(s, String::new());
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl PartialEq<str> for GString

Source§

fn eq(&self, other: &str) -> bool

Compare a GString to a str

use gstring::*;

let s = GString::from("a\u{310}e\u{301}o\u{308}\u{332}");

assert_eq!(s, "a\u{310}e\u{301}o\u{308}\u{332}");
assert_ne!(s, "");
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl PartialEq for GString

Source§

fn eq(&self, other: &GString) -> bool

Compare two GStrings

use gstring::*;

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

let s1 = GString::from(S);
let s2 = GString::from(S);
let s3 = GString::from(S);

assert_eq!(s1, s2);
assert_ne!(s3, GString::from(""));
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl Serialize for GString

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.