using Microsoft.Extensions.Logging; using System.Diagnostics.CodeAnalysis; using System.Text.RegularExpressions; namespace AltBot.Core.Models; /// /// Represents a Content Identifier (CID) /// public class Cid : IParsable { //private static readonly ILogger? _logger; private const int MaxLength = 1024; // Internal constructor for EF Core internal Cid(string value) { Value = value; } public string Value { get; } /// /// Creates a new Cid instance after validating the input string /// /// The raw CID string to validate /// A new Cid instance if valid, null otherwise public static Cid? Create(string rawCid) { return ValidateCid(rawCid) ? new Cid(rawCid) : null; } // For use when the Cid is known to be valid (e.g., loading from database) public static Cid Load(string rawCid) { return new Cid(rawCid); } private static bool ValidateCid(string cid) { if (string.IsNullOrWhiteSpace(cid)) { //_logger?.LogError("CID cannot be null or empty"); return false; } if (cid.Length > MaxLength) { //_logger?.LogError("CID is too long ({MaxLength} chars max)", MaxLength); return false; } // Very basic CID validation if (!Regex.IsMatch(cid, "^[123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz]+$")) { //_logger?.LogError("CID contains invalid characters"); return false; } return true; } public static Cid Parse(string s, IFormatProvider? provider) { if (TryParse(s, provider, out var result)) { return result; } throw new FormatException($"Unable to parse CID: {s}"); } public static bool TryParse([NotNullWhen(true)] string? s, IFormatProvider? provider, [MaybeNullWhen(false)] out Cid result) { if (s != null && ValidateCid(s)) { result = new Cid(s); return true; } result = null; return false; } public override string ToString() => Value; public override bool Equals(object? obj) { if (obj is Cid other) { return Value.Equals(other.Value, StringComparison.Ordinal); } return false; } public override int GetHashCode() => Value.GetHashCode(StringComparison.Ordinal); public static implicit operator string(Cid cid) => cid.Value; public static explicit operator Cid(string s) => Parse(s, null); public static bool operator ==(Cid? left, Cid? right) { if (ReferenceEquals(left, right)) { return true; } if (left is null || right is null) { return false; } return left.Equals(right); } public static bool operator !=(Cid? left, Cid? right) => !(left == right); }