oid: SHA1_DIGEST_LEN → Oid::LEN_SHA1

A small refactor to move this constant closer to the `enum` that it is
about. An associated constant constant fits more nicely.

Reason for changing the name from `SHA1_*_LEN` to `LEN_SHA1`: As we
think about the object format in the future becoming variable, we
would have that the length of an OID is parameterized by the object
format. So, we imagine a function `fn len(format: ObjectFormat)`, to
be called as `Oid::len(ObjectFormat::Sha1)`. This is the new order
we use.
This commit is contained in:
Lorenz Leutgeb 2026-04-23 21:42:36 +02:00 committed by Lorenz Leutgeb
parent 4c605c0671
commit f46624b81c
1 changed files with 20 additions and 15 deletions

View File

@ -74,12 +74,10 @@ extern crate alloc;
#[cfg(not(feature = "sha1"))]
compile_error!("The `sha1` feature is required.");
const SHA1_DIGEST_LEN: usize = 20;
#[derive(PartialEq, Eq, Ord, PartialOrd, Clone, Copy)]
#[non_exhaustive]
pub enum Oid {
Sha1([u8; SHA1_DIGEST_LEN]),
Sha1([u8; Self::LEN_SHA1]),
}
/// Conversions to/from SHA-1.
@ -87,18 +85,21 @@ pub enum Oid {
// for forwards compatibility: What if another hash with digests of the same
// length becomes popular?
impl Oid {
/// The length of a SHA-1 object identifier in bytes.
const SHA1_LEN: usize = 20;
/// A SHA-1 object identifier with all digest bytes set to zero.
/// This is sometimes used as a sentinel value to indicate the absence of
/// an object.
/// To compare whether an object identifier is zero, prefer the method
/// [`Oid::is_zero`] over checking equality with this constant.
pub const ZERO_SHA1: Self = Self::Sha1([0u8; SHA1_DIGEST_LEN]);
pub const ZERO_SHA1: Self = Self::Sha1([0u8; Self::LEN_SHA1]);
pub fn from_sha1(digest: [u8; SHA1_DIGEST_LEN]) -> Self {
pub fn from_sha1(digest: [u8; Self::LEN_SHA1]) -> Self {
Self::Sha1(digest)
}
pub fn into_sha1(&self) -> Option<[u8; SHA1_DIGEST_LEN]> {
pub fn into_sha1(&self) -> Option<[u8; Self::LEN_SHA1]> {
match self {
Oid::Sha1(digest) => Some(*digest),
}
@ -133,11 +134,11 @@ impl From<Oid> for alloc::boxed::Box<[u8]> {
}
pub mod str {
use super::{Oid, SHA1_DIGEST_LEN};
use super::Oid;
use core::str;
/// Length of the string representation of a SHA-1 digest in hexadecimal notation.
pub(super) const SHA1_DIGEST_STR_LEN: usize = SHA1_DIGEST_LEN * 2;
pub(super) const SHA1_DIGEST_STR_LEN: usize = Oid::LEN_SHA1 * 2;
impl str::FromStr for Oid {
type Err = error::ParseOidError;
@ -150,8 +151,8 @@ pub mod str {
return Err(Len(len));
}
let mut bytes = [0u8; SHA1_DIGEST_LEN];
for i in 0..SHA1_DIGEST_LEN {
let mut bytes = [0u8; Oid::LEN_SHA1];
for i in 0..Oid::LEN_SHA1 {
bytes[i] = u8::from_str_radix(&s[i * 2..=i * 2 + 1], 16)
.map_err(|source| At { index: i, source })?;
}
@ -468,7 +469,7 @@ mod test {
impl Arbitrary for Oid {
fn arbitrary(g: &mut Gen) -> Self {
let slice = [0u8; SHA1_DIGEST_LEN];
let slice = [0u8; Oid::SHA1_LEN];
g.fill(slice);
Self::Sha1(slice)
}
@ -511,10 +512,11 @@ mod serde {
type Value = Oid;
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
use crate::str::SHA1_DIGEST_STR_LEN;
write!(
f,
"a Git object identifier (SHA-1 digest in hexadecimal notation; {SHA1_DIGEST_STR_LEN} characters; {SHA1_DIGEST_LEN} bytes)"
"a Git object identifier (SHA-1 digest in hexadecimal notation; {} characters; {} bytes)",
crate::str::SHA1_DIGEST_STR_LEN,
Oid::LEN_SHA1
)
}
@ -571,9 +573,12 @@ mod schemars {
}
fn json_schema(_: &mut SchemaGenerator) -> Schema {
use crate::{SHA1_DIGEST_LEN, str::SHA1_DIGEST_STR_LEN};
use crate::str::SHA1_DIGEST_STR_LEN;
json_schema!({
"description": format!("A Git object identifier (SHA-1 digest in hexadecimal notation; {SHA1_DIGEST_STR_LEN} characters; {SHA1_DIGEST_LEN} bytes)"),
"description": format!(
"A Git object identifier (SHA-1 digest in hexadecimal notation; {SHA1_DIGEST_STR_LEN} characters; {} bytes)",
Oid::LEN_SHA1,
),
"type": "string",
"maxLength": SHA1_DIGEST_STR_LEN,
"minLength": SHA1_DIGEST_STR_LEN,