Skip to content

Version information

VersionInfo is the version a tool reports about itself. Getting it from the right place matters more than it looks — self-update compares the version a freshly staged binary reports against the release tag it came from, and refuses the swap when they disagree.

use rtb_app::version::VersionInfo;
use rtb_app::version_info;

Capture your own version with version_info!

let version = rtb_app::version_info!();

This is the correct way to capture a version, and the only one that reports your crate. The macro expands to VersionInfo::from_pkg_version(env!("CARGO_PKG_VERSION")) at your call site, so the env! is evaluated while your crate is being compiled.

Chain the setters to add build metadata:

let version = rtb_app::version_info!()
    .with_commit("deadbeef")
    .with_date("2026-08-02T00:00:00Z");

version_info! is exported at the crate root (rtb_app::version_info!) and is also re-exported from rtb_app::prelude, so a glob import of the prelude brings it in alongside VersionInfo.

VersionInfo fields

Field Type Default Notes
version semver::Version Parsed semver.
commit Option<String> None Short commit SHA, if the build knew one. Nothing validates the shape.
date Option<String> None ISO-8601 build timestamp. Nothing validates the shape — it is a plain String.

commit and date are populated from a build.rs; the vergen and built crates are the usual sources.

Constructors and setters

Item Signature Notes
VersionInfo::new const fn new(version: Version) -> Self commit and date start None.
with_commit fn with_commit(self, impl Into<String>) -> Self Consumes and returns self.
with_date fn with_date(self, impl Into<String>) -> Self Consumes and returns self.
from_pkg_version fn from_pkg_version(raw: &str) -> Self Parses a version string. Never fails — see below.
from_env fn from_env() -> Self Deprecated since 0.9.0. Reports rtb-app's version, not yours.

from_pkg_version swallows a parse failure

VersionInfo::from_pkg_version("1.2.3").version;        // 1.2.3
VersionInfo::from_pkg_version("1.0.0-alpha.1").version; // 1.0.0-alpha.1
VersionInfo::from_pkg_version("not-a-version").version; // 0.0.0

An unparseable string becomes 0.0.0 with no error, no log line and no Result. The only downstream signal is that 0.0.0 makes is_development() return true. If the string comes from somewhere that might get it wrong — a build.rs reading a git describe, say — parse it yourself with semver::Version::parse and handle the error, then use VersionInfo::new.

Use from_pkg_version directly only when the version string comes from somewhere other than your own CARGO_PKG_VERSION. Otherwise reach for version_info!.

is_development

pub fn is_development(&self) -> bool;

true when either the major version is 0 or the pre-release identifier is non-empty.

Version is_development()
0.1.0 true
0.0.0 true
1.0.0-alpha true
1.2.3-dev.5 true
1.0.0 false
2.3.4 false

Worth knowing: this means every pre-1.0 release is reported as a development build, including a perfectly ordinary tagged 0.9.0. Build metadata (+build.7) does not count — only the pre-release part does.

Why VersionInfo::from_env is deprecated

#[deprecated(since = "0.9.0", note = "returns rtb-app's version, not the calling
tool's — `env!` expands where it is written. Use the `rtb_app::version_info!()`
macro instead.")]
pub fn from_env() -> Self;

from_env is a plain function whose body contains env!("CARGO_PKG_VERSION"). The compiler expands env! where it is written — inside rtb-app — so the function returns the framework's version for every caller. Every downstream tool that used it reported rtb-app's version as its own.

That is not cosmetic. Self-update verifies a freshly staged binary by comparing the version it reports against the release tag it was downloaded for. A 0.8.2 build claiming to be 0.9.0 fails that check and the swap is refused, so a tool that misreports its version cannot update itself.

There is no way to fix this without changing the call site, because the expansion location is the whole problem — which is why the replacement had to be a macro. The crate carries a trybuild fixture asserting the deprecation warning stays in place.

Report your tool's own version covers the migration.

Serde

VersionInfo derives Serialize and Deserialize. commit and date carry #[serde(default)], so a document with only version deserialises cleanly. There is no deny_unknown_fields on this type.