saydbg 0.2.1

A tiny macro for conditional debug printing with optional colored output.
Documentation
# πŸͺΆ saydbg

[![Crates.io](https://img.shields.io/crates/v/saydbg.svg)](https://crates.io/crates/saydbg)
[![Docs.rs](https://docs.rs/saydbg/badge.svg)](https://docs.rs/saydbg)
[![License](https://img.shields.io/crates/l/saydbg)](./LICENSE)

A **tiny, dependency-light macro crate** for conditional debug printing β€” designed to give you  
`println!`-style logging in debug builds, with optional color, timestamps, and file logging.  
In release mode, all debug macros are **completely compiled out** (zero cost).

---

## ✨ Features

βœ… Simple `println!`-style usage  
βœ… Works only in debug mode (`cfg(debug_assertions)`)  
βœ… Optional **colored** output (`--features color`)  
βœ… Optional **timestamps** (`--features timestamp`)  
βœ… Optional **file logging** (`--features file`)  
βœ… Zero-cost in release builds  
βœ… MIT licensed β€” free for any project

---

## πŸ“¦ Installation

Add to your project’s `Cargo.toml`:

```toml
[dependencies]
saydbg = "0.2"
```

Optionally enable features:

```toml
[dependencies]
saydbg = { version = "0.2", features = ["color", "timestamp", "file"] }
```

---

## 🧠 Example

```rust
use saydbg::{saydbg, saywarn, sayerr, saytrace, saylog};

fn main() {
    saydbg!("Connected to database");
    saywarn!("Missing optional config file");
    saytrace!("Query took {:?} ms", 5);
    sayerr!("User not found: {}", "admin");
    saylog!("Server started successfully");
}
```

### 🧱 Default Output (Debug build)

```
[debug] Connected to database
[warn] Missing optional config file
[trace] Query took 5 ms
[error] User not found: admin
[log] Server started successfully
```

### 🌈 With `--features color`

Colors (blue, yellow, red, gray, green) are added for easy scanning.

### πŸ•’ With `--features timestamp`

```
[2025-10-08 12:11:47] [debug] Connected to database
[2025-10-08 12:11:47] [warn] Missing optional config file
```

---

## βš™οΈ Macros

| Macro       | Description                     | Color  | Stream   | Builds     |
| ----------- | ------------------------------- | ------ | -------- | ---------- |
| `saydbg!`   | General debug info              | Blue   | `stdout` | Debug only |
| `sayerr!`   | Errors                          | Red    | `stderr` | Debug only |
| `saywarn!`  | Warnings                        | Yellow | `stdout` | Debug only |
| `saytrace!` | Verbose trace info              | Gray   | `stdout` | Debug only |
| `saylog!`   | Always-on log (even in release) | Green  | `stdout` | All builds |

---

## πŸš€ Why use `saydbg`?

Because sometimes you don’t need a full logger β€” just some conditional, colorful debug messages that disappear in release builds.

`saydbg` sits between:

- ✏️ `println!()` β€” simple but always prints
- 🧱 `log` or `tracing` β€” powerful but heavy for small tools

Perfect for:

- CLI utilities
- Tauri or WASM apps
- Embedded debugging
- Classroom or educational projects
- Quick prototypes or experiments

---

## πŸ”§ Feature Flags

| Feature     | Description                                                                  | Default |
| ----------- | ---------------------------------------------------------------------------- | ------- |
| `color`     | Enables colored log labels via [`colored`]https://crates.io/crates/colored | ❌      |
| `timestamp` | Adds local timestamps using [`chrono`]https://crates.io/crates/chrono      | ❌      |
| `file`      | Writes log output to a file (`saydbg.log`) in addition to stdout/stderr      | ❌      |

Enable all for maximum clarity:

```toml
[dependencies]
saydbg = { version = "0.2", features = ["color", "timestamp", "file"] }
```

---

## πŸ—‚οΈ File Logging (Optional Feature)

When compiled with the `file` feature, `saydbg` automatically mirrors all console output to a persistent log file (`saydbg.log` by default).

### Enabling

Add the feature flag in your `Cargo.toml`:

```toml
[dependencies]
saydbg = { version = "0.2", features = ["file"] }
```

or on the command line:

```bash
cargo run --features "file"
```

### Default Behavior

When enabled, each macro (e.g., `saydbg!`, `saywarn!`, `sayerr!`) appends its message to a file in the working directory:

```
saydbg.log
```

Example content:

```
[2025-10-09 11:32:17] [debug] Connected to database
[2025-10-09 11:32:18] [warn] User 'ryonb' not found in DB β€” inserting.
```

### Manual Logging

You can also call the helper directly:

```rust
use saydbg::write_to_log_file;

write_to_log_file("[info] Manual entry from external system");
```

### Thread Safety

`saydbg` uses a global, thread-safe file handle (via `once_cell` + `Mutex`) to avoid race conditions across threads or async tasks.

This means you can freely log from multiple tasks without worrying about file corruption or interleaving.

---

## 🧩 Example Project Integration

```rust
use saydbg::{saydbg, saywarn, sayerr};

pub fn connect_db() {
    saydbg!("Connecting to database...");
    // ...
    saywarn!("Connection is slow, retrying...");
    sayerr!("Database unreachable after retries");
}
```

All of these compile away completely in release:

```bash
cargo run --release
# (no debug output at all)
```

---

## πŸ“œ License

Licensed under the [MIT License](./LICENSE).

---

## πŸ’‘ Author

**Ryon Boswell** β€” [@crookedlungs](https://github.com/crookedlungs)  
A developer and educator creating lightweight, modular tools for Rust and education.

---

## 🌟 Contributing

Pull requests, feature ideas, and improvements are welcome.  
You can clone this repo, modify the macros, or submit suggestions on [GitHub](https://github.com/crookedlungs/saydbg).

---

> πŸ¦€ _"Debug smart, release clean."_ β€” `saydbg`