Skip to content

refactor(types)!: 1.0 naming and conversion conventions - #247

Merged
wolfv merged 6 commits into
mainfrom
refactor/types-conventions
Sep 25, 2026
Merged

wolfv merged 6 commits into
mainfrom
refactor/types-conventions

Conversation

@wolfv

@wolfv wolfv commented Sep 24, 2026

Copy link
Copy Markdown
Collaborator

Summary

1.0 API work: T-b and T-c from the plan folded into one PR, one commit per theme. It's best reviewed commit by commit.

  1. Digests (c6f8786): Sha256Hash and Sha512Hash are generated from one macro, so they share an API (Jussi's refactor(types)!: deserialize semantic bundle values eagerly #193 comment about Sha512Hash parity):

    • new, TryFrom<&[u8]>
    • hex and base64 parsing and encoding, serde
    • Display / FromStr (hex)
    • DigestBytes conversions and comparisons

    try_from_slice becomes TryFrom<&[u8]> (also on KeyHint), and DigestBytes::from_bytes becomes new, gaining into_bytes, len, to_hex and Display

  2. Enums (4820781):

    • HashAlgorithm: FromStr + Hash replaces from_str_flexible, as_lowercase becomes as_rekor_str, and the stringly oid() is removed
    • MediaType: AsRef<str> replaces Deref<Target = str>, and Bundle::version() becomes media_type()
    • removes the dead BundleVersion and DsseEnvelope::decode_payload
  3. LogIndex (98e0ea5): value() becomes get(), plus From<LogIndex> for u64, TryFrom<i64> and FromStr

  4. Serde helpers (9471cc4): the helper modules are no longer public API. The unused ones are removed, the Rekor v2 digest fields become DigestBytes, and the Rekor-only hash-algorithm helper moves to rekor

  5. Rekor v1 encodings (07d2492, T-c): HexLogId / HexHash move to sigstore_rekor. from_bytes becomes encode, and HexLogId::to_base64() -> String becomes to_log_key_id() -> LogKeyId

  6. Docs: EntryUuid and KeyId are documented as opaque, unvalidated identifiers. That leaves room to add a validating parser later without breaking new

Validation

  • cargo clippy --workspace --all-targets --all-features -- -D warnings
  • cargo test --workspace --all-features --no-fail-fast (new tests: Sha512Hash parity, LogIndex conversions, HexLogId::to_log_key_id)
  • cargo check --no-default-features for types and rekor

Signed-off-by: Wolf Vollprecht w.vollprecht@gmail.com

🤖 Generated with Claude Code

wolfv and others added 6 commits September 24, 2026 18:04
`from_bytes` meant three different things across the digest types, and
`Sha512Hash` lacked most of what `Sha256Hash` offered (#193 review).

- Generate `Sha256Hash` and `Sha512Hash` from one macro so they share an
  API: `new([u8; N])`, `TryFrom<&[u8]>`, hex and base64 parsing and
  encoding, serde, `Display`/`FromStr` (hex), conversions to and from
  `DigestBytes`, and comparisons with byte slices, arrays and vectors.
- Replace `try_from_slice` on `Sha256Hash`, `Sha512Hash` and `KeyHint`
  with `TryFrom<&[u8]>`.
- `DigestBytes::from_bytes(Vec<u8>)` becomes `DigestBytes::new`, and gains
  `into_bytes`, `len`, `is_empty`, `to_hex`, `From<Vec<u8>>` and `Display`.
- `KeyHint` implements `Display` (hex).

BREAKING CHANGE: `Sha256Hash::from_bytes`, `Sha512Hash::from_bytes` and
`DigestBytes::from_bytes` are renamed to `new`; `try_from_slice` is
replaced by `TryFrom<&[u8]>`.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: Wolf Vollprecht <w.vollprecht@gmail.com>
- `HashAlgorithm` implements `FromStr` (accepting the protobuf-specs,
  Rekor and hyphenated spellings) instead of
  `from_str_flexible -> Option`, and derives `Hash`. `as_lowercase` is
  renamed `as_rekor_str`. The stringly-typed `oid()` is removed.
- `MediaType` implements `AsRef<str>` instead of `Deref<Target = str>`.
- `Bundle::version()` is renamed `media_type()`, which is what it returns.
- Remove the unused `BundleVersion` enum, `DsseEnvelope::decode_payload`
  (it only cloned the payload) and the "backwards compatibility"
  `hash::base64_bytes` re-export.
- `DsseEnvelope::new` takes `impl Into<String>` for the payload type.

BREAKING CHANGE: `HashAlgorithm::from_str_flexible` and `oid` are
removed (use `str::parse`); `as_lowercase` is `as_rekor_str`;
`MediaType` no longer derefs to `str`; `Bundle::version` is
`Bundle::media_type`; `BundleVersion`, `DsseEnvelope::decode_payload`
and `sigstore_types::hash::base64_bytes` are removed.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: Wolf Vollprecht <w.vollprecht@gmail.com>
`LogIndex::value()` is renamed `get()`, and `LogIndex` gains
`From<LogIndex> for u64`, `TryFrom<i64>` (rejecting negative indices)
and `FromStr`, so callers need not convert through raw integers.

BREAKING CHANGE: `LogIndex::value` is renamed `LogIndex::get`.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: Wolf Vollprecht <w.vollprecht@gmail.com>
The public `base64_bytes`, `base64_bytes_option`, `hex_bytes`,
`string_u64`, `string_timestamp_opt` and `hash::hash_algorithm_lowercase`
modules were implementation details, but as public items they were part
of the API.

- `string_u64` and `string_timestamp_opt` are crate-private.
- `base64_bytes`, `base64_bytes_option` and `hex_bytes` are removed. The
  only external user, the Rekor v2 `digest` fields, now use
  `DigestBytes`, which serializes as base64 itself.
- `hash_algorithm_lowercase` moves into sigstore-rekor, its only user.

BREAKING CHANGE: the serde helper modules are no longer exported from
sigstore-types; Rekor v2 body `digest` fields are `DigestBytes` instead
of `Vec<u8>`.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: Wolf Vollprecht <w.vollprecht@gmail.com>
`HexLogId` and `HexHash` model the Rekor v1 API's hex strings and are
only used by sigstore-rekor, so they don't belong in the shared types
crate. Move them to `sigstore_rekor::hex_encoded` (re-exported at the
crate root).

- `from_bytes` (which hex-encoded) is renamed `encode`.
- `HexLogId::to_base64() -> Result<String>` becomes
  `to_log_key_id() -> Result<LogKeyId>`, the bundle's typed
  representation.
- `new` takes `impl Into<String>`.

BREAKING CHANGE: `sigstore_types::{HexLogId, HexHash}` moved to
`sigstore_rekor::{HexLogId, HexHash}`; `from_bytes` is `encode`, and
`HexLogId::to_base64` is replaced by `to_log_key_id`.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: Wolf Vollprecht <w.vollprecht@gmail.com>
Neither is validated: Rekor has used several UUID formats, and DSSE
leaves key IDs to the signer. Say so, and take impl Into<String> in
their constructors.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: Wolf Vollprecht <w.vollprecht@gmail.com>

@jku jku left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great, thanks!

1.0 API work: T-b and T-c from the plan folded into one PR,

these are a bit annoying in PRs when I don't think I've seen the plan.

@wolfv
wolfv merged commit fdeed02 into main Sep 25, 2026
19 checks passed
@wolfv
wolfv deleted the refactor/types-conventions branch September 25, 2026 13:33
@wolfv wolfv mentioned this pull request Sep 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants