Debug API
This page documents the public rix/debug API.
Use debug through the unified Rix facade:
#include <rix.hpp>Then access debug helpers with:
rix.debugThe debug API provides helpers for:
printing values
printing to stderr
debug-only printing
formatting strings
appending formatted strings
inspecting values
small example outputrix/debug is designed for examples, local development, quick checks, tests, and small tools.
For real Vix application logs, prefer the Vix logging system:
vix::logPackage
The debug package is:
rix/debugFor facade usage, install:
vix add rix/rix
vix installIn vix.app:
deps = [
"rix/rix",
]For independent package usage, install:
vix add rix/debug
vix installIn vix.app:
deps = [
"rix/debug",
]Header
Facade usage:
#include <rix.hpp>Independent usage:
#include <rix/debug.hpp>Most application examples should use the facade.
Facade member
The debug facade member is:
rix.debugExample:
#include <rix.hpp>
int main()
{
rix.debug.print("Hello", "Rix");
return 0;
}Main helpers
Common debug helpers are:
rix.debug.print(...)
rix.debug.eprint(...)
rix.debug.dprint(...)
rix.debug.sprint(...)
rix.debug.format(...)
rix.debug.format.append(...)
rix.debug.format.to(...)
rix.debug.inspect(...)Print values
Use:
rix.debug.print(...)Example:
#include <rix.hpp>
int main()
{
rix.debug.print("Hello", "Rix");
rix.debug.print("count:", 3);
return 0;
}print writes values separated by spaces and adds a newline.
Print to stderr
Use:
rix.debug.eprint(...)Example:
#include <rix.hpp>
int main()
{
rix.debug.eprint("error:", "something failed");
return 0;
}Use eprint for example errors, diagnostics, and test output.
For production logs in a Vix app, prefer:
vix::logDebug-only print
Use:
rix.debug.dprint(...)Example:
#include <rix.hpp>
int main()
{
rix.debug.dprint("debug value:", 42);
return 0;
}Use dprint for temporary debug messages.
Format values into a string
Use:
const auto text = rix.debug.format(
"Package: {}",
"rix/debug");Example:
#include <rix.hpp>
int main()
{
const auto text = rix.debug.format(
"Package: {}, version: {}",
"rix/debug",
1);
rix.debug.print(text);
return 0;
}Placeholder syntax
The formatter supports simple placeholders.
Automatic indexing:
rix.debug.format("Hello, {}", "Rix");Explicit positional indexing:
rix.debug.format("{0} uses {1}", "Rix", "C++");Escaped braces:
rix.debug.format("{{ package }} = {}", "ready");Supported placeholder forms:
{}
{0}
{1}
{2}
{{
}}Format specifiers are intentionally not supported:
{:>10}
{:.2f}
{:04d}The formatter is small on purpose.
Automatic placeholders
const auto message = rix.debug.format(
"Hello, {}",
"Ada");Output shape:
Hello, AdaExplicit placeholders
const auto message = rix.debug.format(
"{0} writes {1}",
"Ada",
"C++");Output shape:
Ada writes C++Do not mix automatic and explicit indexing in the same format string.
Wrong:
rix.debug.format("{} {0}", "Ada");Use one style:
rix.debug.format("{} {}", "Ada", "C++");or:
rix.debug.format("{0} {1}", "Ada", "C++");Append formatted output
Use:
rix.debug.format.append(out, "Hello {}", "Rix");Example:
#include <rix.hpp>
#include <string>
int main()
{
std::string out = "message: ";
rix.debug.format.append(
out,
"{}",
"ready");
rix.debug.print(out);
return 0;
}This appends formatted output to an existing string.
Replace a string with formatted output
Use:
rix.debug.format.to(out, "Package: {}", "rix/debug");Example:
#include <rix.hpp>
#include <string>
int main()
{
std::string out = "old value";
rix.debug.format.to(
out,
"Package: {}",
"rix/debug");
rix.debug.print(out);
return 0;
}This clears the string and writes the formatted output into it.
Format errors
Invalid format strings can throw rixlib::format_error.
Examples of invalid format strings:
rix.debug.format("{", "value");
rix.debug.format("}", "value");
rix.debug.format("{:>10}", "value");Handle format errors when formatting user-controlled format strings.
#include <rix.hpp>
int main()
{
try
{
const auto text = rix.debug.format("{", "value");
rix.debug.print(text);
}
catch (const rixlib::format_error &error)
{
rix.debug.eprint("format error:", error.what());
return 1;
}
return 0;
}For fixed application format strings, this is usually not necessary.
Inspect values
Use:
rix.debug.inspect(value);Example:
#include <rix.hpp>
#include <string>
#include <vector>
int main()
{
std::vector<std::string> values = {
"Ada",
"C++",
"Rix"};
rix.debug.inspect(values);
return 0;
}inspect is useful for examples, tests, and quick diagnostics.
Sprint values into a string
Use:
const auto text = rix.debug.sprint("Hello", "Rix");Example:
#include <rix.hpp>
int main()
{
const auto text = rix.debug.sprint(
"Hello",
"Rix",
2026);
rix.debug.print(text);
return 0;
}sprint uses the debug rendering pipeline and returns a string.
Complete debug example
#include <rix.hpp>
int main()
{
rix.debug.print("Hello", "Rix");
const std::string package = rix.debug.format(
"Package: {}",
"rix/rix");
rix.debug.print(package);
rix.debug.eprint("stderr:", "diagnostic message");
rix.debug.inspect(package);
return 0;
}Run:
vix run debug.cppCSV debug example
#include <rix.hpp>
int main()
{
const auto table = rix.csv.parse(
"name,language\n"
"Ada,C++\n"
"Gaspard,Vix\n");
rix.debug.print("rows:", table.size());
rix.debug.inspect(table);
return 0;
}This uses:
rix.csv
rix.debugso the unified facade is the right dependency.
PDF debug example
#include <rix.hpp>
int main()
{
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, "debug-pdf.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:", "debug-pdf.pdf");
return 0;
}Auth debug example
#include <rix.hpp>
int main()
{
auto auth = rix.auth.memory();
auto registered = auth.register_user({
"ada@example.com",
"correct-password"});
if (registered.failed())
{
rix.debug.eprint(
"auth error:",
rix.auth.error.to_string(registered.error()),
registered.error().message());
return 1;
}
rix.debug.print("registered:", registered.value().email());
return 0;
}Do not print passwords, password hashes, raw tokens, or session ids in production output.
Logging note
rix.debug includes a small debug logging helper for simple development output.
Example shape:
rix.debug.log("loaded {} rows", table.size());
rix.debug.log.warn("slow path: {}", "csv parse");
rix.debug.log.error("failed: {}", "invalid input");This is useful for examples and local tools.
For real Vix application logging, prefer:
vix::logDo not design production Vix apps around rix.debug.log.
Production logging
In a Vix application, prefer Vix logging for application logs.
Use rix.debug for:
examples
tests
small tools
temporary diagnostics
formatting helpers
inspection helpersUse vix::log for:
production logs
HTTP request logs
service logs
deployment diagnostics
runtime eventsUse in a Vix project
Create a Vix app:
vix new rix-debug-api --app
cd rix-debug-apiAdd Rix:
vix add rix/rix
vix installMake sure vix.app contains:
deps = [
"rix/rix",
]Use in src/main.cpp:
#include <rix.hpp>Build and run:
vix build
vix runSingle-file usage
Create a file:
mkdir -p ~/rix-debug-api
cd ~/rix-debug-api
touch debug.cppAdd:
#include <rix.hpp>
int main()
{
rix.debug.print("Hello from rix.debug");
return 0;
}Run:
vix run debug.cppIf Rix is not available globally:
vix install -g rix/rix
vix run debug.cppIndependent usage
Install only debug:
vix add rix/debug
vix installIn vix.app:
deps = [
"rix/debug",
]Then include:
#include <rix/debug.hpp>Example:
#include <rix/debug.hpp>
int main()
{
auto debug = rixlib::debug::module();
debug.print("Hello from independent rix/debug");
const auto text = debug.format(
"Package: {}",
"rix/debug");
debug.print(text);
return 0;
}Use independent package APIs when you intentionally do not want the unified facade.
For most documentation and application examples, prefer:
#include <rix.hpp>and:
rix.debugEnable only debug in the facade
Use feature macros when you want the facade style but only want debug mounted:
#define RIX_ENABLE_DEBUG
#include <rix.hpp>
int main()
{
rix.debug.print("Hello from debug-only facade");
return 0;
}When at least one RIX_ENABLE_* macro is defined, only selected modules are mounted.
Enable debug with another package
CSV and debug:
#define RIX_ENABLE_CSV
#define RIX_ENABLE_DEBUG
#include <rix.hpp>
int main()
{
const auto table = rix.csv.parse(
"name\n"
"Ada\n");
rix.debug.print("rows:", table.size());
return 0;
}PDF and debug:
#define RIX_ENABLE_PDF
#define RIX_ENABLE_DEBUG
#include <rix.hpp>
int main()
{
auto doc = rix.pdf.document();
rix.debug.print("PDF ready");
return 0;
}Auth and debug:
#define RIX_ENABLE_AUTH
#define RIX_ENABLE_DEBUG
#include <rix.hpp>
int main()
{
auto auth = rix.auth.memory();
rix.debug.print("auth ready");
return 0;
}Format API reference
rix.debug.format supports:
operator()(std::string_view fmt, const Args &...args)
append(std::string &out, std::string_view fmt, const Args &...args)
to(std::string &out, std::string_view fmt, const Args &...args)Usage:
const auto text = rix.debug.format("Hello {}", "Rix");
std::string out;
rix.debug.format.append(out, "A {}", "B");
rix.debug.format.to(out, "C {}", "D");Debug facade API reference
rix.debug exposes:
format
log
inspect
print(...)
eprint(...)
dprint(...)
sprint(...)Use:
rix.debug.print("Hello", "Rix");
rix.debug.eprint("error:", "failed");
rix.debug.dprint("debug:", 42);
auto text = rix.debug.sprint("Hello", "Rix");Common mistakes
Forgetting to install Rix
If your code uses:
#include <rix.hpp>install:
vix add rix/rix
vix installIf your code uses:
#include <rix/debug.hpp>install:
vix add rix/debug
vix installPutting Rix in packages
Wrong:
packages = [
"rix/debug",
]Correct:
deps = [
"rix/debug",
]deps is for Vix Registry packages.
packages is for CMake package discovery.
Installing rix/debug but including <rix.hpp>
If your code uses:
#include <rix.hpp>then install:
vix add rix/rix
vix installIf your code uses:
#include <rix/debug.hpp>then install:
vix add rix/debug
vix installUsing format specifiers
This is not supported:
rix.debug.format("{:.2f}", 3.14);Use simple placeholders:
rix.debug.format("value: {}", 3.14);Mixing automatic and explicit indexes
Wrong:
rix.debug.format("{} {0}", "Ada");Correct:
rix.debug.format("{} {}", "Ada", "C++");or:
rix.debug.format("{0} {1}", "Ada", "C++");Using rix.debug.log for production logs
rix.debug.log is a small development helper.
For Vix application logs, prefer:
vix::logPrinting sensitive values
Avoid printing:
passwords
password hashes
raw tokens
session ids
private keys
secretsThis matters especially when using rix.auth.
Mixing facade and independent usage
Avoid this without a clear reason:
#include <rix.hpp>
#include <rix/debug.hpp>Use one style per file.
Facade:
#include <rix.hpp>Independent:
#include <rix/debug.hpp>What you should remember
Print:
rix.debug.print("Hello", "Rix");Print errors:
rix.debug.eprint("error:", "failed");Format:
const auto text = rix.debug.format(
"Package: {}",
"rix/debug");Inspect:
rix.debug.inspect(value);Use the facade for most examples:
#include <rix.hpp>and:
rix.debugFor project usage:
vix add rix/rix
vix installand keep:
deps = [
"rix/rix",
]For production Vix application logs, prefer:
vix::logNext step
Continue with the PDF API.
Next: PDF API