Skip to content

Instantly share code, notes, and snippets.

@shadowmint
Created May 6, 2014 07:27
Show Gist options
  • Save shadowmint/76d37eb7dcad9aca0bab to your computer and use it in GitHub Desktop.
Save shadowmint/76d37eb7dcad9aca0bab to your computer and use it in GitHub Desktop.
rust strings
use std::str::from_utf8;
pub enum StrTs<'a> {
StrT(&'a str),
VecT(Vec<u8>),
SliceT(&'a [u8]),
}
pub enum StrErr {
InvalidLength
}
pub trait StrOp {
/** Return the raw points in this str */
fn raw<'a>(&'a mut self) -> &'a str;
/** Struct equality comparison */
fn equals(& mut self, value:StrTs) -> bool;
/** Append a new string to the end of this string */
fn append(& mut self, value:StrTs);
}
pub struct Str {
chars:Vec<u8>
}
impl Str {
pub fn new(value:StrTs) -> Str {
match value {
StrT(v) => {
return Str {
chars: Vec::from_slice(v.as_bytes())
};
},
VecT(v) => {
return Str {
chars: v
};
},
SliceT(v) => {
return Str {
chars: Vec::from_slice(v)
};
}
}
}
}
mod internal {
/** Check if two arrays are equal */
pub fn strict_equality(a:&[u8], b:&[u8]) -> bool {
if a.len() != b.len() {
return false;
}
for i in range(0, a.len()) {
if a[i] != b[i] {
return false;
}
}
return true;
}
}
impl StrOp for Str {
fn raw<'a>(&'a mut self) -> &'a str {
return from_utf8(self.chars.slice(0, self.chars.len())).unwrap();
}
fn append(& mut self, value:StrTs) {
match value {
StrT(v) => { self.chars.push_all(v.as_bytes()); },
VecT(v) => { self.chars.push_all(v.slice(0, v.len())); },
SliceT(v) => { self.chars.push_all(v); }
}
}
fn equals(& mut self, value:StrTs) -> bool {
return match value {
StrT(v) => internal::strict_equality(self.chars.slice(0, self.chars.len()), v.as_bytes()),
VecT(v) => internal::strict_equality(self.chars.slice(0, self.chars.len()), v.slice(0, v.len())),
SliceT(v) => internal::strict_equality(self.chars.slice(0, self.chars.len()), v)
};
}
}
#[cfg(test)]
mod StrOpTests {
use super::Str;
use super::StrOp;
use super::StrT;
use super::VecT;
use super::SliceT;
#[test]
fn test_raw() {
let mut x = Str::new(StrT("Value X"));
let mut y = Str::new(SliceT("Value Y".as_bytes()));
let mut z = Str::new(VecT(Vec::from_slice("Value Z".as_bytes())));
assert!(x.equals(StrT("Value X")));
assert!(y.equals(StrT("Value Y")));
assert!(z.equals(StrT("Value Z")));
}
#[test]
fn test_append() {
let mut x = Str::new(StrT("Values:"));
x.append(StrT("X"));
x.append(SliceT("Y".as_bytes()));
x.append(VecT(Vec::from_slice("Z".as_bytes())));
assert!(x.equals(StrT("Values:XYZ")));
}
#[test]
fn test_equals() {
let mut x = Str::new(StrT("Value"));
assert!(x.equals(StrT("Value")));
assert!(x.equals(VecT(Vec::from_slice("Value".as_bytes()))));
assert!(x.equals(SliceT("Value".as_bytes())));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment