import enum import re from typing import overload class DIDMethod(enum.StrEnum): WEB = "web" PLC = "plc" class DID: __lexicon_string_format__ = "did" PATTERN = re.compile(r"^did:[a-z]+:[a-zA-Z0-9._:%-]*[a-zA-Z0-9._-]$") METHOD_PATTERN = re.compile(r"^[a-z]+$") VALUE_PATTERN = re.compile(r"^[a-zA-Z0-9._:%-]*[a-zA-Z0-9._-]$") __method: DIDMethod __value: str @overload def __init__(self, did: str, /): ... @overload def __init__(self, method: str | DIDMethod, value: str, /): ... def __init__(self, did_or_method: str | DIDMethod, value: str | None = None, /): if value is None: if not self.PATTERN.match(did_or_method): raise ValueError("Invalid DID: does not match pattern") did_or_method, value = did_or_method[4:].split(":", 1) else: if not ( isinstance(did_or_method, DIDMethod) or self.METHOD_PATTERN.match(did_or_method) ): raise ValueError("Invalid DID: method does not match pattern") if not self.VALUE_PATTERN.match(value): raise ValueError("Invalid DID: value does not match pattern") self.__method = ( DIDMethod(did_or_method) if not isinstance(did_or_method, DIDMethod) else did_or_method ) self.__value = value @property def method(self) -> str: return self.__method @property def value(self) -> str: return self.__value def __str__(self) -> str: return f"did:{self.__method}:{self.__value}" def __repr__(self) -> str: return str(self)