summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Bridle <ben@derelict.engineering>2025-04-27 12:19:16 +1200
committerBen Bridle <ben@derelict.engineering>2025-04-27 12:19:48 +1200
commitf8dbafda42e6395a69c30ea3fc95caa45313cb7a (patch)
tree4413b6f11e7eee6e94b016ac21459cc598f4e071
downloadinked-f8dbafda42e6395a69c30ea3fc95caa45313cb7a.zip
Initial commit
-rw-r--r--.gitignore1
-rw-r--r--Cargo.lock101
-rw-r--r--Cargo.toml7
-rw-r--r--src/colour.rs26
-rw-r--r--src/fragment.rs109
-rw-r--r--src/lib.rs16
-rw-r--r--src/string.rs72
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() ],
+ }
+ }
+}