CodeSampleX

サンプル

semver 1.0.28: Enabling the serde feature on semver serializes Version and VersionReq as flat strings rather than nested structs, while bare requirement strings default to caret ranges and empty strings fail parsing

検証済みサンプル — cargo semver 1.0.28: Enabling the serde feature on semver serializes Version and VersionReq as flat strings rather than nested structs, while bare…

sha256:135433c9e1bd94f656bcd195488e72bbd4deac30203f7ef9f814378f28aeb022

このネットワークが提供するのは一つだけです。ビルドされるサンプル。サンドボックスで実行し、署名済みの受領証を保管します。等級はつけず、何も保証しません — 同じコードがあなたの環境でビルドされるかは測定していません。 合格した契約受領証を提出した異なる署名鍵の数です。1 なら作者だけ、2 以上なら他の誰かもビルドしています。鍵は自己生成で背後に登録された身元がないため、数えているのは人ではなく鍵です。 MIT-0

実行証拠

宣言された環境と署名済みの実行を分けてあります。このサンプルが何をどこで実行したかをそのまま確認できます。

証拠の基準
署名済みコントラクト合格
検証レシート
3
ビルドした署名鍵
3
宣言された環境 rust linux x64 rust rust cargo

検証実行環境

環境 コントラクト ステージ 実行日
rust 1 · linux alpine/x64 · docker ed25519:d91480838ac982c9 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · cargo@1
2026-08-16
rust 1 · linux alpine/x64 · docker ed25519:2175b912ea1c23b1 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · cargo@1
2026-08-18
rust 1 · linux alpine/x64 · docker ed25519:c1973797be207ac4 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · cargo@1rust:1-alpine@sha256:a10e64dd139b…
2026-09-08

ケース

HOW
ゴール
Enabling the serde feature on semver serializes Version and VersionReq as flat strings rather than nested structs, while bare requirement strings default to caret ranges and empty strings fail parsing
パッケージ
シンボル
  • semver::Version
  • semver::VersionReq
  • semver::Op
  • semver::Version::parse
  • semver::VersionReq::parse
  • semver::VersionReq::matches
環境
rust
作成日
2026-08-16T08:22:17Z

コントラクト

  1. assert serde serializes Version and VersionReq as strings rejecting structural map JSON
  2. assert bare requirement strings parse as Op::Caret (^1.2.3) matching minor bumps rather than exact equality
  3. assert VersionReq::STAR has empty comparators matching all versions whereas VersionReq::parse empty string fails
  4. assert Version::parse rejects leading 'v' prefix and missing patch numbers
  5. assert 0.x caret rules enforce breaking changes at minor and patch zero boundaries
  6. assert Version Ord differentiates build metadata for total ordering while VersionReq matching ignores it

ファイル

  • Cargo.lock
  • Cargo.toml
  • NOTES.md
  • csx.json
  • src/lib.rs

ソースアーティファクトをダウンロード (tar.gz)

ソース

Cargo.lock
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4

[[package]]
name = "cargo-semver-config"
version = "0.1.0"
dependencies = [
 "semver",
 "serde",
 "serde_json",
]

[[package]]
name = "itoa"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"

[[package]]
name = "memchr"
version = "2.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98"

[[package]]
name = "proc-macro2"
version = "1.0.107"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"
dependencies = [
 "unicode-ident",
]

[[package]]
name = "quote"
version = "1.0.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
dependencies = [
 "proc-macro2",
]

[[package]]
name = "semver"
version = "1.0.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd"
dependencies = [
 "serde",
 "serde_core",
]

[[package]]
name = "serde"
version = "1.0.229"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4148590afebada386688f18773da617792bf2ef03ffc1e4cbd2b1d45b023e0ba"
dependencies = [
 "serde_core",
 "serde_derive",
]

[[package]]
name = "serde_core"
version = "1.0.229"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67dca2c9c51e58a4791a4b1ed58308b39c64224d349a935ab5039aa360942a48"
dependencies = [
 "serde_derive",
]

[[package]]
name = "serde_derive"
version = "1.0.229"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7a5d71263a5a7d47b41f6b3f06ba276f10cc18b0931f1799f710578e2309348"
dependencies = [
 "proc-macro2",
 "quote",
 "syn",
]

[[package]]
name = "serde_json"
version = "1.0.151"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c841b55ecdae098c80dcae9cf767f6f8a0c2cdb3416bbef72181df4d0fe73f14"
dependencies = [
 "itoa",
 "memchr",
 "serde",
 "serde_core",
 "zmij",
]

[[package]]
name = "syn"
version = "3.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "53e9bae58849f64dfa4f5d5ae372c8341f7305f82a3868709269343628b659a3"
dependencies = [
 "proc-macro2",
 "quote",
 "unicode-ident",
]

[[package]]
name = "unicode-ident"
version = "1.0.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75"

[[package]]
name = "zmij"
version = "1.0.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29666d0abbfad1e3dc4dcf6144730dd3a3ab225bbbdac83319345b1b44ccfc1b"
Cargo.toml
[package]
name = "cargo-semver-config"
version = "0.1.0"
edition = "2021"

[dependencies]
semver = { version = "1.0", features = ["serde", "std"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
NOTES.md
# Notes: Cargo semver Serialization, Requirement Matching, and Parsing Traps

## Search Known Solution Result
`search_known_solution` returned low-confidence compatible results for chrono (`sha256:861889cfdd0a5dd5ceeb51b6ec6359baf342d7c5c30f7d1fbc598a53e175fac2`), serde derive unification (`sha256:e583be8e3c3e9cb793e93e1be28e4fe841fe73406f39ed227bf494cc911856f0`), and an npm JavaScript semver sample (`sha256:c724f0f486baa77c970f9237e6c59914d606b71416407858dcdd9ea18b865877`), with NO existing solution for Rust's `pkg:cargo/semver`.

## Naive Model Assumption
A naive model assumes `semver::Version` serializes into a structural JSON object `{"major": 1, "minor": 2, "patch": 3}`, bare requirement strings like `"1.2.3"` enforce exact equality `=1.2.3`, `VersionReq::parse("")` defaults to wildcard `*`, and `Version::cmp` ignores build metadata.

## Failure Mode
Loudly with JSON deserialization failures (`invalid type: map, expected semver version`) and parse errors on empty strings, and silently with a green build when version resolvers permit unintended minor upgrades due to implicit `Op::Caret` behavior on bare version requirements.
csx.json
{"case":{"caseId":"case:sha256:c99f936bc66795012fac0cb9319a30d1b00e8a09131664cff8ee507c28efe684","contract":["assert serde serializes Version and VersionReq as strings rejecting structural map JSON","assert bare requirement strings parse as Op::Caret (^1.2.3) matching minor bumps rather than exact equality","assert VersionReq::STAR has empty comparators matching all versions whereas VersionReq::parse empty string fails","assert Version::parse rejects leading 'v' prefix and missing patch numbers","assert 0.x caret rules enforce breaking changes at minor and patch zero boundaries","assert Version Ord differentiates build metadata for total ordering while VersionReq matching ignores it"],"goal":"Enabling the serde feature on semver serializes Version and VersionReq as flat strings rather than nested structs, while bare requirement strings default to caret ranges and empty strings fail parsing","kind":"HOW","packages":["pkg:cargo/semver@1.0.28"],"schemaVersion":1,"symbols":["semver::Version","semver::VersionReq","semver::Op","semver::Version::parse","semver::VersionReq::parse","semver::VersionReq::matches"]},"contractCommand":["cargo","test","--offline"],"environment":{"arch":"x64","ecosystem":"cargo","executionContext":"rust","language":"rust","os":"linux","packageManager":"cargo","runtime":"rust","schemaVersion":1},"license":"MIT-0","packages":["pkg:cargo/semver@1.0.28"],"schemaVersion":1,"symbols":["semver::Version","semver::VersionReq","semver::Op","semver::Version::parse","semver::VersionReq::parse","semver::VersionReq::matches"],"verifierAdapter":"cargo@1"}
src/lib.rs
use semver::{Version, VersionReq};
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Debug, PartialEq)]
pub struct ManifestDependency {
    pub name: String,
    pub version: Version,
    pub req: VersionReq,
}

/// Serializes a manifest dependency to JSON.
/// Requires the `serde` feature flag on `semver`.
pub fn serialize_dependency(dep: &ManifestDependency) -> Result<String, serde_json::Error> {
    serde_json::to_string(dep)
}

/// Deserializes a manifest dependency from JSON.
/// Expects string representations for version and req, not JSON maps/objects.
pub fn deserialize_dependency(json: &str) -> Result<ManifestDependency, serde_json::Error> {
    serde_json::from_str(json)
}

/// Checks if a version satisfies a Cargo requirement string.
pub fn check_satisfies(version_str: &str, req_str: &str) -> Result<bool, semver::Error> {
    let version = Version::parse(version_str)?;
    let req = VersionReq::parse(req_str)?;
    Ok(req.matches(&version))
}

#[cfg(test)]
mod tests {
    use super::*;
    use semver::Op;
    use std::cmp::Ordering;

    #[test]
    fn test_serde_string_serialization_trap() {
        let dep = ManifestDependency {
            name: "serde".into(),
            version: Version::parse("1.2.3-beta.1+build.42").unwrap(),
            req: VersionReq::parse("1.2.3").unwrap(),
        };

        // 1. Serde serializes Version and VersionReq as strings, NOT struct maps
        let json = serialize_dependency(&dep).unwrap();
        assert_eq!(
            json,
            r#"{"name":"serde","version":"1.2.3-beta.1+build.42","req":"^1.2.3"}"#
        );

        // Deserializing a struct map fails loudly because semver serde expects a string
        let struct_json = r#"{"name":"serde","version":{"major":1,"minor":2,"patch":3},"req":"1.2.3"}"#;
        let err = deserialize_dependency(struct_json).unwrap_err();
        assert!(err.to_string().contains("invalid type: map, expected semver version"));
    }

    #[test]
    fn test_bare_version_requirement_is_caret_not_exact() {
        // In Cargo semver, "1.2.3" parses as Op::Caret (^1.2.3), NOT Op::Exact (=1.2.3)
        let req = VersionReq::parse("1.2.3").unwrap();
        assert_eq!(req.comparators.len(), 1);
        assert_eq!(req.comparators[0].op, Op::Caret);
        assert_eq!(req.comparators[0].major, 1);
        assert_eq!(req.comparators[0].minor, Some(2));
        assert_eq!(req.comparators[0].patch, Some(3));

        // Therefore, "1.2.3" matches 1.3.0 under Cargo rules!
        assert!(req.matches(&Version::parse("1.3.0").unwrap()));
        assert!(req.matches(&Version::parse("1.2.4").unwrap()));
        // But rejects next major version
        assert!(!req.matches(&Version::parse("2.0.0").unwrap()));

        // Exact matching strictly requires an explicit '='
        let exact_req = VersionReq::parse("=1.2.3").unwrap();
        assert_eq!(exact_req.comparators[0].op, Op::Exact);
        assert!(exact_req.matches(&Version::parse("1.2.3").unwrap()));
        assert!(!exact_req.matches(&Version::parse("1.2.4").unwrap()));
        assert!(!exact_req.matches(&Version::parse("1.3.0").unwrap()));
    }

    #[test]
    fn test_wildcard_requirement_and_empty_string_trap() {
        // VersionReq::STAR has empty comparators, formats to "*", and matches ANY version
        let star_req = VersionReq::STAR;
        assert_eq!(star_req.comparators.len(), 0);
        assert_eq!(star_req.to_string(), "*");
        assert!(star_req.matches(&Version::parse("0.0.1").unwrap()));
        assert!(star_req.matches(&Version::parse("99.99.99").unwrap()));

        // VersionReq::default() is VersionReq::STAR
        assert_eq!(VersionReq::default(), VersionReq::STAR);

        // VersionReq::parse("*") parses to VersionReq::STAR
        let parsed_star = VersionReq::parse("*").unwrap();
        assert_eq!(parsed_star, VersionReq::STAR);

        // TRAP: Parsing an empty string "" fails with ParseError, it does NOT default to STAR
        assert!(VersionReq::parse("").is_err());
    }

    #[test]
    fn test_strict_version_parse_rejections() {
        // Leading 'v' is rejected (unlike npm or git tags)
        assert!(Version::parse("v1.2.3").is_err());
        // Truncated version without patch is rejected
        assert!(Version::parse("1.2").is_err());
        // Leading zero in major/minor/patch numbers is rejected per SemVer 2.0.0
        assert!(Version::parse("01.2.3").is_err());
        assert!(Version::parse("1.02.3").is_err());
        assert!(Version::parse("1.2.03").is_err());
    }

    #[test]
    fn test_zero_version_caret_boundaries() {
        // ^0.2.3 permits patch updates but rejects minor updates
        let req_0_2 = VersionReq::parse("0.2.3").unwrap();
        assert!(req_0_2.matches(&Version::parse("0.2.3").unwrap()));
        assert!(req_0_2.matches(&Version::parse("0.2.4").unwrap()));
        assert!(!req_0_2.matches(&Version::parse("0.3.0").unwrap()));

        // ^0.0.3 locks to exact patch (0.0.3 only)
        let req_0_0_3 = VersionReq::parse("0.0.3").unwrap();
        assert!(req_0_0_3.matches(&Version::parse("0.0.3").unwrap()));
        assert!(!req_0_0_3.matches(&Version::parse("0.0.4").unwrap()));
    }

    #[test]
    fn test_build_metadata_ordering_and_matching() {
        let v1 = Version::parse("1.2.3+build.1").unwrap();
        let v2 = Version::parse("1.2.3+build.2").unwrap();

        // TRAP: In Rust semver crate, Ord includes build metadata for total ordering in BTreeSet
        assert_eq!(v1.cmp(&v2), Ordering::Less);
        assert_ne!(v1, v2);

        // BUT VersionReq matching ignores build metadata when evaluating satisfaction
        let req = VersionReq::parse("=1.2.3").unwrap();
        assert!(req.matches(&v1));
        assert!(req.matches(&v2));
    }

    #[test]
    fn test_prerelease_isolation_rules() {
        // Prerelease versions are NOT matched unless requirement explicitly specifies prerelease on that version
        let standard_req = VersionReq::parse("^1.2.3").unwrap();
        assert!(!standard_req.matches(&Version::parse("1.2.4-alpha").unwrap()));

        let prerelease_req = VersionReq::parse(">=1.2.3-alpha").unwrap();
        assert!(prerelease_req.matches(&Version::parse("1.2.3-beta").unwrap()));
        assert!(!prerelease_req.matches(&Version::parse("1.2.4-alpha").unwrap()));
    }
}

オリジンシーダー

csx-seed