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

Add Equals to DynamicData #35733

Merged
merged 9 commits into from
Apr 24, 2023
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ public sealed partial class DynamicData : System.Dynamic.IDynamicMetaObjectProvi
{
internal DynamicData() { }
public void Dispose() { }
public override bool Equals(object? obj) { throw null; }
public override int GetHashCode() { throw null; }
public static bool operator ==(Azure.Core.Dynamic.DynamicData? left, object? right) { throw null; }
public static implicit operator bool (Azure.Core.Dynamic.DynamicData value) { throw null; }
public static implicit operator double (Azure.Core.Dynamic.DynamicData value) { throw null; }
public static implicit operator int (Azure.Core.Dynamic.DynamicData value) { throw null; }
Expand All @@ -130,6 +133,7 @@ public sealed partial class DynamicData : System.Dynamic.IDynamicMetaObjectProvi
public static implicit operator float? (Azure.Core.Dynamic.DynamicData value) { throw null; }
public static implicit operator float (Azure.Core.Dynamic.DynamicData value) { throw null; }
public static implicit operator string (Azure.Core.Dynamic.DynamicData value) { throw null; }
public static bool operator !=(Azure.Core.Dynamic.DynamicData? left, object? right) { throw null; }
System.Dynamic.DynamicMetaObject System.Dynamic.IDynamicMetaObjectProvider.GetMetaObject(System.Linq.Expressions.Expression parameter) { throw null; }
public override string ToString() { throw null; }
}
Expand Down Expand Up @@ -194,7 +198,11 @@ public sealed partial class MutableJsonDocument : System.IDisposable
public void Set(string value) { }
public Azure.Core.Json.MutableJsonElement SetProperty(string name, object value) { throw null; }
public override string ToString() { throw null; }
public bool TryGetDouble(out double value) { throw null; }
public bool TryGetInt32(out int value) { throw null; }
public bool TryGetInt64(out long value) { throw null; }
public bool TryGetProperty(string name, out Azure.Core.Json.MutableJsonElement value) { throw null; }
public bool TryGetSingle(out float value) { throw null; }
[System.Diagnostics.DebuggerDisplayAttribute("{Current,nq}")]
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public partial struct ArrayEnumerator : System.Collections.Generic.IEnumerable<Azure.Core.Json.MutableJsonElement>, System.Collections.Generic.IEnumerator<Azure.Core.Json.MutableJsonElement>, System.Collections.IEnumerable, System.Collections.IEnumerator, System.IDisposable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ public sealed partial class DynamicData : System.Dynamic.IDynamicMetaObjectProvi
{
internal DynamicData() { }
public void Dispose() { }
public override bool Equals(object? obj) { throw null; }
public override int GetHashCode() { throw null; }
public static bool operator ==(Azure.Core.Dynamic.DynamicData? left, object? right) { throw null; }
public static implicit operator bool (Azure.Core.Dynamic.DynamicData value) { throw null; }
public static implicit operator double (Azure.Core.Dynamic.DynamicData value) { throw null; }
public static implicit operator int (Azure.Core.Dynamic.DynamicData value) { throw null; }
Expand All @@ -130,6 +133,7 @@ public sealed partial class DynamicData : System.Dynamic.IDynamicMetaObjectProvi
public static implicit operator float? (Azure.Core.Dynamic.DynamicData value) { throw null; }
public static implicit operator float (Azure.Core.Dynamic.DynamicData value) { throw null; }
public static implicit operator string (Azure.Core.Dynamic.DynamicData value) { throw null; }
public static bool operator !=(Azure.Core.Dynamic.DynamicData? left, object? right) { throw null; }
System.Dynamic.DynamicMetaObject System.Dynamic.IDynamicMetaObjectProvider.GetMetaObject(System.Linq.Expressions.Expression parameter) { throw null; }
public override string ToString() { throw null; }
}
Expand Down Expand Up @@ -194,7 +198,11 @@ public sealed partial class MutableJsonDocument : System.IDisposable
public void Set(string value) { }
public Azure.Core.Json.MutableJsonElement SetProperty(string name, object value) { throw null; }
public override string ToString() { throw null; }
public bool TryGetDouble(out double value) { throw null; }
public bool TryGetInt32(out int value) { throw null; }
public bool TryGetInt64(out long value) { throw null; }
public bool TryGetProperty(string name, out Azure.Core.Json.MutableJsonElement value) { throw null; }
public bool TryGetSingle(out float value) { throw null; }
[System.Diagnostics.DebuggerDisplayAttribute("{Current,nq}")]
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public partial struct ArrayEnumerator : System.Collections.Generic.IEnumerable<Azure.Core.Json.MutableJsonElement>, System.Collections.Generic.IEnumerator<Azure.Core.Json.MutableJsonElement>, System.Collections.IEnumerable, System.Collections.IEnumerator, System.IDisposable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,9 @@ public sealed partial class DynamicData : System.Dynamic.IDynamicMetaObjectProvi
{
internal DynamicData() { }
public void Dispose() { }
public override bool Equals(object? obj) { throw null; }
public override int GetHashCode() { throw null; }
public static bool operator ==(Azure.Core.Dynamic.DynamicData? left, object? right) { throw null; }
public static implicit operator bool (Azure.Core.Dynamic.DynamicData value) { throw null; }
public static implicit operator double (Azure.Core.Dynamic.DynamicData value) { throw null; }
public static implicit operator int (Azure.Core.Dynamic.DynamicData value) { throw null; }
Expand All @@ -130,6 +133,7 @@ public sealed partial class DynamicData : System.Dynamic.IDynamicMetaObjectProvi
public static implicit operator float? (Azure.Core.Dynamic.DynamicData value) { throw null; }
public static implicit operator float (Azure.Core.Dynamic.DynamicData value) { throw null; }
public static implicit operator string (Azure.Core.Dynamic.DynamicData value) { throw null; }
public static bool operator !=(Azure.Core.Dynamic.DynamicData? left, object? right) { throw null; }
System.Dynamic.DynamicMetaObject System.Dynamic.IDynamicMetaObjectProvider.GetMetaObject(System.Linq.Expressions.Expression parameter) { throw null; }
public override string ToString() { throw null; }
}
Expand Down Expand Up @@ -194,7 +198,11 @@ public sealed partial class MutableJsonDocument : System.IDisposable
public void Set(string value) { }
public Azure.Core.Json.MutableJsonElement SetProperty(string name, object value) { throw null; }
public override string ToString() { throw null; }
public bool TryGetDouble(out double value) { throw null; }
public bool TryGetInt32(out int value) { throw null; }
public bool TryGetInt64(out long value) { throw null; }
public bool TryGetProperty(string name, out Azure.Core.Json.MutableJsonElement value) { throw null; }
public bool TryGetSingle(out float value) { throw null; }
[System.Diagnostics.DebuggerDisplayAttribute("{Current,nq}")]
[System.Runtime.InteropServices.StructLayoutAttribute(System.Runtime.InteropServices.LayoutKind.Sequential)]
public partial struct ArrayEnumerator : System.Collections.Generic.IEnumerable<Azure.Core.Json.MutableJsonElement>, System.Collections.Generic.IEnumerator<Azure.Core.Json.MutableJsonElement>, System.Collections.IEnumerable, System.Collections.IEnumerator, System.IDisposable
Expand Down
40 changes: 40 additions & 0 deletions sdk/core/Azure.Core.Experimental/src/DynamicData.Operators.cs
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,46 @@ public partial class DynamicData
}
}

/// <summary>
/// Determines whether the specified <see cref="DynamicData"/> and <see cref="object"/> have the same value.
/// </summary>
/// <remarks>
/// This operator calls through to <see cref="DynamicData.Equals(object?)"/> when DynamicData is on the left-hand
/// side of the operation. <see cref="DynamicData.Equals(object?)"/> has value semantics when the DynamicData represents
/// a JSON primitive, i.e. string, bool, number, or null, and reference semantics otherwise, i.e. for objects and arrays.
///
/// Please note that if DynamicData is on the right-hand side of a <c>==</c> operation, this operator will not be invoked.
/// Because of this the result of a <c>==</c> comparison with <c>null</c> on the left and a DynamicData instance on the right will return <c>false</c>.
/// </remarks>
/// <param name="left">The <see cref="DynamicData"/> to compare.</param>
/// <param name="right">The <see cref="object"/> to compare.</param>
/// <returns><c>true</c> if the value of <paramref name="left"/> is the same as the value of <paramref name="right"/>; otherwise, <c>false</c>.</returns>
public static bool operator ==(DynamicData? left, object? right)
{
if (left is null)
{
return right is null;
}

return left.Equals(right);
}

/// <summary>
/// Determines whether the specified <see cref="DynamicData"/> and <see cref="object"/> have different values.
/// </summary>
/// <remarks>
/// This operator calls through to <see cref="DynamicData.Equals(object?)"/> when DynamicData is on the left-hand
/// side of the operation. <see cref="DynamicData.Equals(object?)"/> has value semantics when the DynamicData represents
/// a JSON primitive, i.e. string, bool, number, or null, and reference semantics otherwise, i.e. for objects and arrays.
///
/// Please note that if DynamicData is on the right-hand side of a <c>!=</c> operation, this operator will not be invoked.
/// Because of this the result of a <c>!=</c> comparison with <c>null</c> on the left and a DynamicData instance on the right will return <c>true</c>.
/// </remarks>
/// <param name="left">The <see cref="DynamicData"/> to compare.</param>
/// <param name="right">The <see cref="object"/> to compare.</param>
/// <returns><c>true</c> if the value of <paramref name="left"/> is different from the value of <paramref name="right"/>; otherwise, <c>false</c>.</returns>
public static bool operator !=(DynamicData? left, object? right) => !(left == right);

private static string GetInvalidCastExceptionText(Type target, MutableJsonElement element)
{
return $"Unable to cast element to '{target}'. Element has kind '{element.ValueKind}'.";
Expand Down
90 changes: 90 additions & 0 deletions sdk/core/Azure.Core.Experimental/src/DynamicData.cs
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,96 @@ public void Dispose()
_element.DisposeRoot();
}

/// <inheritdoc/>
public override bool Equals(object? obj)
{
if (obj is null)
{
return _element.ValueKind == JsonValueKind.Null;
}

if (_element.ValueKind == JsonValueKind.Null)
{
return obj is null || obj is DynamicData d && Equals(d);
annelo-msft marked this conversation as resolved.
Show resolved Hide resolved
}

return obj switch
{
string s =>
_element.ValueKind == JsonValueKind.String &&
_element.GetString() == s,

bool b =>
(_element.ValueKind == JsonValueKind.True ||
_element.ValueKind == JsonValueKind.False) &&
_element.GetBoolean() == b,

double d =>
_element.ValueKind == JsonValueKind.Number &&
_element.TryGetDouble(out double od) && d == od,

float f =>
_element.ValueKind == JsonValueKind.Number &&
_element.TryGetSingle(out float of) && f == of,

long l =>
_element.ValueKind == JsonValueKind.Number &&
_element.TryGetInt64(out long ol) && l == ol,

int i =>
_element.ValueKind == JsonValueKind.Number &&
_element.TryGetInt32(out int oi) && i == oi,

DynamicData data => Equals(data),

_ => base.Equals(obj),
};
}

internal bool Equals(DynamicData other)
{
if (other is null)
{
return _element.ValueKind == JsonValueKind.Null;
}

if (_element.ValueKind != other._element.ValueKind)
{
return false;
}

return _element.ValueKind switch
{
JsonValueKind.String => _element.GetString() == other._element.GetString(),
JsonValueKind.Number => NumberEqual(other),
JsonValueKind.True => true,
JsonValueKind.False => true,
JsonValueKind.Null => true,
heaths marked this conversation as resolved.
Show resolved Hide resolved
_ => base.Equals(other)
};
}

private bool NumberEqual(DynamicData other)
annelo-msft marked this conversation as resolved.
Show resolved Hide resolved
{
if (_element.TryGetDouble(out double d))
{
return other._element.TryGetDouble(out Double od) && d == od;
}

if (_element.TryGetInt64(out long l))
{
return other._element.TryGetInt64(out long ol) && l == ol;
}

return false;
}

/// <inheritdoc/>
public override int GetHashCode()
{
return _element.GetHashCode();
}

[DebuggerBrowsable(DebuggerBrowsableState.Never)]
private string DebuggerDisplay => _element.DebuggerDisplay;

Expand Down
Loading