using System.Diagnostics.CodeAnalysis;
using System.Text.RegularExpressions;
using Microsoft.Extensions.Logging;
namespace AltBot.Core.Models;
///
/// Represents a Decentralized Identifier (DID)
///
public class Did : IParsable
{
//private static readonly ILogger? _logger;
private const int MaxLength = 2048;
// Internal constructor for EF Core
internal Did(string value)
{
Value = value;
}
public string Value { get; }
///
/// Creates a new Did instance after validating the input string
///
/// The raw DID string to validate
/// A new Did instance if valid, null otherwise
public static Did? Create(string rawDid)
{
return ValidateDid(rawDid) ? new Did(rawDid) : null;
}
// For use when the Did is known to be valid (e.g., loading from database)
public static Did Load(string rawDid)
{
return new Did(rawDid);
}
private static bool ValidateDid(string did)
{
if (string.IsNullOrWhiteSpace(did))
{
//_logger?.LogError("DID cannot be null or empty");
return false;
}
var parts = did.Split(':');
if (parts.Length != 3)
{
//_logger?.LogError("DID requires prefix, method, and method-specific content");
return false;
}
if (parts[0] != "did")
{
//_logger?.LogError("DID must start with 'did' prefix");
return false;
};
// Basic method name validation
if (parts[1] is not "plc" and not "web")
{
//_logger?.LogError("DID method must be 'plc' or 'web'");
return false;
}
if (did.Length > MaxLength)
{
//_logger?.LogError("DID is too long ({MaxLength} chars max)", MaxLength);
return false;
}
return true;
}
public static Did Parse(string s, IFormatProvider? provider)
{
if (TryParse(s, provider, out var result))
{
return result;
}
throw new FormatException($"Unable to parse DID: {s}");
}
public static bool TryParse([NotNullWhen(true)] string? s, IFormatProvider? provider, [MaybeNullWhen(false)] out Did result)
{
if (s != null && ValidateDid(s))
{
result = new Did(s);
return true;
}
result = null;
return false;
}
public override string ToString() => Value;
public override bool Equals(object? obj)
{
if (obj is Did other)
{
return Value.Equals(other.Value, StringComparison.Ordinal);
}
return false;
}
public override int GetHashCode() => Value.GetHashCode(StringComparison.Ordinal);
public static implicit operator string(Did did) => did.Value;
public static explicit operator Did(string s) => Parse(s, null);
public static bool operator ==(Did? left, Did? right)
{
if (ReferenceEquals(left, right))
{
return true;
}
if (left is null || right is null)
{
return false;
}
return left.Equals(right);
}
public static bool operator !=(Did? left, Did? right) => !(left == right);
}