Skip to content

Commit

Permalink
Merge pull request #108 from greymistcube/refactor/text-equality
Browse files Browse the repository at this point in the history
Streamline `Text` equality and comparison
  • Loading branch information
greymistcube authored Oct 19, 2023
2 parents 7a7c0c0 + ea92917 commit 6d30b55
Show file tree
Hide file tree
Showing 3 changed files with 91 additions and 51 deletions.
64 changes: 64 additions & 0 deletions Bencodex.Tests/Types/TextTest.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System;
using Bencodex.Types;
using Xunit;
using static Bencodex.Misc.ImmutableByteArrayExtensions;
Expand All @@ -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<ArgumentException>(() => s.CompareTo(ot));
Assert.Throws<ArgumentException>(() => 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()
{
Expand Down
75 changes: 24 additions & 51 deletions Bencodex/Types/Text.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@ namespace Bencodex.Types
public struct Text :
IKey,
IEquatable<Text>,
IComparable<string>,
IComparable<Text>,
IEquatable<string>,
IComparable
{
private int? _utf8Length;
Expand Down Expand Up @@ -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<string>.Equals(string other)
{
return other != null && Value.Equals(other);
}
public static bool operator ==(Text left, string right) => left.Equals(right);

bool IEquatable<Text>.Equals(Text other) => Value.Equals(other);
public static bool operator !=(Text left, string right) => !left.Equals(right);

bool IEquatable<IValue>.Equals(IValue other) =>
other is Text o && ((IEquatable<Text>)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<Text>)this).Equals(txt);
case string str:
return ((IEquatable<string>)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<string>.CompareTo(string other)
public override int GetHashCode()
{
return string.Compare(Value, other, StringComparison.Ordinal);
return Value.GetHashCode();
}

int IComparable<Text>.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<Text>)this).CompareTo(txt);
case string str:
return ((IComparable<string>)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)}");
}

/// <inheritdoc cref="IValue.Inspect(bool)"/>
Expand Down
3 changes: 3 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<string>` and `IComparable<string>` from `Text`.
[[#104], [#108]]
- Removed `CompositeComparer<TA, TB>` 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


Expand Down

0 comments on commit 6d30b55

Please sign in to comment.