Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Streamline Text equality and comparison #108

Merged
merged 3 commits into from
Oct 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading