Skip to content

ddn.ddn

This page provides working examples demonstrating how to use the ddn.ddn module for version information in your D applications.

Basic Version Information

The simplest use case is retrieving the DDN library version:

#!/usr/bin/env dub
/+ dub.sdl:
    name "ddn-version-basic"
    dependency "ddn" version="*"
+/
module examples.ddn_version_basic;

import std.stdio;
import ddn.ddn;

void main() {
    // Get version as a formatted string
    writeln("DDN Library Version: ", ddnVersionString());

    // Get version as a numeric value
    writeln("Numeric Version: ", ddnVersion());

    // Access individual version components
    writefln("Major: %d, Minor: %d, Patch: %d", MAJOR, MINOR, PATCH);
}

Output:

DDN Library Version: 2.0.0
Numeric Version: 2000000
Major: 2, Minor: 0, Patch: 0


Compile-Time Version Checks

Use compile-time constants for conditional compilation:

#!/usr/bin/env dub
/+ dub.sdl:
    name "ddn-version-ctfe"
    dependency "ddn" version="*"
+/
module examples.ddn_version_ctfe;

import std.stdio;
import ddn.ddn;

void main() {
    // Compile-time version assertions
    static assert(MAJOR >= 2, "This code requires DDN 2.x or later");
    static assert(MINOR >= 0);
    static assert(PATCH >= 0);

    // Compile-time version string check
    static assert(ddnVersionString() == "2.0.0");

    // Compile-time numeric version check
    static assert(ddnVersion() == 2_000_000);

    writeln("All compile-time version checks passed!");
    writeln("Running with DDN version: ", ddnVersionString());
}

Version Comparison for Feature Detection

Compare versions to enable or disable features:

#!/usr/bin/env dub
/+ dub.sdl:
    name "ddn-version-compare"
    dependency "ddn" version="*"
+/
module examples.ddn_version_compare;

import std.stdio;
import ddn.ddn;

void main() {
    // Check if running version 2.0.0 or later
    if (ddnVersion() >= 2_000_000) {
        writeln("Using DDN 2.x features");
        useNewFeatures();
    } else {
        writeln("Using legacy DDN 1.x compatibility mode");
        useLegacyFeatures();
    }

    // Check for specific version ranges
    enum int V1_5_0 = 1_005_000;
    enum int V2_0_0 = 2_000_000;
    enum int V3_0_0 = 3_000_000;

    int ver = ddnVersion();

    if (ver >= V2_0_0 && ver < V3_0_0) {
        writeln("Running DDN 2.x series");
    } else if (ver >= V1_5_0 && ver < V2_0_0) {
        writeln("Running DDN 1.5+ series");
    }
}

void useNewFeatures() {
    writeln("  - Advanced CSV parsing enabled");
    writeln("  - Enhanced path operations enabled");
}

void useLegacyFeatures() {
    writeln("  - Basic functionality only");
}

Version Logging and Diagnostics

Include version information in application logs:

#!/usr/bin/env dub
/+ dub.sdl:
    name "ddn-version-logging"
    dependency "ddn" version="*"
+/
module examples.ddn_version_logging;

import std.stdio;
import std.datetime;
import std.format;
import ddn.ddn;

void main() {
    // Log application startup with version info
    logStartup();

    // Simulate some work
    writeln("Application running...");

    // Log shutdown
    logShutdown();
}

void logStartup() {
    auto now = Clock.currTime();
    writefln("[%s] Application starting", now.toISOExtString());
    writefln("[%s] DDN Library: %s (build %d)", 
        now.toISOExtString(), 
        ddnVersionString(), 
        ddnVersion());
    writefln("[%s] Version components: %d.%d.%d",
        now.toISOExtString(),
        MAJOR, MINOR, PATCH);
}

void logShutdown() {
    auto now = Clock.currTime();
    writefln("[%s] Application shutting down", now.toISOExtString());
}

Version Information in Help Output

Display version in command-line help:

#!/usr/bin/env dub
/+ dub.sdl:
    name "ddn-version-help"
    dependency "ddn" version="*"
+/
module examples.ddn_version_help;

import std.stdio;
import std.format;
import ddn.ddn;

enum APP_NAME = "MyApp";
enum APP_VERSION = "1.0.0";

void main(string[] args) {
    if (args.length > 1 && (args[1] == "--version" || args[1] == "-v")) {
        printVersion();
        return;
    }

    if (args.length > 1 && (args[1] == "--help" || args[1] == "-h")) {
        printHelp();
        return;
    }

    writeln("Running ", APP_NAME, "...");
}

void printVersion() {
    writefln("%s version %s", APP_NAME, APP_VERSION);
    writefln("Built with DDN %s", ddnVersionString());
}

void printHelp() {
    writefln("%s - A sample application", APP_NAME);
    writeln();
    writeln("Usage: myapp [options]");
    writeln();
    writeln("Options:");
    writeln("  -h, --help     Show this help message");
    writeln("  -v, --version  Show version information");
    writeln();
    writefln("DDN Library Version: %s", ddnVersionString());
}

Version Encoding Explained

Understanding the numeric version encoding:

#!/usr/bin/env dub
/+ dub.sdl:
    name "ddn-version-encoding"
    dependency "ddn" version="*"
+/
module examples.ddn_version_encoding;

import std.stdio;
import std.format;
import ddn.ddn;

void main() {
    writeln("=== DDN Version Encoding ===");
    writeln();

    // The version encoding formula:
    // version = PATCH + (MINOR × 1,000) + (MAJOR × 1,000,000)

    int calculatedVersion = PATCH + (MINOR * 1_000) + (MAJOR * 1_000_000);

    writefln("MAJOR = %d", MAJOR);
    writefln("MINOR = %d", MINOR);
    writefln("PATCH = %d", PATCH);
    writeln();
    writefln("Formula: PATCH + (MINOR × 1000) + (MAJOR × 1000000)");
    writefln("         %d + (%d × 1000) + (%d × 1000000)", PATCH, MINOR, MAJOR);
    writefln("         = %d", calculatedVersion);
    writeln();
    writefln("ddnVersion() returns: %d", ddnVersion());
    writefln("Match: %s", calculatedVersion == ddnVersion() ? "Yes" : "No");
    writeln();

    // Demonstrate decoding
    int ver = ddnVersion();
    int decodedMajor = ver / 1_000_000;
    int decodedMinor = (ver % 1_000_000) / 1_000;
    int decodedPatch = ver % 1_000;

    writeln("=== Decoding Version Number ===");
    writefln("From %d:", ver);
    writefln("  Major: %d / 1000000 = %d", ver, decodedMajor);
    writefln("  Minor: (%d %% 1000000) / 1000 = %d", ver, decodedMinor);
    writefln("  Patch: %d %% 1000 = %d", ver, decodedPatch);
}

Output:

=== DDN Version Encoding ===

MAJOR = 2
MINOR = 0
PATCH = 0

Formula: PATCH + (MINOR × 1000) + (MAJOR × 1000000)
         0 + (0 × 1000) + (2 × 1000000)
         = 2000000

ddnVersion() returns: 2000000
Match: Yes

=== Decoding Version Number ===
From 2000000:
  Major: 2000000 / 1000000 = 2
  Minor: (2000000 % 1000000) / 1000 = 0
  Patch: 2000000 % 1000 = 0


Using Version in Unit Tests

Verify version consistency in tests:

#!/usr/bin/env dub
/+ dub.sdl:
    name "ddn-version-unittest"
    dependency "ddn" version="*"
+/
module examples.ddn_version_unittest;

import std.stdio;
import std.format;
import std.conv;
import ddn.ddn;

// Unit tests for version consistency
unittest {
    // Verify version components are non-negative
    assert(MAJOR >= 0);
    assert(MINOR >= 0);
    assert(PATCH >= 0);

    // Verify numeric version matches components
    int expected = PATCH + (MINOR * 1_000) + (MAJOR * 1_000_000);
    assert(ddnVersion() == expected);

    // Verify string version format
    string expectedStr = format("%d.%d.%d", MAJOR, MINOR, PATCH);
    assert(ddnVersionString() == expectedStr);
}

void main() {
    writeln("Version unit tests passed!");
    writefln("Tested version: %s (%d)", ddnVersionString(), ddnVersion());
}

Complete Application Example

A complete example combining all version features:

#!/usr/bin/env dub
/+ dub.sdl:
    name "ddn-version-complete"
    dependency "ddn" version="*"
+/
module examples.ddn_version_complete;

import std.stdio;
import std.format;
import std.datetime;
import ddn.ddn;

// Application metadata
enum APP_NAME = "VersionDemo";
enum APP_VERSION = "1.0.0";

// Minimum required DDN version
enum int MIN_DDN_VERSION = 2_000_000;

void main(string[] args) {
    // Check DDN version requirement
    static assert(ddnVersion() >= MIN_DDN_VERSION,
        "This application requires DDN 2.0.0 or later");

    // Handle command-line arguments
    if (args.length > 1) {
        switch (args[1]) {
            case "--version", "-v":
                printVersionInfo();
                return;
            case "--help", "-h":
                printHelp();
                return;
            default:
                writefln("Unknown option: %s", args[1]);
                writeln("Use --help for usage information.");
                return;
        }
    }

    // Main application logic
    runApplication();
}

void printVersionInfo() {
    writefln("%s %s", APP_NAME, APP_VERSION);
    writefln("DDN Library: %s (numeric: %d)", ddnVersionString(), ddnVersion());
    writefln("DDN Components: Major=%d, Minor=%d, Patch=%d", MAJOR, MINOR, PATCH);
}

void printHelp() {
    writefln("%s - DDN Version Information Demo", APP_NAME);
    writeln();
    writeln("Usage: version-demo [options]");
    writeln();
    writeln("Options:");
    writeln("  -v, --version  Display version information");
    writeln("  -h, --help     Display this help message");
    writeln();
    writefln("Built with DDN %s", ddnVersionString());
}

void runApplication() {
    auto startTime = Clock.currTime();

    writefln("[%s] %s starting...", startTime.toISOExtString(), APP_NAME);
    writefln("[%s] Using DDN %s", startTime.toISOExtString(), ddnVersionString());

    // Demonstrate version-based feature selection
    if (ddnVersion() >= 2_000_000) {
        writeln("[INFO] DDN 2.x detected - all features available");
    }

    writeln();
    writeln("Application completed successfully.");
}

Running the Examples

To run any of these examples, save the code to a .d file and use DUB:

# Run directly with dub
dub run --single example.d

# Or compile first
dub build --single example.d
./example

All examples are self-contained and include the necessary DUB configuration in the file header.