AltHeroes Bot v2
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}