| | 1 | | namespace Allyaria.Theming.Contracts; |
| | 2 | |
|
| | 3 | | /// <summary> |
| | 4 | | /// Represents a base class for theming values in Allyaria. Provides comparison, equality, and formatting functionality |
| | 5 | | /// strongly typed value wrappers. |
| | 6 | | /// </summary> |
| | 7 | | public abstract class ValueBase : IComparable<ValueBase>, IEquatable<ValueBase> |
| | 8 | | { |
| | 9 | | /// <summary>Initializes a new instance of the <see cref="ValueBase" /> class.</summary> |
| | 10 | | /// <param name="values">The underlying string value.</param> |
| 6444 | 11 | | protected ValueBase(params string[] values) => Value = string.Join(',', values); |
| | 12 | |
|
| | 13 | | /// <summary>Gets the raw string value represented by this instance.</summary> |
| 260 | 14 | | public virtual string Value { get; } |
| | 15 | |
|
| | 16 | | /// <summary>Compares two <see cref="ValueBase" /> instances for ordering.</summary> |
| | 17 | | /// <param name="left">The left-hand instance.</param> |
| | 18 | | /// <param name="right">The right-hand instance.</param> |
| | 19 | | /// <returns> |
| | 20 | | /// A value less than zero if <paramref name="left" /> is less than <paramref name="right" />, zero if they are equa |
| | 21 | | /// greater than zero if <paramref name="left" /> is greater than <paramref name="right" />. |
| | 22 | | /// </returns> |
| | 23 | | /// <exception cref="ArgumentException">Thrown when types of <paramref name="left" /> and <paramref name="right" /> |
| | 24 | | public static int Compare(ValueBase? left, ValueBase? right) |
| | 25 | | { |
| 50 | 26 | | if (left is null && right is null) |
| | 27 | | { |
| 2 | 28 | | return 0; |
| | 29 | | } |
| | 30 | |
|
| 48 | 31 | | if (left is null) |
| | 32 | | { |
| 2 | 33 | | return -1; |
| | 34 | | } |
| | 35 | |
|
| 46 | 36 | | if (right is null) |
| | 37 | | { |
| 4 | 38 | | return 1; |
| | 39 | | } |
| | 40 | |
|
| 42 | 41 | | if (left.GetType() != right.GetType()) |
| | 42 | | { |
| 6 | 43 | | throw new ArgumentException("Cannot compare values of different types."); |
| | 44 | | } |
| | 45 | |
|
| 36 | 46 | | return string.Compare(left.Value, right.Value, StringComparison.Ordinal); |
| | 47 | | } |
| | 48 | |
|
| | 49 | | /// <summary>Compares this instance to another <see cref="ValueBase" /> instance.</summary> |
| | 50 | | /// <param name="other">The other value to compare against.</param> |
| | 51 | | /// <returns> |
| | 52 | | /// A value less than zero if this instance is less than <paramref name="other" />, zero if they are equal, or great |
| | 53 | | /// zero if this instance is greater than <paramref name="other" />. |
| | 54 | | /// </returns> |
| | 55 | | /// <exception cref="ArgumentException">Thrown when the type of <paramref name="other" /> differs from this instance |
| | 56 | | public int CompareTo(ValueBase? other) |
| | 57 | | { |
| 14 | 58 | | if (ReferenceEquals(this, other)) |
| | 59 | | { |
| 2 | 60 | | return 0; |
| | 61 | | } |
| | 62 | |
|
| 12 | 63 | | if (other is null) |
| | 64 | | { |
| 2 | 65 | | return 1; |
| | 66 | | } |
| | 67 | |
|
| 10 | 68 | | if (GetType() != other.GetType()) |
| | 69 | | { |
| 2 | 70 | | throw new ArgumentException("Cannot compare values of different types."); |
| | 71 | | } |
| | 72 | |
|
| 8 | 73 | | return string.Compare(Value, other.Value, StringComparison.Ordinal); |
| | 74 | | } |
| | 75 | |
|
| | 76 | | /// <summary>Determines whether the specified object is equal to this instance.</summary> |
| | 77 | | /// <param name="obj">The object to compare with.</param> |
| | 78 | | /// <returns><c>true</c> if the specified object is equal to this instance; otherwise, <c>false</c>.</returns> |
| 38 | 79 | | public override bool Equals(object? obj) => obj is ValueBase other && Equals(other); |
| | 80 | |
|
| | 81 | | /// <summary>Determines whether the specified <see cref="ValueBase" /> is equal to this instance.</summary> |
| | 82 | | /// <param name="other">The other value to compare with.</param> |
| | 83 | | /// <returns><c>true</c> if the instances are equal; otherwise, <c>false</c>.</returns> |
| 38 | 84 | | public bool Equals(ValueBase? other) => Compare(this, other) is 0; |
| | 85 | |
|
| | 86 | | /// <summary>Determines whether two <see cref="ValueBase" /> instances are equal.</summary> |
| | 87 | | /// <param name="left">The left-hand instance.</param> |
| | 88 | | /// <param name="right">The right-hand instance.</param> |
| | 89 | | /// <returns><c>true</c> if both instances are equal; otherwise, <c>false</c>.</returns> |
| 8 | 90 | | public static bool Equals(ValueBase? left, ValueBase? right) => left?.Equals(right) is true; |
| | 91 | |
|
| | 92 | | /// <summary>Returns a hash code for this instance based on its <see cref="Value" />.</summary> |
| | 93 | | /// <returns>A hash code for this instance.</returns> |
| 4 | 94 | | public override int GetHashCode() => Value.GetHashCode(StringComparison.Ordinal); |
| | 95 | |
|
| | 96 | | /// <summary>Converts the current value into a CSS declaration string for the specified property.</summary> |
| | 97 | | /// <param name="propertyName">The CSS property name. If <c>null</c> or whitespace, only the value is returned.</par |
| | 98 | | /// <returns> |
| | 99 | | /// A CSS declaration in the format <c>"property: value;"</c> if <paramref name="propertyName" /> is provided; other |
| | 100 | | /// just the <see cref="Value" />. |
| | 101 | | /// </returns> |
| | 102 | | public string ToCss(string propertyName) |
| 406 | 103 | | => string.IsNullOrWhiteSpace(propertyName) |
| 406 | 104 | | ? Value |
| 406 | 105 | | : $"{propertyName.ToLowerInvariant().Trim()}:{Value};"; |
| | 106 | |
|
| | 107 | | /// <summary>Returns the string representation of this instance.</summary> |
| | 108 | | /// <returns>The raw string value.</returns> |
| 34 | 109 | | public override string ToString() => Value; |
| | 110 | |
|
| | 111 | | /// <summary>Validates and normalizes a raw string input for use in theming value objects.</summary> |
| | 112 | | /// <param name="value">The input string to validate. Must not be <c>null</c>, empty, or whitespace-only.</param> |
| | 113 | | /// <returns>A trimmed version of <paramref name="value" /> with leading and trailing whitespace removed.</returns> |
| | 114 | | /// <exception cref="ArgumentException"> |
| | 115 | | /// Thrown when <paramref name="value" /> is <c>null</c>, empty, consists only of whitespace, or contains disallowed |
| | 116 | | /// control characters (all Unicode control characters except tab, line feed, and carriage return). |
| | 117 | | /// </exception> |
| | 118 | | protected static string ValidateInput(string value) |
| | 119 | | { |
| 382 | 120 | | ArgumentException.ThrowIfNullOrWhiteSpace(value, nameof(value)); |
| | 121 | |
|
| 356 | 122 | | var trimmed = value.Trim(); |
| | 123 | |
|
| 2914 | 124 | | return trimmed.Any(static c => char.IsControl(c)) |
| 356 | 125 | | ? throw new ArgumentException("Value contains control characters.", nameof(value)) |
| 356 | 126 | | : trimmed; |
| | 127 | | } |
| | 128 | |
|
| | 129 | | /// <summary>Determines whether two instances are equal.</summary> |
| 4 | 130 | | public static bool operator ==(ValueBase? left, ValueBase? right) => Compare(left, right) == 0; |
| | 131 | |
|
| | 132 | | /// <summary>Determines whether one instance is greater than another.</summary> |
| 2 | 133 | | public static bool operator >(ValueBase left, ValueBase right) => left.CompareTo(right) > 0; |
| | 134 | |
|
| | 135 | | /// <summary>Determines whether one instance is greater than or equal to another.</summary> |
| 2 | 136 | | public static bool operator >=(ValueBase left, ValueBase right) => left.CompareTo(right) >= 0; |
| | 137 | |
|
| | 138 | | /// <summary>Determines whether two instances are not equal.</summary> |
| 2 | 139 | | public static bool operator !=(ValueBase? left, ValueBase? right) => !(left == right); |
| | 140 | |
|
| | 141 | | /// <summary>Determines whether one instance is less than another.</summary> |
| 2 | 142 | | public static bool operator <(ValueBase left, ValueBase right) => left.CompareTo(right) < 0; |
| | 143 | |
|
| | 144 | | /// <summary>Determines whether one instance is less than or equal to another.</summary> |
| 2 | 145 | | public static bool operator <=(ValueBase left, ValueBase right) => left.CompareTo(right) <= 0; |
| | 146 | | } |