# RConsole
A WebSocket-based logging library for Rust — send structured log messages to the [NConsole](https://drive.google.com/drive/folders/1P4cqXhalzsiPtrVAKWvoD9tK_pt9ZpzJ?usp=share_link) desktop app. Mirrors the API of the Flutter `nconsole` package.

## Installation
Add dependency to `Cargo.toml`:
```toml
[dependencies]
rconsole = "1.0.1"
```
Desktop app download: [NConsole](https://drive.google.com/drive/folders/1P4cqXhalzsiPtrVAKWvoD9tK_pt9ZpzJ?usp=share_link)
## Quick Start
```rust
use rconsole::*;
use serde_json::json;
fn main() {
// Point to your NConsole server
NConsole::set_uri("192.168.1.100");
// Log with mixed types — like console.log(a, b, c) in JavaScript
nlog!("Hello from Rust!", 42, true, json!({"key": "val"}));
ninfo!("Server started on port", 8080);
nwarn!("Memory usage:", 85.5, "%");
nerror!("Connection failed", json!({"code": 500}));
// Grouped logging
ngroup!("HTTP Request");
nlog!("GET", "/api/users");
nlog!("Status:", 200);
ngroup_end!();
// Collapsed group
ngroup_collapsed!("Response Body");
nlog!(json!({"users": [{"name": "Alex", "age": 25}]}));
ngroup_end!();
// Clear console
nclear!();
}
```
## API
### Configuration
```rust
use rconsole::NConsole;
// Set WebSocket URI (auto-normalizes: adds ws:// and :9090 if needed)
NConsole::set_uri("192.168.1.100"); // → ws://192.168.1.100:9090
NConsole::set_uri("localhost:3000"); // → ws://localhost:3000
NConsole::set_uri("ws://example.com"); // → kept as-is
// Enable/disable logging
NConsole::set_enable(false); // disable (all log calls become no-ops)
NConsole::set_enable(true); // enable
// Check status
let enabled = NConsole::is_enable();
let uri = NConsole::uri();
```
### Macros (recommended — supports mixed types)
| `nlog!(a, b, c)` | `console.log(a, b, c)` |
| `ninfo!(a, b)` | `console.info(a, b)` |
| `nwarn!(a, b)` | `console.warn(a, b)` |
| `nerror!(a, b)` | `console.error(a, b)` |
| `ngroup!("label")` | `console.group("label")` |
| `ngroup_collapsed!("label")` | `console.groupCollapsed("label")` |
| `ngroup_end!()` | `console.groupEnd()` |
| `nclear!()` | `console.clear()` |
Each argument can be any type that implements `serde::Serialize` — strings, numbers, bools, structs, `serde_json::Value`, etc.
```rust
#[derive(serde::Serialize)]
struct User { name: String, age: u32 }
let user = User { name: "Alex".into(), age: 25 };
nlog!("User logged in:", user);
```
### Method API (homogeneous types only)
```rust
use rconsole::NConsole;
NConsole::log(&["Hello", "World"]);
NConsole::info(&["Server started"]);
NConsole::warn(&["High memory usage"]);
NConsole::error(&["Connection failed"]);
NConsole::group("Request #1");
NConsole::group_end();
NConsole::clear();
```
### Log Listener
```rust
use rconsole::{NConsole, LogType};
});
```
## Log Types
| `log` | Standard log message |
| `info` | Informational message |
| `warn` | Warning message |
| `error` | Error message |
| `group` | Start a named log group |
| `groupCollapsed` | Start a collapsed log group |
| `groupEnd` | End the current log group |
| `clear` | Clear the console |
## Architecture
```
src/
├── lib.rs # Crate root, re-exports
├── macros.rs # nlog!, ninfo!, nwarn!, nerror!, etc.
├── domain/ # Pure types (no dependencies)
│ ├── log_type.rs # LogType enum
│ └── log_arg.rs # LogArg enum
├── console/ # Core logic
│ ├── uri.rs # URI normalization
│ ├── client_info.rs # ClientInfo struct
│ └── web_console.rs # WebConsole singleton (thread-safe)
├── infrastructure/ # Transport
│ └── websocket.rs # WsConnection wrapper
└── services/ # Public API
└── logger.rs # NConsole façade
```
## Thread Safety
All methods are thread-safe. The internal `WebConsole` singleton is protected by `Mutex` via `once_cell::sync::Lazy`.
## Author
NghiNV
## License
MIT