Created
January 28, 2023 20:35
-
-
Save bwatts/8a7a99484a429f4a93c64d93c70c22ef to your computer and use it in GitHub Desktop.
I got annoyed checking if strings are null or whitespace in every message.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[JsonConverter(typeof(TextJsonConverter))] | |
[TypeConverter(typeof(TextTypeConverter))] | |
public sealed class Text : IEquatable<Text>, IEquatable<string>, IComparable<Text>, IComparable<string> | |
{ | |
readonly string _value; | |
Text(string value) => | |
_value = value; | |
public override string ToString() => | |
_value.ToString(); | |
public override int GetHashCode() => | |
_value.GetHashCode(); | |
public override bool Equals(object? obj) => | |
obj switch | |
{ | |
Text other => Equals(other), | |
string other => Equals(other), | |
_ => false | |
}; | |
public bool Equals(Text? other) => | |
_value == other?._value; | |
public bool Equals(string? other) => | |
_value == other; | |
public int CompareTo(Text? other) => | |
other is null ? 1 : _value.CompareTo(other._value); | |
public int CompareTo(string? other) => | |
other is null ? 1 : _value.CompareTo(other); | |
// | |
// Static API | |
// | |
public static bool TryFrom(string? value, [NotNullWhen(true)] out Text? text) => | |
(text = !string.IsNullOrWhiteSpace(value) ? new Text(value) : null) is not null; | |
public static Text From(string value) => | |
TryFrom(value, out var text) ? text : throw new ArgumentOutOfRangeException(nameof(value)); | |
public static bool operator ==(Text? x, Text? y) => EqualityComparer<Text?>.Default.Equals(x, y); | |
public static bool operator !=(Text? x, Text? y) => !(x == y); | |
public static bool operator <(Text? x, Text? y) => Comparer<Text?>.Default.Compare(x, y) < 0; | |
public static bool operator >(Text? x, Text? y) => Comparer<Text?>.Default.Compare(x, y) > 0; | |
public static bool operator <=(Text? x, Text? y) => Comparer<Text?>.Default.Compare(x, y) <= 0; | |
public static bool operator >=(Text? x, Text? y) => Comparer<Text?>.Default.Compare(x, y) >= 0; | |
public static bool operator ==(Text? x, string? y) => EqualityComparer<string?>.Default.Equals(x, y); | |
public static bool operator !=(Text? x, string? y) => !(x == y); | |
public static bool operator <(Text? x, string? y) => Comparer<string?>.Default.Compare(x?._value, y) < 0; | |
public static bool operator >(Text? x, string? y) => Comparer<string?>.Default.Compare(x?._value, y) > 0; | |
public static bool operator <=(Text? x, string? y) => Comparer<string?>.Default.Compare(x?._value, y) <= 0; | |
public static bool operator >=(Text? x, string? y) => Comparer<string?>.Default.Compare(x?._value, y) >= 0; | |
public static explicit operator Text(string value) => From(value); | |
public static implicit operator string(Text value) => value.ToString(); | |
// | |
// Converters | |
// | |
sealed class TextJsonConverter : JsonConverter<Text> | |
{ | |
public override Text? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => | |
TryFrom(reader.GetString(), out var text) ? text : null; | |
public override void Write(Utf8JsonWriter writer, Text value, JsonSerializerOptions options) => | |
writer.WriteStringValue(value.ToString()); | |
} | |
sealed class TextTypeConverter : TypeConverter | |
{ | |
public override bool CanConvertFrom(ITypeDescriptorContext? context, Type sourceType) => | |
sourceType == typeof(string); | |
public override bool CanConvertTo(ITypeDescriptorContext? context, Type? destinationType) => | |
destinationType == typeof(string); | |
public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value) => | |
value is string s ? From(s) : base.ConvertFrom(context, culture, value); | |
public override object? ConvertTo(ITypeDescriptorContext? context, CultureInfo? culture, object? value, Type destinationType) => | |
destinationType == typeof(string) && value is Text text | |
? text.ToString() | |
: base.ConvertTo(context, culture, value, destinationType); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment