Aded doc tests throughout
This commit is contained in:
parent
972ddb57ca
commit
6abfc6aa54
18
src/app.rs
18
src/app.rs
|
@ -34,7 +34,21 @@ impl Renderer {
|
|||
}
|
||||
|
||||
/// The app is the core container for the application logic, resources,
|
||||
/// state, and run loop.
|
||||
/// state, and run loop.
|
||||
///
|
||||
/// Setting up a basic application:
|
||||
///
|
||||
/// ```
|
||||
/// use arkham::prelude::*;
|
||||
///
|
||||
/// fn main() {
|
||||
/// App::new(root_view).run();
|
||||
/// }
|
||||
///
|
||||
/// fn root_view(ctx: &mut ViewContext) {
|
||||
/// ctx.insert((2,2), "Hello World");
|
||||
/// }
|
||||
/// ```
|
||||
pub struct App<F, Args>
|
||||
where
|
||||
F: Callable<Args>,
|
||||
|
@ -147,12 +161,14 @@ where
|
|||
pub fn run(&mut self) -> anyhow::Result<()> {
|
||||
self.container.borrow_mut().bind(Res::new(Terminal));
|
||||
self.container.borrow_mut().bind(Res::new(Keyboard::new()));
|
||||
|
||||
let _ = ctrlc::set_handler(|| {
|
||||
let mut out = std::io::stdout();
|
||||
let _ = terminal::disable_raw_mode();
|
||||
let _ = execute!(out, terminal::LeaveAlternateScreen, cursor::Show);
|
||||
std::process::exit(0);
|
||||
});
|
||||
|
||||
let mut out = std::io::stdout();
|
||||
execute!(out, terminal::EnterAlternateScreen, cursor::Hide)?;
|
||||
terminal::enable_raw_mode()?;
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
use std::ops::{Add, AddAssign, Sub};
|
||||
|
||||
/// Pos represents a coordinate position within the termianl screen.
|
||||
///
|
||||
/// *NOTE* Most functions accept a value that can be converted into a Pos.
|
||||
/// For these a simple tuple of coordinates is sufficient.
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct Pos {
|
||||
pub x: usize,
|
||||
|
@ -8,6 +11,16 @@ pub struct Pos {
|
|||
}
|
||||
|
||||
impl Pos {
|
||||
/// Generate a new Pos from a given set of coordinates.
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/// ```
|
||||
/// use arkham::prelude::*;
|
||||
/// let pos = Pos::new(3,1);
|
||||
/// assert_eq!(pos.x, 3);
|
||||
/// assert_eq!(pos.y, 1);
|
||||
/// ```
|
||||
pub fn new(x: usize, y: usize) -> Self {
|
||||
Self { x, y }
|
||||
}
|
||||
|
@ -45,7 +58,27 @@ impl AddAssign<Pos> for Pos {
|
|||
}
|
||||
}
|
||||
|
||||
// An area that can be operated on.
|
||||
/// An area that can be operated on.
|
||||
///
|
||||
/// ```
|
||||
/// use arkham::prelude::*;
|
||||
///
|
||||
/// let s = Size::new(3,3);
|
||||
/// assert_eq!(s.width, 3);
|
||||
/// assert_eq!(s.height, 3);
|
||||
/// ```
|
||||
///
|
||||
/// Sizes can be added and subtracted to mutate them easily:
|
||||
///
|
||||
/// ```
|
||||
/// use arkham::prelude::*;
|
||||
///
|
||||
/// let s1 = Size::new(3,3);
|
||||
/// let s2 = Size::new(0,1);
|
||||
/// let s = s1 - s2;
|
||||
/// assert_eq!(s.width, 3);
|
||||
/// assert_eq!(s.height, 2);
|
||||
/// ```
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct Size {
|
||||
pub width: usize,
|
||||
|
@ -172,11 +205,33 @@ impl Rect {
|
|||
}
|
||||
}
|
||||
|
||||
/// Move the Rect's origin, without chaging its size.
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/// ```
|
||||
/// use arkham::prelude::*;
|
||||
///
|
||||
/// let mut rect = Rect::new((0,0), (15,5));
|
||||
/// rect.translate(5,0);
|
||||
/// assert_eq!(rect.pos.x, 5);
|
||||
/// ```
|
||||
pub fn translate(&mut self, x: i32, y: i32) {
|
||||
self.pos.x = (self.pos.x as i32 + x).max(0) as usize;
|
||||
self.pos.y = (self.pos.y as i32 + y).max(0) as usize;
|
||||
}
|
||||
|
||||
/// Change the Rect's size without altering its position.
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/// ```
|
||||
/// use arkham::prelude::*;
|
||||
///
|
||||
/// let mut rect = Rect::new((0,0), (15,5));
|
||||
/// rect.expand(5,0);
|
||||
/// assert_eq!(rect.size.width, 20);
|
||||
/// ```
|
||||
pub fn expand(&mut self, width: i32, height: i32) {
|
||||
self.size.width = (self.size.width as i32 + width).max(1) as usize;
|
||||
self.size.height = (self.size.height as i32 + height).max(1) as usize;
|
||||
|
|
119
src/runes.rs
119
src/runes.rs
|
@ -52,29 +52,71 @@ impl From<Color> for Rune {
|
|||
}
|
||||
|
||||
impl Rune {
|
||||
/// Create a new empty Rune. This can be used with the settings functions as a _builder_ pattern
|
||||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// use arkham::prelude::*;
|
||||
/// let rune:Rune = Rune::new().bg(Color::Blue).fg(Color::White).bold();
|
||||
/// ```
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// Set the content of the rune. The rune's content is a single character.
|
||||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// use arkham::prelude::*;
|
||||
/// let rune = Rune::new().content('A');
|
||||
/// assert_eq!(rune.content, Some('A'));
|
||||
/// ```
|
||||
pub fn content(mut self, content: char) -> Self {
|
||||
self.content = Some(content);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the background color of the rune.
|
||||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// use arkham::prelude::*;
|
||||
/// let rune = Rune::new().bg(Color::Green);
|
||||
/// assert_eq!(rune.bg, Some(Color::Green));
|
||||
/// ```
|
||||
pub fn bg(mut self, bg: Color) -> Self {
|
||||
self.bg = Some(bg);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the text color of the rune.
|
||||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// use arkham::prelude::*;
|
||||
/// let rune = Rune::new().fg(Color::Green);
|
||||
/// assert_eq!(rune.fg, Some(Color::Green));
|
||||
/// ```
|
||||
pub fn fg(mut self, fg: Color) -> Self {
|
||||
self.fg = Some(fg);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the text color of the rune.
|
||||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// use arkham::prelude::*;
|
||||
/// let rune = Rune::new().fg(Color::Green);
|
||||
/// assert_eq!(rune.fg, Some(Color::Green));
|
||||
/// ```
|
||||
pub fn bold(mut self) -> Self {
|
||||
self.bold = true;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn render<W>(self, out: &mut W) -> anyhow::Result<()>
|
||||
/// Renders a Print command into the terminal's output queue
|
||||
pub(crate) fn render<W>(self, out: &mut W) -> anyhow::Result<()>
|
||||
where
|
||||
W: std::io::Write,
|
||||
{
|
||||
|
@ -95,10 +137,17 @@ impl Rune {
|
|||
}
|
||||
}
|
||||
|
||||
/// Runes represetns a series of runes. This is generally used to convert
|
||||
/// Runes represents a series of runes. This is generally used to convert
|
||||
/// strings into Runes and apply styling information to them.
|
||||
///
|
||||
/// Building runes from a string:
|
||||
///
|
||||
/// ```
|
||||
/// use arkham::prelude::*;
|
||||
/// let runes = "This is a test string".to_runes().fg(Color::White);
|
||||
/// ```
|
||||
#[derive(Clone, Debug, Default)]
|
||||
pub struct Runes(Vec<Rune>);
|
||||
pub struct Runes(pub(crate) Vec<Rune>);
|
||||
|
||||
impl std::ops::Deref for Runes {
|
||||
type Target = Vec<Rune>;
|
||||
|
@ -127,26 +176,70 @@ impl<T: ToString> From<T> for Runes {
|
|||
}
|
||||
|
||||
impl Runes {
|
||||
/// Create a new runes collection from a vector of Rune.
|
||||
pub fn new(runes: Vec<Rune>) -> Self {
|
||||
Self(runes)
|
||||
}
|
||||
pub fn fg(self, color: Color) -> Self {
|
||||
self.set_fg(Some(color))
|
||||
}
|
||||
|
||||
pub fn set_fg(mut self, color: Option<Color>) -> Self {
|
||||
/// Set the text color of the rune.
|
||||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// use arkham::prelude::*;
|
||||
/// let runes = "blue".to_runes().fg(Color::Blue);
|
||||
/// assert!(runes.iter().all(|r| r.fg == Some(Color::Blue)))
|
||||
/// ```
|
||||
pub fn fg(mut self, color: Color) -> Self {
|
||||
for r in self.0.iter_mut() {
|
||||
r.fg = color;
|
||||
r.fg = Some(color);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the text color of the rune.
|
||||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// use arkham::prelude::*;
|
||||
/// let mut runes = "on blue".to_runes().bg(Color::Blue);
|
||||
/// let runes = runes.clear_fg();
|
||||
/// assert!(runes.iter().all(|r| r.fg == None))
|
||||
pub fn clear_fg(mut self) -> Self {
|
||||
for r in self.0.iter_mut() {
|
||||
r.fg = None;
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the text color of the rune.
|
||||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// use arkham::prelude::*;
|
||||
/// let runes = "on blue".to_runes().bg(Color::Blue);
|
||||
/// assert!(runes.iter().all(|r| r.bg == Some(Color::Blue)))
|
||||
/// ```
|
||||
pub fn bg(mut self, color: Color) -> Self {
|
||||
for r in self.0.iter_mut() {
|
||||
r.bg = Some(color);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the text color of the rune.
|
||||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// use arkham::prelude::*;
|
||||
/// let mut runes = "on blue".to_runes().bg(Color::Blue);
|
||||
/// let runes = runes.clear_bg();
|
||||
/// assert!(runes.iter().all(|r| r.bg == None))
|
||||
pub fn clear_bg(mut self) -> Self {
|
||||
for r in self.0.iter_mut() {
|
||||
r.bg = None;
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
pub fn bold(mut self) -> Self {
|
||||
for r in self.0.iter_mut() {
|
||||
r.bold = true;
|
||||
|
@ -154,6 +247,14 @@ impl Runes {
|
|||
self
|
||||
}
|
||||
|
||||
/// Append runes or a string displayable object to the Runes
|
||||
///
|
||||
/// Example:
|
||||
/// ```
|
||||
/// use arkham::prelude::*;
|
||||
/// let mut runes = "This is a test string. ".to_runes();
|
||||
/// runes.add("This is a colored string".to_runes().fg(Color::Blue));
|
||||
/// runes.add("This is another basic string");
|
||||
pub fn add<R>(&mut self, runes: R)
|
||||
where
|
||||
R: Into<Runes>,
|
||||
|
|
11
src/view.rs
11
src/view.rs
|
@ -148,6 +148,8 @@ impl View {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use crossterm::style::Color;
|
||||
|
||||
use crate::{geometry::Rect, runes::Rune};
|
||||
|
||||
use super::View;
|
||||
|
@ -242,4 +244,13 @@ mod tests {
|
|||
assert_eq!(view.0[2][1].content, Some('X'));
|
||||
assert_eq!(view.0[2][2].content, Some('X'));
|
||||
}
|
||||
|
||||
#[test]
|
||||
pub fn test_color_fill() {
|
||||
let mut view = View::new((3, 3));
|
||||
view.fill_all(Color::Red);
|
||||
assert!(view
|
||||
.iter()
|
||||
.all(|rs| rs.iter().all(|r| r.bg == Some(Color::Red))));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue