diff options
| author | Ben Bridle <ben@derelict.engineering> | 2025-04-27 12:19:16 +1200 | 
|---|---|---|
| committer | Ben Bridle <ben@derelict.engineering> | 2025-04-27 12:19:48 +1200 | 
| commit | f8dbafda42e6395a69c30ea3fc95caa45313cb7a (patch) | |
| tree | 4413b6f11e7eee6e94b016ac21459cc598f4e071 | |
| download | inked-f8dbafda42e6395a69c30ea3fc95caa45313cb7a.zip | |
Initial commit
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | Cargo.lock | 101 | ||||
| -rw-r--r-- | Cargo.toml | 7 | ||||
| -rw-r--r-- | src/colour.rs | 26 | ||||
| -rw-r--r-- | src/fragment.rs | 109 | ||||
| -rw-r--r-- | src/lib.rs | 16 | ||||
| -rw-r--r-- | src/string.rs | 72 | 
7 files changed, 332 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..98894f7 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,101 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "inked" +version = "0.1.0" +dependencies = [ + "termcolor", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "winapi-util" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..37cf225 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "inked" +version = "0.1.0" +edition = "2024" + +[dependencies] +termcolor = "1.4.1" diff --git a/src/colour.rs b/src/colour.rs new file mode 100644 index 0000000..96f854d --- /dev/null +++ b/src/colour.rs @@ -0,0 +1,26 @@ +#[derive(Clone, Copy, Debug)] +pub enum Colour { +    Black, +    Red, +    Green, +    Yellow, +    Blue, +    Magenta, +    Cyan, +    White, +} + +impl From<Colour> for termcolor::Color { +    fn from(c: Colour) -> Self { +        match c { +            Colour::Black   => termcolor::Color::Black, +            Colour::Red     => termcolor::Color::Red, +            Colour::Green   => termcolor::Color::Green, +            Colour::Yellow  => termcolor::Color::Yellow, +            Colour::Blue    => termcolor::Color::Blue, +            Colour::Magenta => termcolor::Color::Magenta, +            Colour::Cyan    => termcolor::Color::Cyan, +            Colour::White   => termcolor::Color::White, +        } +    } +} diff --git a/src/fragment.rs b/src/fragment.rs new file mode 100644 index 0000000..8663fd2 --- /dev/null +++ b/src/fragment.rs @@ -0,0 +1,109 @@ +use crate::*; + + +pub struct InkedFragment { +    pub string: String, +    pub colour: ColorSpec, +} + +impl InkedFragment { +    pub fn from(string: impl Into<String>) -> Self { +        Self { +            string: string.into(), +            colour: ColorSpec::new(), +        } +    } + +    pub fn to_string(self) -> InkedString { +        let mut string = InkedString::new(); +        string.push(self); +        string +    } + +    pub fn print(self)    { self.to_string().print(); } +    pub fn println(self)  { self.to_string().println(); } +    pub fn eprint(self)   { self.to_string().eprint(); } +    pub fn eprintln(self) { self.to_string().eprintln(); } + +    // ---------------------------------------- + +    pub fn set_colour(mut self, colour: Option<Colour>) -> Self { +        match colour { +            Some(colour) => self.colour.set_fg(Some(colour.into())), +            None => self.colour.set_fg(None), +        }; +        self +    } + +    pub fn set_bold(mut self, bold: bool) -> Self { +        self.colour.set_bold(bold); +        self +    } + +    pub fn set_dim(mut self, dim: bool) -> Self { +        self.colour.set_dimmed(dim); +        self +    } + +    // ---------------------------------------- + +    pub fn black(mut self) -> Self { +        self.colour.set_fg(Some(Color::Black)); +        self +    } + +    pub fn red(mut self) -> Self { +        self.colour.set_fg(Some(Color::Red)); +        self +    } + +    pub fn green(mut self) -> Self { +        self.colour.set_fg(Some(Color::Green)); +        self +    } + +    pub fn yellow(mut self) -> Self { +        self.colour.set_fg(Some(Color::Yellow)); +        self +    } + +    pub fn blue(mut self) -> Self { +        self.colour.set_fg(Some(Color::Blue)); +        self +    } + +    pub fn magenta(mut self) -> Self { +        self.colour.set_fg(Some(Color::Magenta)); +        self +    } + +    pub fn cyan(mut self) -> Self { +        self.colour.set_fg(Some(Color::Cyan)); +        self +    } + +    pub fn white(mut self) -> Self { +        self.colour.set_fg(Some(Color::White)); +        self +    } + +    pub fn bold(mut self) -> Self { +        self.colour.set_bold(true); +        self +    } + +    pub fn dim(mut self) -> Self { +        self.colour.set_dimmed(true); +        self +    } +} + + +impl From<String> for InkedFragment { +    fn from(string: std::string::String) -> Self { +        Self { +            string, +            colour: ColorSpec::new(), +        } +    } +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..f11f18f --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,16 @@ +mod colour; +mod fragment; +mod string; + +pub use colour::*; +pub use fragment::*; +pub use string::*; + +use termcolor::*; + + +#[macro_export] macro_rules! ink { +    ($($tokens:tt)*) => { +        $crate::InkedFragment::from(format!($($tokens)*)) +    }; +} diff --git a/src/string.rs b/src/string.rs new file mode 100644 index 0000000..7b34fc8 --- /dev/null +++ b/src/string.rs @@ -0,0 +1,72 @@ +use crate::*; + +use std::io::Write; +use std::sync::LazyLock; + + +static STDOUT_WRITER: LazyLock<BufferWriter> = LazyLock::new(|| +    BufferWriter::stdout(ColorChoice::Auto) +); + +static STDERR_WRITER: LazyLock<BufferWriter> = LazyLock::new(|| +    BufferWriter::stderr(ColorChoice::Auto) +); + + +pub struct InkedString { +    pub fragments: Vec<InkedFragment>, +} + +impl InkedString { +    pub fn new() -> Self { +        Self { +            fragments: Vec::new(), +        } +    } + +    pub fn push(&mut self, fragment: impl Into<InkedFragment>) { +        self.fragments.push(fragment.into()); +    } + +    pub fn append(&mut self, mut string: InkedString) { +        self.fragments.append(&mut string.fragments); +    } + +    pub fn print(mut self) { +        self.push(ink!("")); +        self.write_string(&STDOUT_WRITER) +    } + +    pub fn println(mut self) { +        self.push(ink!("\n")); +        self.write_string(&STDOUT_WRITER) +    } + +    pub fn eprint(mut self) { +        self.push(ink!("")); +        self.write_string(&STDERR_WRITER) +    } + +    pub fn eprintln(mut self) { +        self.push(ink!("\n")); +        self.write_string(&STDERR_WRITER) +    } + +    fn write_string(self, writer: &LazyLock<BufferWriter>) { +        let mut buffer = writer.buffer(); +        for fragment in &self.fragments { +            buffer.set_color(&fragment.colour).unwrap(); +            write!(buffer, "{}", fragment.string).unwrap(); +        } +        writer.print(&buffer).unwrap() +    } +} + + +impl From<String> for InkedString { +    fn from(string: std::string::String) -> Self { +        Self { +            fragments: vec![ string.into() ], +        } +    } +}  | 
