colour: String,
}
+#[derive(Debug, Clone)]
+pub struct ColouredStringSlice<'a> {
+ text: &'a str,
+ colour: &'a str,
+}
+
impl ColouredString {
pub fn plain(text: &str) -> Self {
ColouredString {
pub fn width(&self) -> usize { UnicodeWidthStr::width(&self.text as &str) }
pub fn text(&self) -> &str { &self.text }
+
+ pub fn slice(&self) -> ColouredStringSlice {
+ ColouredStringSlice {
+ text: &self.text,
+ colour: &self.colour,
+ }
+ }
+}
+
+impl<'a> ColouredStringSlice<'a> {
+ pub fn general(text: &'a str, colour: &'a str) -> Self {
+ assert_eq!(text.chars().count(), colour.chars().count(),
+ "Mismatched lengths in ColouredStringSlice::general");
+ ColouredStringSlice {
+ text: text,
+ colour: colour,
+ }
+ }
+
+ pub fn nchars(&self) -> usize { self.text.chars().count() }
+ pub fn width(&self) -> usize { UnicodeWidthStr::width(&self.text as &str) }
+ pub fn text(&self) -> &'a str { &self.text }
}
impl PartialEq for ColouredString {
impl Eq for ColouredString {}
+impl<'a> PartialEq for ColouredStringSlice<'a> {
+ fn eq(&self, rhs: &ColouredStringSlice) -> bool {
+ self.text == rhs.text && self.colour == rhs.colour
+ }
+}
+
+impl<'a> Eq for ColouredStringSlice<'a> {}
+
impl std::ops::Add<ColouredString> for ColouredString {
type Output = Self;
fn add(self, rhs: Self) -> Self {
}
pub struct ColouredStringFragIterator<'a> {
- cs: &'a ColouredString,
+ cs: ColouredStringSlice<'a>,
textpos: usize,
colourpos: usize,
}
pub struct ColouredStringSplitIterator<'a> {
- cs: &'a ColouredString,
+ cs: ColouredStringSlice<'a>,
width: usize,
textpos: usize,
colourpos: usize,
}
+impl<'a> ColouredStringSlice<'a> {
+ pub fn frags(&self) -> ColouredStringFragIterator<'a> {
+ ColouredStringFragIterator {
+ cs: self.clone(),
+ textpos: 0,
+ colourpos: 0,
+ }
+ }
+ pub fn split(&'a self, width: usize) -> ColouredStringSplitIterator<'a> {
+ ColouredStringSplitIterator {
+ cs: self.clone(),
+ width: width,
+ textpos: 0,
+ colourpos: 0,
+ }
+ }
+}
+
impl<'a> ColouredString {
pub fn frags(&'a self) -> ColouredStringFragIterator<'a> {
ColouredStringFragIterator {
- cs: self,
+ cs: self.slice(),
textpos: 0,
colourpos: 0,
}
}
pub fn split(&'a self, width: usize) -> ColouredStringSplitIterator<'a> {
ColouredStringSplitIterator {
- cs: self,
+ cs: self.slice(),
width: width,
textpos: 0,
colourpos: 0,
}
impl<'a> Iterator for ColouredStringSplitIterator<'a> {
- type Item = ColouredString;
+ type Item = ColouredStringSlice<'a>;
fn next(&mut self) -> Option<Self::Item> {
let textslice = &self.cs.text[self.textpos..];
let mut textit = textslice.char_indices();
};
self.textpos += textend;
self.colourpos += colourend;
- Some(ColouredString::general(&textslice[..textend],
- &colourslice[..colourend]))
+ Some(ColouredStringSlice {
+ text: &textslice[..textend],
+ colour: &colourslice[..colourend],
+ })
},
_ => panic!("length mismatch in CSSI"),
}
fn test_split() {
let cs = ColouredString::general("abcdefgh", "mnopqrst");
let mut lines = cs.split(3);
- assert_eq!(lines.next(), Some(ColouredString::general("abc", "mno")));
- assert_eq!(lines.next(), Some(ColouredString::general("def", "pqr")));
- assert_eq!(lines.next(), Some(ColouredString::general("gh", "st")));
+ assert_eq!(lines.next(), Some(ColouredStringSlice::general("abc", "mno")));
+ assert_eq!(lines.next(), Some(ColouredStringSlice::general("def", "pqr")));
+ assert_eq!(lines.next(), Some(ColouredStringSlice::general("gh", "st")));
assert_eq!(lines.next(), None);
let mut lines = cs.split(4);
- assert_eq!(lines.next(), Some(ColouredString::general("abcd", "mnop")));
- assert_eq!(lines.next(), Some(ColouredString::general("efgh", "qrst")));
+ assert_eq!(lines.next(), Some(ColouredStringSlice::general("abcd", "mnop")));
+ assert_eq!(lines.next(), Some(ColouredStringSlice::general("efgh", "qrst")));
assert_eq!(lines.next(), None);
- let cs = ColouredString::general("ab\u{4567}defgh", "mnopqrst");
+ let cs = ColouredStringSlice::general("ab\u{4567}defgh", "mnopqrst");
let mut lines = cs.split(3);
- assert_eq!(lines.next(), Some(ColouredString::general("ab", "mn")));
- assert_eq!(lines.next(), Some(ColouredString::general("\u{4567}d", "op")));
- assert_eq!(lines.next(), Some(ColouredString::general("efg", "qrs")));
- assert_eq!(lines.next(), Some(ColouredString::general("h", "t")));
+ assert_eq!(lines.next(), Some(ColouredStringSlice::general("ab", "mn")));
+ assert_eq!(lines.next(), Some(ColouredStringSlice::general("\u{4567}d", "op")));
+ assert_eq!(lines.next(), Some(ColouredStringSlice::general("efg", "qrs")));
+ assert_eq!(lines.next(), Some(ColouredStringSlice::general("h", "t")));
assert_eq!(lines.next(), None);
}