Rix is the official package layer for Vix.cpp Browse packages
Skip to content

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:

cpp
#include <rix.hpp>

and access Debug through:

cpp
rix.debug

What rix/debug provides

rix/debug provides a small API for:

txt
printing values
printing errors
debug-only prints
formatting strings
formatting printed values into strings
inspecting values
simple local diagnostics

The 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:

bash
mkdir -p ~/rix-debug-example
cd ~/rix-debug-example
touch debug.cpp

Add:

cpp
#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:

bash
vix run debug.cpp

If Rix is not available yet for single-file usage:

bash
vix install -g rix/rix
vix run debug.cpp

Expected output

The output should look like this:

txt
Hello Rix
Package: rix/rix

The 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:

bash
vix add rix/rix
vix install

In vix.app, declare:

txt
deps = [
  "rix/rix",
]

If you want to use only the independent debug package, install:

bash
vix add rix/debug
vix install

and declare:

txt
deps = [
  "rix/debug",
]

For most documentation examples, prefer the facade package:

cpp
#include <rix.hpp>

Use:

cpp
rix.debug.print(...)

Example:

cpp
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.

Use:

cpp
rix.debug.eprint(...)

Example:

cpp
rix.debug.eprint("error:", "something failed");

eprint writes to stderr.

Use it for local error output in examples.

Debug-only print

Use:

cpp
rix.debug.dprint(...)

Example:

cpp
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:

cpp
rix.debug.format(...)

Example:

cpp
const auto message =
    rix.debug.format("Package: {}", "rix/rix");

rix.debug.print(message);

Output:

txt
Package: rix/rix

Formatting placeholders

rix.debug.format supports simple placeholders:

txt
{}      automatic argument indexing
{0}     explicit positional indexing
{{      escaped opening brace
}}      escaped closing brace

Examples:

cpp
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:

cpp
auto message =
    rix.debug.format("{} uses {}", "Rix", "C++");

Result:

txt
Rix uses C++

Explicit placeholders

Use {0}, {1}, and other numeric indexes when the order should be explicit:

cpp
auto message =
    rix.debug.format("{0} + {0} = {1}", "C++", "Vix.cpp");

Result:

txt
C++ + C++ = Vix.cpp

Do 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:

cpp
auto message =
    rix.debug.format("{{ package }} = {}", "rix/debug");

Result:

txt
{ package } = rix/debug

Unsupported format specifiers

rix.debug.format intentionally keeps formatting small.

It does not support format specifiers such as:

txt
{:>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:

cpp
std::string out = "Rix: ";

rix.debug.format.append(
    out,
    "{}",
    "debug");

rix.debug.print(out);

Expected output:

txt
Rix: debug

Replace a string with formatted output

Use:

cpp
rix.debug.format.to(out, "Package: {}", "rix/debug");

Example:

cpp
std::string out;

rix.debug.format.to(
    out,
    "Package: {}",
    "rix/debug");

rix.debug.print(out);

Sprint

Use:

cpp
rix.debug.sprint(...)

when you want the same value rendering as print, but returned as a string.

Example:

cpp
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:

cpp
rix.debug.inspect(value);

Example:

cpp
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:

cpp
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:

cpp
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:

txt
examples
small tools
local diagnostics
quick prints
tests
documentation snippets

Use Vix logging for:

txt
production logs
structured application logs
request logs
service logs
deployment diagnostics
runtime observability

In other words:

txt
rix.debug -> simple development output
Vix logging -> real application logging

Use in a Vix project

Create an application:

bash
vix new debug-app --app
cd debug-app

Add Rix:

bash
vix add rix/rix
vix install

In vix.app, add:

txt
deps = [
  "rix/rix",
]

A small manifest can look like this:

txt
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:

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:

bash
vix build
vix run

Single-file usage

For small scripts, examples, and experiments:

bash
vix run debug.cpp

If Rix is installed globally for single-file usage:

bash
vix install -g rix/rix
vix run debug.cpp

For project usage, prefer:

bash
vix add rix/rix
vix install

and keep the dependency in vix.app:

txt
deps = [
  "rix/rix",
]

Facade usage

The recommended documentation style is:

cpp
#include <rix.hpp>

Then:

cpp
rix.debug.print("Hello", "Rix");

This keeps Debug available through the same public object as the other Rix packages:

cpp
rix.csv
rix.debug
rix.auth
rix.pdf

Independent package usage

If your project only needs Debug, install:

bash
vix add rix/debug
vix install

In vix.app:

txt
deps = [
  "rix/debug",
]

Then include:

cpp
#include <rix/debug.hpp>

Use this style when you do not need the unified rix.* facade.

For most application documentation, prefer:

cpp
#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:

cpp
#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:

cpp
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:

cpp
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:

txt
plain-text passwords
password hashes
session ids
raw token values

Debug with PDF

Debug is useful when checking PDF generation:

cpp
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:

txt
plain-text passwords
password hashes
session ids
raw token values

This matters especially when using rix/auth.

Mixing automatic and explicit format indexes

Wrong:

cpp
rix.debug.format("{} {0}", "Rix");

Use either automatic:

cpp
rix.debug.format("{} {}", "Rix", "Debug");

or explicit:

cpp
rix.debug.format("{0} {1}", "Rix", "Debug");

Expecting advanced format specifiers

This is not supported:

cpp
rix.debug.format("{:.2f}", 3.14159);

Use simple placeholders.

Forgetting deps

For a Vix project, do not put Rix packages in packages.

Use:

txt
deps = [
  "rix/rix",
]

packages is for CMake package discovery.

deps is for Vix Registry packages.

What you should remember

Use the facade:

cpp
#include <rix.hpp>

Print values:

cpp
rix.debug.print("Hello", "Rix");

Print errors:

cpp
rix.debug.eprint("error:", "message");

Format strings:

cpp
auto message = rix.debug.format("Package: {}", "rix/debug");

Inspect values:

cpp
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:

bash
vix add rix/rix
vix install

and use:

txt
deps = [
  "rix/rix",
]

Next step

Learn formatting.

Next: Formatting

Released under the MIT License.