at main 3.1 kB view raw
1using Microsoft.Extensions.Logging; 2using System.Diagnostics.CodeAnalysis; 3using System.Text.RegularExpressions; 4 5namespace AltBot.Core.Models; 6 7/// <summary> 8/// Represents a Content Identifier (CID) 9/// </summary> 10public class Cid : IParsable<Cid> 11{ 12 //private static readonly ILogger<Cid>? _logger; 13 private const int MaxLength = 1024; 14 15 // Internal constructor for EF Core 16 internal Cid(string value) 17 { 18 Value = value; 19 } 20 21 public string Value { get; } 22 23 /// <summary> 24 /// Creates a new Cid instance after validating the input string 25 /// </summary> 26 /// <param name="rawCid">The raw CID string to validate</param> 27 /// <returns>A new Cid instance if valid, null otherwise</returns> 28 public static Cid? Create(string rawCid) 29 { 30 return ValidateCid(rawCid) ? new Cid(rawCid) : null; 31 } 32 33 // For use when the Cid is known to be valid (e.g., loading from database) 34 public static Cid Load(string rawCid) 35 { 36 return new Cid(rawCid); 37 } 38 39 private static bool ValidateCid(string cid) 40 { 41 if (string.IsNullOrWhiteSpace(cid)) 42 { 43 //_logger?.LogError("CID cannot be null or empty"); 44 return false; 45 } 46 47 if (cid.Length > MaxLength) 48 { 49 //_logger?.LogError("CID is too long ({MaxLength} chars max)", MaxLength); 50 return false; 51 } 52 53 // Very basic CID validation 54 if (!Regex.IsMatch(cid, "^[123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz]+$")) 55 { 56 //_logger?.LogError("CID contains invalid characters"); 57 return false; 58 } 59 60 return true; 61 } 62 63 public static Cid Parse(string s, IFormatProvider? provider) 64 { 65 if (TryParse(s, provider, out var result)) 66 { 67 return result; 68 } 69 throw new FormatException($"Unable to parse CID: {s}"); 70 } 71 72 public static bool TryParse([NotNullWhen(true)] string? s, IFormatProvider? provider, [MaybeNullWhen(false)] out Cid result) 73 { 74 if (s != null && ValidateCid(s)) 75 { 76 result = new Cid(s); 77 return true; 78 } 79 result = null; 80 return false; 81 } 82 83 public override string ToString() => Value; 84 85 public override bool Equals(object? obj) 86 { 87 if (obj is Cid other) 88 { 89 return Value.Equals(other.Value, StringComparison.Ordinal); 90 } 91 return false; 92 } 93 94 public override int GetHashCode() => Value.GetHashCode(StringComparison.Ordinal); 95 96 public static implicit operator string(Cid cid) => cid.Value; 97 98 public static explicit operator Cid(string s) => Parse(s, null); 99 100 public static bool operator ==(Cid? left, Cid? right) 101 { 102 if (ReferenceEquals(left, right)) 103 { 104 return true; 105 } 106 107 if (left is null || right is null) 108 { 109 return false; 110 } 111 112 return left.Equals(right); 113 } 114 115 public static bool operator !=(Cid? left, Cid? right) => !(left == right); 116}