diff --git a/Bencodex.Tests/Types/TextTest.cs b/Bencodex.Tests/Types/TextTest.cs index 73f5593..d5acfcb 100644 --- a/Bencodex.Tests/Types/TextTest.cs +++ b/Bencodex.Tests/Types/TextTest.cs @@ -1,3 +1,4 @@ +using System; using Bencodex.Types; using Xunit; using static Bencodex.Misc.ImmutableByteArrayExtensions; @@ -19,6 +20,69 @@ public void Kind() Assert.Equal(ValueKind.Text, _complex.Kind); } + [Fact] + public void Equality() + { + string s = "foo"; + Text t = new Text("foo"); + object os = (object)s; + object ot = (object)t; + +#pragma warning disable CS1718 // Comparison made to same variable + Assert.True(t == t); + Assert.True(t.Equals(t)); + Assert.True(t.Equals(ot)); + Assert.True(ot.Equals(t)); + Assert.True(ot.Equals(ot)); +#pragma warning restore CS1718 + + Assert.True(s == t); + Assert.True(t == s); + Assert.True(s.Equals(t)); + Assert.True(t.Equals(t)); + + Assert.False(s.Equals(ot)); + Assert.False(t.Equals(os)); + Assert.False(os.Equals(t)); + Assert.False(ot.Equals(s)); + Assert.False(os.Equals(ot)); + Assert.False(ot.Equals(os)); + } + + [Fact] + public void Comparison() + { + string s = "foo"; + Text t = new Text("foo"); + Text? n = null; + object os = (object)s; + object ot = (object)t; + object on = null; + + Assert.Equal(0, t.CompareTo(t)); + Assert.Equal(0, t.CompareTo(ot)); + Assert.Equal(1, t.CompareTo(n)); + Assert.Equal(1, t.CompareTo(on)); + + Assert.Equal(0, s.CompareTo(t)); + Assert.Equal(0, t.CompareTo(s)); + + Assert.Throws(() => s.CompareTo(ot)); + Assert.Throws(() => t.CompareTo(os)); + + Text t0 = new Text("0"); + Text t1 = new Text("1"); + Text t00 = new Text("00"); + + Assert.Equal(0, t0.CompareTo(t0)); + Assert.True(t0.CompareTo(t1) < 0); + Assert.True(t1.CompareTo(t0) > 0); + Assert.True(t0.CompareTo(t00) < 0); + Assert.True(t00.CompareTo(t0) > 0); + Assert.True(t1.CompareTo(t00) > 0); + Assert.True(t00.CompareTo(t1) < 0); + } + [Fact] public void EncodingLength() { diff --git a/Bencodex/Types/Text.cs b/Bencodex/Types/Text.cs index a2bd47d..27004c2 100644 --- a/Bencodex/Types/Text.cs +++ b/Bencodex/Types/Text.cs @@ -10,9 +10,7 @@ namespace Bencodex.Types public struct Text : IKey, IEquatable, - IComparable, IComparable, - IEquatable, IComparable { private int? _utf8Length; @@ -91,72 +89,47 @@ public static implicit operator Text(string s) return new Text(s); } - public static bool operator ==(Text left, Text right) - { - return left.Equals(right); - } + public static bool operator ==(Text left, Text right) => left.Equals(right); - public static bool operator !=(Text left, Text right) - { - return !left.Equals(right); - } + public static bool operator !=(Text left, Text right) => !left.Equals(right); - bool IEquatable.Equals(string other) - { - return other != null && Value.Equals(other); - } + public static bool operator ==(Text left, string right) => left.Equals(right); - bool IEquatable.Equals(Text other) => Value.Equals(other); + public static bool operator !=(Text left, string right) => !left.Equals(right); - bool IEquatable.Equals(IValue other) => - other is Text o && ((IEquatable)this).Equals(o); + public static bool operator ==(string left, Text right) => left.Equals(right.Value); - public override bool Equals(object obj) - { - switch (obj) - { - case null: - return false; - case Text txt: - return ((IEquatable)this).Equals(txt); - case string str: - return ((IEquatable)this).Equals(str); - default: - return false; - } - } + public static bool operator !=(string left, Text right) => !left.Equals(right.Value); - public override int GetHashCode() - { - return Value?.GetHashCode() ?? 0; - } + public bool Equals(IValue other) => other is Text t && Equals(t); + + public bool Equals(Text other) => Value.Equals(other); + + public override bool Equals(object obj) => obj is Text t && Equals(t); - int IComparable.CompareTo(string other) + public override int GetHashCode() { - return string.Compare(Value, other, StringComparison.Ordinal); + return Value.GetHashCode(); } - int IComparable.CompareTo(Text other) + public int CompareTo(Text other) { return string.Compare(Value, other.Value, StringComparison.Ordinal); } - public int CompareTo(object obj) + public int CompareTo(object? obj) { - switch (obj) + if (obj is null) { - case null: - return 1; - case Text txt: - return ((IComparable)this).CompareTo(txt); - case string str: - return ((IComparable)this).CompareTo(str); - default: - throw new ArgumentException( - "the argument is neither Text nor String", - nameof(obj) - ); + return 1; } + + if (obj is Text t) + { + return CompareTo(t); + } + + throw new ArgumentException($"Object must be of type {nameof(Text)}"); } /// diff --git a/CHANGES.md b/CHANGES.md index 2c892bd..b550c55 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -10,11 +10,14 @@ To be released. `Integer`. [[#104], [#107]] - Changed the behaviors of `Integer.Equals()` and `Integer.CompareTo()` to be more consistent. [[#106], [#107]] + - Removed `IEquatable` and `IComparable` from `Text`. + [[#104], [#108]] - Removed `CompositeComparer` struct. [[#109]] [#104]: https://github.com/planetarium/bencodex.net/issues/104 [#106]: https://github.com/planetarium/bencodex.net/issues/106 [#107]: https://github.com/planetarium/bencodex.net/pull/107 +[#108]: https://github.com/planetarium/bencodex.net/pull/108 [#109]: https://github.com/planetarium/bencodex.net/pull/109