Zillowe FoundationZillowe Documentation

Getting Started

Learn how to parse, render, compare and validate ZFVM versions.

Parsing a Version

The canonical form is [Branch] [Status] [X.Y.Z] [Build], where the build component is optional. Use Version::parse:

use zfvm::{Branch, Status, Version};

fn main() -> zfvm::Result<()> {
    let version = Version::parse("Dev Beta 1.2.3 456")?;

    assert_eq!(version.branch(), Branch::Dev);
    assert_eq!(version.status(), Status::Beta);
    assert_eq!(version.core().to_string(), "1.2.3");
    assert_eq!(version.build().map(|b| b.as_str()), Some("456"));

    Ok(())
}

Parsing is strict. It rejects anything that does not match the grammar, including most mistakes people actually make:

use zfvm::Version;

fn main() {
    // Long names are not identifiers. ZFVM section 3 requires `Dev`.
    assert!(Version::parse("Development Beta 1.2.3").is_err());

    // Identifiers are case-sensitive.
    assert!(Version::parse("dev beta 1.2.3").is_err());

    // Leading zeros are forbidden, inherited from SemVer.
    assert!(Version::parse("Prod Beta 1.02.3").is_err());

    // Exactly one space separates components.
    assert!(Version::parse("Prod  Beta 1.2.3").is_err());

    // The vocabularies are closed.
    assert!(Version::parse("Main Beta 1.2.3").is_err());
    assert!(Version::parse("Prod Stable 1.2.3").is_err());
}

Errors carry the offending input, so a message names what actually failed rather than only which category it fell into.

Rendering Every Form

A parsed version can be rendered in any of the defined forms:

use zfvm::Version;

fn main() -> zfvm::Result<()> {
    let version = Version::parse("Dev Beta 1.2.3 456")?;

    assert_eq!(version.to_canonical(), "Dev Beta 1.2.3 456");
    assert_eq!(version.to_contextual(), "Beta 1.2.3 456");
    assert_eq!(version.to_semantic(), "1.2.3");
    assert_eq!(version.to_symbolic_acronym(), "D-B-1.2.3");
    assert_eq!(version.to_symbolic_long(), "Dev-Beta-1.2.3");
    assert_eq!(version.to_symbolic_index(), "b2s3-1.2.3");
    assert_eq!(version.to_semver(), "1.2.3-2+456");

    Ok(())
}

Displaying a Version writes the canonical form, so to_string and to_canonical agree.

Note that the symbolic forms omit the build component. That is intentional: a build identifier is per-compilation detail, and the symbolic forms exist for machine-readable identifiers like container tags and file names, where a changing build would fragment the namespace.

The Contextual Form

Where the branch is already known from context, the canonical form can be shortened. parse_contextual returns a value that carries no branch, which you supply separately:

use zfvm::{Branch, Version};

fn main() -> zfvm::Result<()> {
    let contextual = Version::parse_contextual("Beta 1.2.3")?;
    assert_eq!(contextual.status(), zfvm::Status::Beta);

    let version = contextual.with_branch(Branch::Dev);
    assert_eq!(version.to_string(), "Dev Beta 1.2.3");

    Ok(())
}

Prefer the canonical form wherever the branch is known. The contextual form cannot be parsed back into a complete version on its own.

Validating a Version

Parsing rejects malformed strings. validate rejects strings that are well-formed but contradict a policy rule. The only such rule today is the Release-with-zero-major restriction:

use zfvm::Version;

fn main() -> zfvm::Result<()> {
    // Well-formed, but a 0.y.z codebase has no stable public API, so it
    // cannot be called a Release.
    let version = Version::parse("Prod Release 0.9.0")?;
    assert!(version.validate().is_err());

    let version = Version::parse("Prod RC 0.9.0")?;
    assert!(version.validate().is_ok());

    Ok(())
}

Modifying a Version

The with_* methods return a modified copy and leave the other fields alone:

use zfvm::{Branch, Status, Version};

fn main() -> zfvm::Result<()> {
    let version = Version::parse("Dev Beta 1.2.3 456")?;

    assert_eq!(
        version.with_status(Status::Rc).to_string(),
        "Dev RC 1.2.3 456"
    );
    assert_eq!(
        version.with_branch(Branch::Prod).to_string(),
        "Prod Beta 1.2.3 456"
    );
    assert_eq!(version.with_build(None).to_string(), "Dev Beta 1.2.3");

    Ok(())
}

A status change does not move the core version. See Version Precedence for why that matters.


A software organization

2026 © All Rights Reserved.

  • All the content is available under CC BY-SA 4.0, expect where otherwise stated.

Last updated on