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

Debug Quick Start ​

This page shows the fastest way to use rix/debug.

The examples use the public Rix facade:

cpp
#include <rix.hpp>

and access Debug through:

cpp
rix.debug

rix/debug is useful for examples, quick tools, local diagnostics, and development-time output.

For production application logs, prefer the Vix logging system.

What you will build ​

You will create a small C++ file that:

txt
prints values
prints an error message
formats a string
stores printed output in a string
inspects a value
runs with vix run

Create a working folder ​

Create a small folder in your home directory:

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

Add the example ​

Open:

txt
debug.cpp

Add:

cpp
#include <rix.hpp>

#include <string>

int main()
{
  rix.debug.print("== rix/debug quick start ==");

  rix.debug.print("Hello", "Rix");
  rix.debug.print("rows:", 3);
  rix.debug.print("ready:", true);

  const std::string package =
      rix.debug.format("Package: {}", "rix/debug");

  rix.debug.print(package);

  const std::string line =
      rix.debug.sprint("generated line:", package);

  rix.debug.print(line);

  rix.debug.eprint("stderr example:", "this is an error-style message");

  rix.debug.inspect(package);

  return 0;
}

Run the file ​

Run:

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 similar to this:

txt
== rix/debug quick start ==
Hello Rix
rows: 3
ready: true
Package: rix/debug
generated line: Package: rix/debug

The eprint output is written to stderr.

The exact inspect output depends on the inspected value.

Use:

cpp
rix.debug.print(...)

Example:

cpp
rix.debug.print("Hello", "Rix");
rix.debug.print("count:", 3);
rix.debug.print("ok:", true);

print writes values separated by spaces and adds a newline.

This is the most common rix/debug helper.

Use:

cpp
rix.debug.eprint(...)

Example:

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

eprint writes to stderr.

Use it for examples, local diagnostics, and command-line tools.

Debug-only print ​

Use:

cpp
rix.debug.dprint(...)

Example:

cpp
rix.debug.dprint("debug value:", 42);

Use this when the message is only useful while debugging.

Format a string ​

Use:

cpp
rix.debug.format(...)

Example:

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

rix.debug.print(message);

Output:

txt
Package: rix/debug

Automatic placeholders ​

Use {} to insert arguments in order:

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

Result:

txt
Rix uses C++

Explicit placeholders ​

Use {0}, {1}, and other indexes when you want explicit argument positions:

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

Result:

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

Do not mix automatic placeholders and explicit placeholders in the same format string.

Escape braces ​

Use double opening braces and double closing braces when you need literal braces:

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

Result:

txt
{ package } = rix/debug

Unsupported format specifiers ​

rix.debug.format is intentionally small.

It does not support format specifiers such as:

txt
{:.2f}
{:>10}
{:04d}

Use simple placeholders.

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
std::string out;

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

rix.debug.print(out);

Expected output:

txt
Package: rix/debug

Sprint values into a string ​

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

Inspect a value ​

Use:

cpp
rix.debug.inspect(value);

Example:

cpp
std::string package = "rix/debug";

rix.debug.inspect(package);

Inspection is useful when you want a clearer development-time view of a value.

Complete formatting example ​

cpp
#include <rix.hpp>

#include <string>

int main()
{
  const auto one =
      rix.debug.format("Hello, {}", "Ada");

  const auto two =
      rix.debug.format("{0} builds on {1}", "Rix", "Vix.cpp");

  const auto three =
      rix.debug.format("{{ module }} = {}", "debug");

  rix.debug.print(one);
  rix.debug.print(two);
  rix.debug.print(three);

  return 0;
}

Run:

bash
vix run debug.cpp

Expected output:

txt
Hello, Ada
Rix builds on Vix.cpp
{ module } = debug

Use in a Vix project ​

Create a Vix application:

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

Add Rix:

bash
vix add rix/rix
vix install

In vix.app, make sure Rix is listed under deps:

txt
deps = [
  "rix/rix",
]

A small vix.app 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, use:

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",
]

Use only Debug with the facade ​

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 is useful for lighter builds.

Use the independent package ​

For independent usage, install:

bash
vix add rix/debug
vix install

In vix.app:

txt
deps = [
  "rix/debug",
]

Then include the independent package header:

cpp
#include <rix/debug.hpp>

Use this style when a project only needs Debug and does not need the full unified Rix facade.

For most application documentation, prefer:

cpp
#include <rix.hpp>

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 examples that show Auth results:

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;
}

rix.debug.print("registered:", registered.value().email());

Do not print authentication secrets in production.

Avoid printing:

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

Debug with PDF ​

Debug is useful for checking whether a PDF was created:

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");

Logging note ​

rix/debug is not the main production logging API.

Use rix.debug.print, rix.debug.eprint, rix.debug.dprint, rix.debug.format, and rix.debug.inspect for development output and documentation examples.

For real application logs, prefer the Vix logging system.

Use this rule:

txt
rix.debug -> examples, local diagnostics, quick tools
Vix logging -> production logs, service logs, request logs

Common mistakes ​

Using debug output as production logging ​

rix.debug is for simple development output.

For real application logs, use the Vix logging system.

Printing secrets ​

Do not print:

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

This matters especially when using rix/auth.

Mixing placeholder styles ​

Wrong:

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

Use automatic placeholders:

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

or explicit placeholders:

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

Expecting advanced format specifiers ​

Wrong:

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

Use simple placeholders:

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

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 to stderr:

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

Format strings:

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

Build printed output as a string:

cpp
auto line = rix.debug.sprint("rows:", 3);

Inspect values:

cpp
rix.debug.inspect(message);

For a Vix project, install Rix:

bash
vix add rix/rix
vix install

and use:

txt
deps = [
  "rix/rix",
]

Use rix.debug for examples and development output.

Prefer Vix logging for real application logs.

Next step ​

Learn the printing helpers.

Next: Printing

Released under the MIT License.