use color::{black, Color};
use std::path::PathBuf;
#[derive(Clone, Debug)]
pub struct Text {
pub sequence: Vec<TextUnit>,
pub position: Position,
}
#[derive(Clone, Debug)]
pub struct TextUnit {
pub string: String,
pub style: Style,
}
#[derive(Copy, Clone, Debug)]
pub enum Line {
Under,
Over,
Through,
}
#[derive(Copy, Clone, Debug)]
pub enum Position {
Center,
ToLeft,
ToRight
}
#[derive(Clone, Debug)]
pub struct Style {
pub typeface: Option<PathBuf>,
pub height: Option<f64>,
pub color: Color,
pub bold: bool,
pub italic: bool,
pub line: Option<Line>,
pub monospace: bool,
}
impl Style {
pub fn default() -> Style {
Style {
typeface: None,
height: None,
color: black(),
bold: false,
italic: false,
line: None,
monospace: false,
}
}
}
impl Text {
pub fn from_string(string: String) -> Text {
Text {
sequence: vec![TextUnit { string: string, style: Style::default(), }],
position: Position::Center
}
}
pub fn empty() -> Text {
Text::from_string("".to_string())
}
#[inline]
pub fn append(mut self, other: Text) -> Text {
self.sequence.extend(other.sequence.into_iter());
self
}
pub fn concat(texts: Vec<Text>) -> Text {
let position = texts.get(0).map(|t| t.position).unwrap_or(Position::Center);
Text {
sequence: texts.into_iter()
.flat_map(|Text { sequence, position }| sequence.into_iter())
.collect(),
position: position
}
}
pub fn join(separator: Text, texts: Vec<Text>) -> Text {
texts.into_iter().fold(Text::empty(), |texts, text| {
texts.append(text).append(separator.clone())
})
}
#[inline]
pub fn style(self, style: Style) -> Text {
let string = String::from_utf8(self.sequence.into_iter().flat_map(|unit| {
unit.string.into_bytes().into_iter()
}).collect()).unwrap();
Text {
sequence: vec![TextUnit { string: string, style: style }],
..self
}
}
#[inline]
pub fn typeface(mut self, path: PathBuf) -> Text {
for unit in self.sequence.iter_mut() {
unit.style.typeface = Some(path.clone());
}
self
}
#[inline]
pub fn monospace(mut self) -> Text {
for unit in self.sequence.iter_mut() {
unit.style.monospace = true;
}
self
}
#[inline]
pub fn height(mut self, h: f64) -> Text {
for unit in self.sequence.iter_mut() {
unit.style.height = Some(h);
}
self
}
#[inline]
pub fn color(mut self, color: Color) -> Text {
for unit in self.sequence.iter_mut() {
unit.style.color = color;
}
self
}
#[inline]
pub fn bold(mut self) -> Text {
for unit in self.sequence.iter_mut() {
unit.style.bold = true;
}
self
}
#[inline]
pub fn italic(mut self) -> Text {
for unit in self.sequence.iter_mut() {
unit.style.italic = true;
}
self
}
#[inline]
pub fn line(mut self, line: Line) -> Text {
for unit in self.sequence.iter_mut() {
unit.style.line = Some(line);
}
self
}
#[inline]
pub fn position(mut self, position: Position) -> Text {
self.position = position;
self
}
}