Debug
rix/debug is the Rix package for simple development-time output, formatting, printing, and inspection.
It is designed for examples, local diagnostics, learning, and small tools.
The examples on this page use the public Rix facade:
#include <rix.hpp>and access Debug through:
rix.debugWhat rix/debug provides
rix/debug provides a small API for:
printing values
printing errors
debug-only prints
formatting strings
formatting printed values into strings
inspecting values
simple local diagnosticsThe goal is to keep examples and development code easy to read.
For production application logs, prefer the Vix logging system.
Basic example
Create a file:
mkdir -p ~/rix-debug-example
cd ~/rix-debug-example
touch debug.cppAdd:
#include <rix.hpp>
#include <string>
int main()
{
rix.debug.print("Hello", "Rix");
const std::string package =
rix.debug.format("Package: {}", "rix/rix");
rix.debug.print(package);
rix.debug.eprint("error output:", "example");
rix.debug.inspect(package);
return 0;
}Run it:
vix run debug.cppIf Rix is not available yet for single-file usage:
vix install -g rix/rix
vix run debug.cppExpected output
The output should look like this:
Hello Rix
Package: rix/rixThe eprint output is written to stderr.
The exact inspection output depends on the value being inspected.
Install
For normal usage through the unified facade, install:
vix add rix/rix
vix installIn vix.app, declare:
deps = [
"rix/rix",
]If you want to use only the independent debug package, install:
vix add rix/debug
vix installand declare:
deps = [
"rix/debug",
]For most documentation examples, prefer the facade package:
#include <rix.hpp>Print values
Use:
rix.debug.print(...)Example:
rix.debug.print("Hello", "Rix");
rix.debug.print("rows:", 3);
rix.debug.print("ready:", true);print writes values separated by spaces and adds a trailing newline.
It is useful for examples and quick checks.
Print errors
Use:
rix.debug.eprint(...)Example:
rix.debug.eprint("error:", "something failed");eprint writes to stderr.
Use it for local error output in examples.
Debug-only print
Use:
rix.debug.dprint(...)Example:
rix.debug.dprint("debug value:", 42);Use dprint for debug-only output.
The exact behavior depends on the debug package configuration.
Format a string
Use:
rix.debug.format(...)Example:
const auto message =
rix.debug.format("Package: {}", "rix/rix");
rix.debug.print(message);Output:
Package: rix/rixFormatting placeholders
rix.debug.format supports simple placeholders:
{} automatic argument indexing
{0} explicit positional indexing
{{ escaped opening brace
}} escaped closing braceExamples:
auto a = rix.debug.format("Hello, {}", "Ada");
auto b = rix.debug.format(
"Value = {0}, name = {1}",
42,
"Ada");
auto c = rix.debug.format(
"{{ package }} = {}",
"rix/rix");Automatic placeholders
Use {} for automatic argument order:
auto message =
rix.debug.format("{} uses {}", "Rix", "C++");Result:
Rix uses C++Explicit placeholders
Use {0}, {1}, and other numeric indexes when the order should be explicit:
auto message =
rix.debug.format("{0} + {0} = {1}", "C++", "Vix.cpp");Result:
C++ + C++ = Vix.cppDo not mix automatic and explicit indexing in the same format string.
Escaped braces
Use double opening braces and double closing braces when you need literal braces:
auto message =
rix.debug.format("{{ package }} = {}", "rix/debug");Result:
{ package } = rix/debugUnsupported format specifiers
rix.debug.format intentionally keeps formatting small.
It does not support format specifiers such as:
{:>10}
{:.2f}
{:04d}Use simple placeholders for Rix debug formatting.
For advanced formatting, use another formatting library or normal C++ formatting tools where appropriate.
Append formatted output
You can append formatted text to an existing string:
std::string out = "Rix: ";
rix.debug.format.append(
out,
"{}",
"debug");
rix.debug.print(out);Expected output:
Rix: debugReplace a string with formatted output
Use:
rix.debug.format.to(out, "Package: {}", "rix/debug");Example:
std::string out;
rix.debug.format.to(
out,
"Package: {}",
"rix/debug");
rix.debug.print(out);Sprint
Use:
rix.debug.sprint(...)when you want the same value rendering as print, but returned as a string.
Example:
const auto line = rix.debug.sprint("rows:", 3);
rix.debug.print(line);This is useful when you want to build a message before printing or storing it.
Inspect values
Use:
rix.debug.inspect(value);Example:
std::string package = "rix/rix";
rix.debug.inspect(package);Inspection is useful during development when you want to see a value clearly.
Local debug output
rix/debug is useful in documentation examples because it keeps output simple:
rix.debug.print("registered user");
rix.debug.print("id:", user.id());
rix.debug.print("email:", user.email());It is also useful when testing other Rix packages:
const auto table = rix.csv.parse(input);
rix.debug.print("rows:", table.size());Logging note
rix.debug.log exists as a simple debug package component, but for real application logging prefer the Vix logging system.
Use rix.debug for:
examples
small tools
local diagnostics
quick prints
tests
documentation snippetsUse Vix logging for:
production logs
structured application logs
request logs
service logs
deployment diagnostics
runtime observabilityIn other words:
rix.debug -> simple development output
Vix logging -> real application loggingUse in a Vix project
Create an application:
vix new debug-app --app
cd debug-appAdd Rix:
vix add rix/rix
vix installIn vix.app, add:
deps = [
"rix/rix",
]A small manifest can look like this:
name = "debug-app"
type = "executable"
standard = "c++20"
output_dir = "bin"
sources = [
"src/main.cpp",
]
include_dirs = [
"include",
"src",
]
deps = [
"rix/rix",
]
packages = [
"vix",
]
links = [
"vix::vix",
]Then use Debug in src/main.cpp:
#include <rix.hpp>
int main()
{
rix.debug.print("Hello", "Rix");
const auto message =
rix.debug.format("Package: {}", "rix/debug");
rix.debug.print(message);
return 0;
}Build and run:
vix build
vix runSingle-file usage
For small scripts, examples, and experiments:
vix run debug.cppIf Rix is installed globally for single-file usage:
vix install -g rix/rix
vix run debug.cppFor project usage, prefer:
vix add rix/rix
vix installand keep the dependency in vix.app:
deps = [
"rix/rix",
]Facade usage
The recommended documentation style is:
#include <rix.hpp>Then:
rix.debug.print("Hello", "Rix");This keeps Debug available through the same public object as the other Rix packages:
rix.csv
rix.debug
rix.auth
rix.pdfIndependent package usage
If your project only needs Debug, install:
vix add rix/debug
vix installIn vix.app:
deps = [
"rix/debug",
]Then include:
#include <rix/debug.hpp>Use this style when you do not need the unified rix.* facade.
For most application documentation, prefer:
#include <rix.hpp>Lightweight facade usage
If you want the rix.* facade style but only want Debug mounted, define the feature macro before including rix.hpp:
#define RIX_ENABLE_DEBUG
#include <rix.hpp>
int main()
{
rix.debug.print("Hello", "Rix");
return 0;
}When at least one RIX_ENABLE_* macro is defined, only selected modules are mounted.
This keeps the facade style while reducing what gets included.
Debug with CSV
Debug is useful for printing parsed CSV data:
const auto table = rix.csv.parse(
"name,language\n"
"Ada,C++\n");
rix.debug.print("rows:", table.size());
for (const auto &row : table)
{
rix.debug.print("fields:", row.size());
}Debug with Auth
Debug is useful for documentation examples:
auto auth = rix.auth.memory();
auto registered = auth.register_user({
"ada@example.com",
"correct-password"});
if (registered.failed())
{
const auto &error = registered.error();
rix.debug.eprint(
"auth error:",
rix.auth.error.to_string(error),
error.message());
return 1;
}Do not print authentication secrets in production.
Avoid logging:
plain-text passwords
password hashes
session ids
raw token valuesDebug with PDF
Debug is useful when checking PDF generation:
auto doc = rix.pdf.document();
auto &page = doc.add_page();
page.text(
page.x_left(),
page.y_top(),
"Hello from rix.pdf");
auto saved = rix.pdf.save(doc, "example.pdf");
if (saved.failed())
{
rix.debug.eprint(
"pdf error:",
rix.pdf.error.to_string(saved.error()),
saved.error().message());
return 1;
}
rix.debug.print("created:", "example.pdf");Common mistakes
Using debug output as production logging
rix.debug is for simple development output.
For real application logs, prefer Vix logging.
Printing secrets
Do not print:
plain-text passwords
password hashes
session ids
raw token valuesThis matters especially when using rix/auth.
Mixing automatic and explicit format indexes
Wrong:
rix.debug.format("{} {0}", "Rix");Use either automatic:
rix.debug.format("{} {}", "Rix", "Debug");or explicit:
rix.debug.format("{0} {1}", "Rix", "Debug");Expecting advanced format specifiers
This is not supported:
rix.debug.format("{:.2f}", 3.14159);Use simple placeholders.
Forgetting deps
For a Vix project, do not put Rix packages in packages.
Use:
deps = [
"rix/rix",
]packages is for CMake package discovery.
deps is for Vix Registry packages.
What you should remember
Use the facade:
#include <rix.hpp>Print values:
rix.debug.print("Hello", "Rix");Print errors:
rix.debug.eprint("error:", "message");Format strings:
auto message = rix.debug.format("Package: {}", "rix/debug");Inspect values:
rix.debug.inspect(message);Use rix.debug for development output and examples.
Prefer Vix logging for real application logs.
For a Vix project, install Rix:
vix add rix/rix
vix installand use:
deps = [
"rix/rix",
]Next step
Learn formatting.
Next: Formatting