use super::MethodError;
pub fn parse_did_method(did: &str) -> Result<&str, MethodError> {
let after_did = did
.strip_prefix("did:")
.ok_or_else(|| MethodError::Malformed(did.to_string()))?;
let (method, rest) = after_did
.split_once(':')
.ok_or_else(|| MethodError::Malformed(did.to_string()))?;
if method.is_empty() || rest.is_empty() {
return Err(MethodError::Malformed(did.to_string()));
}
if !method
.chars()
.all(|c| c.is_ascii_lowercase() || c.is_ascii_digit())
{
return Err(MethodError::Malformed(did.to_string()));
}
Ok(method)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn extracts_webvh_method() {
let m = parse_did_method("did:webvh:Q1Hh3jBb2:example.com:tenant:user1").unwrap();
assert_eq!(m, "webvh");
}
#[test]
fn extracts_web_method() {
let m = parse_did_method("did:web:example.com:tenant:user1").unwrap();
assert_eq!(m, "web");
}
#[test]
fn extracts_web_method_no_path() {
let m = parse_did_method("did:web:example.com").unwrap();
assert_eq!(m, "web");
}
#[test]
fn rejects_missing_did_prefix() {
assert!(parse_did_method("webvh:Q1:example.com").is_err());
assert!(parse_did_method("Q1:example.com").is_err());
assert!(parse_did_method("").is_err());
}
#[test]
fn rejects_missing_method_or_body() {
assert!(parse_did_method("did:").is_err());
assert!(parse_did_method("did::body").is_err());
assert!(parse_did_method("did:webvh:").is_err());
assert!(parse_did_method("did:webvh").is_err());
}
#[test]
fn rejects_uppercase_or_punctuation_in_method() {
assert!(parse_did_method("did:WebVH:Q1:host").is_err());
assert!(parse_did_method("did:web-vh:Q1:host").is_err());
assert!(parse_did_method("did:web_vh:Q1:host").is_err());
}
#[test]
fn accepts_alphanumeric_method_name() {
assert_eq!(parse_did_method("did:webs2:host:path").unwrap(), "webs2");
}
}