Created
May 6, 2014 07:27
-
-
Save shadowmint/76d37eb7dcad9aca0bab to your computer and use it in GitHub Desktop.
rust strings
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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