Programming Language

Nocter

A self-contained systems language built around simplicity, encapsulation, and foolproof design.

/development/std/str/text.nct

text.nct

//! Borrowed UTF-8 text operations.

include ./index.nct

use std/iter.{Iterator, ViewIter}
use std/ptr.from_addr
use std/string.{String, bytes_from_str, contains, ends_with, find, find_from, split, starts_with}
use std/string.{LinesIter, SplitIter, get_range, is_char_boundary, lines, split_views}
use std/string.{strip_prefix, strip_suffix}
use std/vec.Vec

instance str {
    operator (&self == other: &Self): bool {
        let left = bytes_from_str(self)
        let right = bytes_from_str(other)
        if left.len() != right.len() {
            return false
        }
        var index: usize = 0
        while index < left.len() {
            if left[index] != right[index] {
                return false
            }
            index = index + 1
        }
        return true
    }

    operator (&self < other: &Self): bool {
        let left = bytes_from_str(self)
        let right = bytes_from_str(other)
        let shared_len: usize = if left.len() < right.len() { left.len() } else { right.len() }
        var index: usize = 0
        while index < shared_len {
            if left[index] < right[index] { return true }
            if right[index] < left[index] { return false }
            index = index + 1
        }
        return left.len() < right.len()
    }

    method &self.len(): usize {
        return str_len_raw(self)
    }

    method &self.is_empty(): bool {
        return str_len_raw(self) == 0
    }

    method &self.ptr(): *u8 {
        return from_addr(str_ptr_addr_raw(self))
    }

    method &self.bytes(): &[u8] {
        return bytes_from_str(self)
    }

    method &self.is_char_boundary(index: usize): bool {
        return is_char_boundary(self, index)
    }

    method &self.get_range(start: usize, end: usize): &str? {
        return get_range(self, start, end)?
    }

    method &self.find_from(needle: &str, start: usize): usize? {
        return find_from(self, needle, start)?
    }

    method &self.find(needle: &str): usize? {
        return find(self, needle)?
    }

    method &self.contains(needle: &str): bool {
        return contains(self, needle)
    }

    method &self.starts_with(prefix: &str): bool {
        return starts_with(self, prefix)
    }

    method &self.ends_with(suffix: &str): bool {
        return ends_with(self, suffix)
    }

    method &self.strip_prefix(prefix: &str): &str? from self {
        return strip_prefix(self, prefix)?
    }

    method &self.strip_suffix(suffix: &str): &str? from self {
        return strip_suffix(self, suffix)?
    }

    method &self.split(separator: &str): Vec<String>! {
        return split(self, separator)?
    }

    method &self.split_views(separator: &str): SplitIter! from self | separator {
        return split_views(self, separator)?
    }

    method &self.lines(): some Iterator<Item = &str> {
        return lines(self)
    }

    method &self.bytes_iter(): ViewIter<u8> {
        return ViewIter.from_view(bytes_from_str(self))
    }
}