Skip to content

Commit bc0c972

Browse files
authored
mcf: add McfHash::from_id (#1924)
Simplifies constructing MCF hashes starting with a leading identifier. Also removes the previous logic for mandating at least one field, instead changing it to disallowing trailing `$`
1 parent 4c59f8d commit bc0c972

File tree

2 files changed

+34
-8
lines changed

2 files changed

+34
-8
lines changed

mcf/src/lib.rs

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,23 @@ impl McfHash {
6060
Ok(Self(s))
6161
}
6262

63+
/// Create an [`McfHash`] from an identifier.
64+
///
65+
/// # Returns
66+
///
67+
/// Error if the identifier is invalid.
68+
///
69+
/// Allowed characters match the regex: `[a-z0-9\-]`, where the first and last characters do NOT
70+
/// contain a `-`.
71+
pub fn from_id(id: &str) -> Result<McfHash> {
72+
validate_id(id)?;
73+
74+
let mut hash = String::with_capacity(1 + id.len());
75+
hash.push(fields::DELIMITER);
76+
hash.push_str(id);
77+
Ok(Self(hash))
78+
}
79+
6380
/// Get the contained string as a `str`.
6481
pub fn as_str(&self) -> &str {
6582
&self.0
@@ -125,6 +142,11 @@ impl str::FromStr for McfHash {
125142
/// Perform validations that the given string is well-formed MCF.
126143
#[cfg(feature = "alloc")]
127144
fn validate(s: &str) -> Result<()> {
145+
// Disallow trailing `$`
146+
if s.ends_with(fields::DELIMITER) {
147+
return Err(Error {});
148+
}
149+
128150
// Validates the hash begins with a leading `$`
129151
let mut fields = Fields::new(s)?;
130152

@@ -133,17 +155,10 @@ fn validate(s: &str) -> Result<()> {
133155
validate_id(id.as_str())?;
134156

135157
// Validate the remaining fields have an appropriate format
136-
let mut any = false;
137158
for field in fields {
138-
any = true;
139159
field.validate()?;
140160
}
141161

142-
// Must have at least one field.
143-
if !any {
144-
return Err(Error {});
145-
}
146-
147162
Ok(())
148163
}
149164

mcf/tests/mcf.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,16 @@ const EXAMPLE_HASH: &[u8] = &hex!(
1212
"0d358cad62739eb554863c183aef27e6390368fe061fc5fcb1193a392d60dcad4594fa8d383ab8fc3f0dc8088974602668422e6a58edfa1afe24831b10be69be"
1313
);
1414

15+
#[test]
16+
fn from_id() {
17+
let mcf_hash = McfHash::from_id("6").unwrap();
18+
assert_eq!("$6", mcf_hash.as_str());
19+
}
20+
1521
#[test]
1622
fn parse_malformed() {
1723
assert!("Hello, world!".parse::<McfHash>().is_err());
1824
assert!("$".parse::<McfHash>().is_err());
19-
assert!("$foo".parse::<McfHash>().is_err());
2025
assert!("$$".parse::<McfHash>().is_err());
2126
assert!("$$foo".parse::<McfHash>().is_err());
2227
assert!("$foo$".parse::<McfHash>().is_err());
@@ -25,6 +30,12 @@ fn parse_malformed() {
2530
assert!("$-foo$bar".parse::<McfHash>().is_err());
2631
}
2732

33+
#[test]
34+
fn parse_id_only() {
35+
let hash: McfHash = "$6".parse().unwrap();
36+
assert_eq!("6", hash.id());
37+
}
38+
2839
#[test]
2940
fn parse_sha512_hash() {
3041
let hash: McfHash = SHA512_HASH.parse().unwrap();

0 commit comments

Comments
 (0)