1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
#![forbid(unsafe_code)]
#![warn(missing_docs)]
/*!
A library designed to provide a curses alternative.
Explaining things is hard, so here's an example:
```
use yacll::Yogurt;
fn main() -> yacll::Result<()> {
let mut y = Yogurt::new();
// does not add newline
y.print("Hello, world!\n")?;
// flush the buffer (print just queues things for execution)
y.flush()?;
Ok(())
}
// try running `$ cargo run --example=quickstart` if you have the repository cloned!
```
*/
pub use crossterm::terminal::ClearType as ClrT;
use std::io::{stdout, Stdout};
use thiserror::Error;
mod output;
pub mod stylize;
pub use output::*;
pub mod input;
/// **Y**et An**o**ther Data Stora**g**e **U** St**r**uc**t**. Main struct for methods.
///
/// Unless a method specifies it flushes the buffer, calling the [`flush`](Yogurt::flush) method will be required for the changes to take effect.
#[derive(Debug)]
pub struct Yogurt {
stdout: Stdout,
/// Terminal size before entering alternate mode
size: Option<Point>,
}
impl Yogurt {
/// Create a new yogurt.
pub fn new() -> Self {
Yogurt {
stdout: stdout(),
size: None,
}
}
}
impl Default for Yogurt {
fn default() -> Self {
Yogurt::new()
}
}
/// A point on the screen.
#[derive(Debug, Copy, Clone)]
pub struct Point {
/// Which column this point is on.
pub x: u16,
/// Which row this point is on.
pub y: u16,
}
impl From<(u16, u16)> for Point {
/// Convert a tuple to a point. The first tuple value is interpreted as `x`, while the second is interpreted as `y`.
fn from(t: (u16, u16)) -> Self {
Point { x: t.0, y: t.1 }
}
}
impl From<Point> for (u16, u16) {
fn from(point: Point) -> Self {
(point.x, point.y)
}
}
/// **Y**et **A**nother E**rr**or enum.
#[non_exhaustive]
#[derive(Error, Debug)]
pub enum Yarr {
/// An IO error.
#[error(transparent)]
IO(#[from] std::io::Error),
/// Tried to use something that depended on alternate mode, but wasn't in it already.
#[error("tried to use something that depended on alternate mode, but wasn't in it already")]
NotInAltMode,
/// An error converting crossterm's KeyCode type to yacll's KeyCode type. This error will never
/// appear in public interfaces (because it should be impossible), so you do not have to worry about it.
#[error("tried to convert a crossterm keycode to a yacll keycode but failed")]
FromCrossKeyCodeError,
}
/// Result with the given type and an instance of `Yarr`.
pub type Result<T> = core::result::Result<T, Yarr>;