Format
This page explains the formatting helpers provided by rix/debug.
The examples use the public Rix facade:
#include <rix.hpp>and access formatting through:
rix.debug.formatFormatting is useful when you want to build a string with placeholders before printing it, storing it, returning it, or passing it to another API.
For production application logs, prefer the Vix logging system.
Basic example
Create a file:
mkdir -p ~/rix-debug-format
cd ~/rix-debug-format
touch format.cppAdd:
#include <rix.hpp>
#include <string>
int main()
{
const std::string one =
rix.debug.format("Hello, {}", "Ada");
const std::string two =
rix.debug.format(
"{0} builds on {1}",
"Rix",
"Vix.cpp");
const std::string three =
rix.debug.format(
"{{ package }} = {}",
"rix/debug");
rix.debug.print(one);
rix.debug.print(two);
rix.debug.print(three);
return 0;
}Run it:
vix run format.cppIf Rix is not available yet for single-file usage:
vix install -g rix/rix
vix run format.cppExpected output
The output should look like this:
Hello, Ada
Rix builds on Vix.cpp
{ package } = rix/debugrix.debug.format
Use:
rix.debug.format(...)to create a formatted string.
Example:
const auto message =
rix.debug.format("Package: {}", "rix/debug");
rix.debug.print(message);Output:
Package: rix/debugformat returns a std::string.
It does not print by itself.
Automatic placeholders
Use {} to insert arguments in order:
const auto message =
rix.debug.format("{} uses {}", "Rix", "C++");Output:
Rix uses C++Each {} consumes the next argument.
Example:
const auto message =
rix.debug.format(
"name: {}, language: {}, rows: {}",
"Ada",
"C++",
3);Output:
name: Ada, language: C++, rows: 3Explicit placeholders
Use {0}, {1}, and other numeric indexes when the position should be explicit:
const auto message =
rix.debug.format("{0} + {0} = {1}", "C++", "Vix.cpp");Output:
C++ + C++ = Vix.cppExplicit indexes are useful when the same value appears more than once.
Do not mix placeholder styles
Do not mix automatic placeholders and explicit placeholders in the same format string.
Wrong:
rix.debug.format("{} {0}", "Rix");Use automatic placeholders:
rix.debug.format("{} {}", "Rix", "Debug");or explicit placeholders:
rix.debug.format("{0} {1}", "Rix", "Debug");Escaped braces
Use double opening braces and double closing braces when you need literal braces:
const auto message =
rix.debug.format("{{ package }} = {}", "rix/debug");Output:
{ package } = rix/debugThis is useful when printing template-like text, configuration blocks, or examples.
Unsupported format specifiers
rix.debug.format intentionally keeps formatting small.
It does not support format specifiers such as:
{:>10}
{:.2f}
{:04d}Wrong:
rix.debug.format("{:.2f}", 3.14159);Use simple placeholders:
rix.debug.format("value: {}", 3.14159);For advanced formatting, use another formatting library or normal C++ formatting tools where appropriate.
Format different value types
rix.debug.format uses the Rix rendering pipeline.
You can format strings, numbers, booleans, and other supported printable values.
const auto message =
rix.debug.format(
"name: {}, rows: {}, ready: {}",
"Ada",
3,
true);
rix.debug.print(message);Output shape:
name: Ada, rows: 3, ready: trueAppend formatted output
Use:
rix.debug.format.append(...)to append formatted text to an existing string.
Example:
std::string out = "Rix: ";
rix.debug.format.append(
out,
"{}",
"debug");
rix.debug.print(out);Output:
Rix: debugAppend is useful when you are building a longer string in steps.
Replace a string with formatted output
Use:
rix.debug.format.to(...)to replace an existing string with formatted output.
Example:
std::string out = "old value";
rix.debug.format.to(
out,
"Package: {}",
"rix/debug");
rix.debug.print(out);Output:
Package: rix/debugThe previous content of out is cleared.
format vs print
Use format when you need a string:
const auto message =
rix.debug.format("rows: {}", 3);
rix.debug.print(message);Use print when you only want to write values immediately:
rix.debug.print("rows:", 3);print separates values with spaces.
format replaces placeholders and returns a string.
format vs sprint
Use format when you want placeholder-based formatting:
const auto message =
rix.debug.format("Package: {}", "rix/debug");Use sprint when you want the same rendering style as print, but returned as a string:
const auto line =
rix.debug.sprint("Package:", "rix/debug");Both return std::string.
The difference is the style:
format -> placeholder replacement
sprint -> print-style value joiningComplete append example
#include <rix.hpp>
#include <string>
int main()
{
std::string output;
rix.debug.format.append(
output,
"package: {}\n",
"rix/debug");
rix.debug.format.append(
output,
"status: {}\n",
"ready");
rix.debug.format.append(
output,
"rows: {}\n",
3);
rix.debug.print(output);
return 0;
}Run:
vix run format.cppExpected output:
package: rix/debug
status: ready
rows: 3Complete replace example
#include <rix.hpp>
#include <string>
int main()
{
std::string message;
rix.debug.format.to(
message,
"Hello, {}",
"Rix");
rix.debug.print(message);
rix.debug.format.to(
message,
"Package: {}",
"rix/debug");
rix.debug.print(message);
return 0;
}Run:
vix run format.cppExpected output:
Hello, Rix
Package: rix/debugFormatting errors
Invalid format strings can throw rixlib::format_error.
Examples of invalid usage:
rix.debug.format("{", "Rix");
rix.debug.format("}", "Rix");
rix.debug.format("{2}", "Rix");
rix.debug.format("{} {0}", "Rix");
rix.debug.format("{:.2f}", 3.14);For examples and small tools, keep format strings simple.
For user-provided format strings, handle errors explicitly.
Example:
try
{
const auto message =
rix.debug.format("{} {}", "Rix", "Debug");
rix.debug.print(message);
}
catch (const rixlib::format_error &error)
{
rix.debug.eprint("format error:", error.what());
return 1;
}Format CSV output messages
Formatting is useful when reporting CSV results:
#include <rix.hpp>
int main()
{
const auto table = rix.csv.parse(
"name,language\n"
"Ada,C++\n"
"Gaspard,Vix\n");
const auto message =
rix.debug.format("loaded {} rows", table.size());
rix.debug.print(message);
return 0;
}Format Auth errors
Formatting can help create readable Auth diagnostics:
#include <rix.hpp>
int main()
{
auto auth = rix.auth.memory();
auto login = auth.login({
"ada@example.com",
"wrong-password"});
if (login.failed())
{
const auto &error = login.error();
const auto message =
rix.debug.format(
"auth error: {}: {}",
rix.auth.error.to_string(error),
error.message());
rix.debug.eprint(message);
return 1;
}
return 0;
}Do not format or print authentication secrets in production.
Avoid printing:
plain-text passwords
password hashes
session ids
raw token valuesFormat PDF messages
Formatting is useful when reporting generated files:
#include <rix.hpp>
int main()
{
auto saved = rix.pdf.make_text(
"hello.pdf",
"Hello from rix.pdf",
"Rix PDF");
if (saved.failed())
{
const auto message =
rix.debug.format(
"pdf error: {}: {}",
rix.pdf.error.to_string(saved.error()),
saved.error().message());
rix.debug.eprint(message);
return 1;
}
rix.debug.print(
rix.debug.format("created: {}", "hello.pdf"));
return 0;
}Use in a Vix project
Create a Vix application:
vix new debug-format --app
cd debug-formatAdd Rix:
vix add rix/rix
vix installIn vix.app, make sure Rix is listed under deps:
deps = [
"rix/rix",
]A small vix.app can look like this:
name = "debug-format"
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 formatting in src/main.cpp:
#include <rix.hpp>
int main()
{
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 format.cppIf Rix is installed globally for single-file usage:
vix install -g rix/rix
vix run format.cppFor project usage, prefer:
vix add rix/rix
vix installand keep the dependency in vix.app:
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:
#define RIX_ENABLE_DEBUG
#include <rix.hpp>
int main()
{
const auto message =
rix.debug.format("Hello, {}", "Rix");
rix.debug.print(message);
return 0;
}When at least one RIX_ENABLE_* macro is defined, only selected modules are mounted.
Use the independent package
For independent usage, install:
vix add rix/debug
vix installIn vix.app:
deps = [
"rix/debug",
]Then include the independent package header:
#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:
#include <rix.hpp>Logging note
rix.debug.format creates strings.
It is useful for examples and local diagnostics.
For real application logs, prefer the Vix logging system.
Use this rule:
rix.debug -> examples, local diagnostics, quick tools
Vix logging -> production logs, service logs, request logsCommon mistakes
Expecting print to replace placeholders
Wrong:
rix.debug.print("Package: {}", "rix/debug");Use format:
rix.debug.print(
rix.debug.format("Package: {}", "rix/debug"));Mixing automatic and explicit placeholders
Wrong:
rix.debug.format("{} {0}", "Rix");Use one style:
rix.debug.format("{} {}", "Rix", "Debug");or:
rix.debug.format("{0} {1}", "Rix", "Debug");Using unsupported format specifiers
Wrong:
rix.debug.format("{:.2f}", 3.14159);Use simple placeholders:
rix.debug.format("value: {}", 3.14159);Forgetting escaped braces
Wrong:
rix.debug.format("{ package } = {}", "rix/debug");Use:
rix.debug.format("{{ package }} = {}", "rix/debug");Formatting secrets
Do not format or print:
plain-text passwords
password hashes
session ids
raw token valuesThis matters especially with rix/auth.
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
Format a string:
auto message = rix.debug.format("Hello, {}", "Rix");Use automatic placeholders:
rix.debug.format("{} uses {}", "Rix", "C++");Use explicit placeholders:
rix.debug.format("{0} + {0} = {1}", "C++", "Vix.cpp");Escape braces:
rix.debug.format("{{ package }} = {}", "rix/debug");Append:
rix.debug.format.append(out, "{}", "debug");Replace:
rix.debug.format.to(out, "Package: {}", "rix/debug");Use simple placeholders only.
For a Vix project, install Rix:
vix add rix/rix
vix installand use:
deps = [
"rix/rix",
]Next step
Learn inspection.
Next: Inspect