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

Implement Eq and Hash trait methods #97

Merged
merged 3 commits into from
Nov 18, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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
25 changes: 24 additions & 1 deletion bindgen/templates/ObjectTemplate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,15 @@
{%- if self.include_once_check("ObjectRuntime.cs") %}{% include "ObjectRuntime.cs" %}{% endif %}

{%- call cs::docstring(obj, 0) %}
{{ config.access_modifier() }} interface I{{ type_name }} {
{{ config.access_modifier() }} interface I{{ type_name }}
{%- for tm in obj.uniffi_traits() -%}
{%- if loop.first -%} : {% endif -%}
cmcknight-bb marked this conversation as resolved.
Show resolved Hide resolved
{%- match tm -%}
{%- when UniffiTrait::Eq { eq, ne } -%}
IEquatable<{{type_name}}>
{%- else -%}
{%- endmatch -%}
{%- endfor %} {
{% for meth in obj.methods() -%}
{%- call cs::docstring(meth, 4) %}
{%- call cs::method_throws_annotation(meth.throws_type()) %}
Expand Down Expand Up @@ -63,6 +71,21 @@ override protected bool ReleaseHandle() {
public override string ToString() {
return {{ Type::String.borrow()|lift_fn }}({%- call cs::to_ffi_call_with_prefix("this.GetHandle()", fmt) %});
}
{%- when UniffiTrait::Eq { eq, ne } %}
public bool Equals({{type_name}}? other)
{
if (other is null) return false;
return {{ Type::Boolean.borrow()|lift_fn }}({%- call cs::to_ffi_call_with_prefix("this.GetHandle()", eq) %});
}
public override bool Equals(object? obj)
{
if (obj is null || !(obj is {{type_name}})) return false;
return Equals(obj as {{type_name}});
}
{%- when UniffiTrait::Hash { hash } %}
public override int GetHashCode() {
return (int){{ Type::UInt64.borrow()|lift_fn }}({%- call cs::to_ffi_call_with_prefix("this.GetHandle()", hash) %});
}
{%- else %}
{%- endmatch %}
{%- endfor %}
Expand Down
113 changes: 110 additions & 3 deletions dotnet-tests/UniffiCS.BindingTests/TestTraitMethod.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

using System;
using System.Collections.Generic;
using uniffi.trait_methods;

namespace UniffiCS.BindingTests;

public class TestTraitMethods
{
[Fact]
public void TraitMethodsWork()
public void TestDisplay()
{
using (var methods = new TraitMethods("yo"))
{
Expand All @@ -18,11 +20,116 @@ public void TraitMethodsWork()
}

[Fact]
public void TraitMethodsProcMacro()
public void TestEq()
{
using (var methods = new TraitMethods("yo"))
{
// Values are equal if input is the same
Assert.Equal(methods, new TraitMethods("yo"));
Assert.NotEqual(methods, new TraitMethods("yoyo"));

// Values are not referentially equal
Assert.False(methods == new TraitMethods("yo"));
}
}

[Fact]
public void TestEqNull()
{
TraitMethods? t1 = null;
TraitMethods? t2 = null;
Assert.True(Object.Equals(t1, t2));

t1 = new TraitMethods("yo");
Assert.False(Object.Equals(t1, t2));

Assert.False(new TraitMethods("yo") == null);
Assert.True(new TraitMethods("yo") != null);
}

[Fact]
public void TestEqContains()
{
var tm = new TraitMethods("yo");
var list = new List<TraitMethods>
{
tm
};

Assert.Contains(tm, list);
Assert.Contains(new TraitMethods("yo"), list);
Assert.DoesNotContain(null, list);
Assert.DoesNotContain(new TraitMethods("yoyo"), list);
}

[Fact]
public void TestHash()
{
using (var methods = new TraitMethods("yo"))
{
Assert.Equal(methods.GetHashCode(), new TraitMethods("yo").GetHashCode());
Assert.NotEqual(methods.GetHashCode(), new TraitMethods("yoyo").GetHashCode());
}
}
}

public class TestProcMacroTraitMethods
{
[Fact]
public void TestDisplay()
{
using (var methods = new ProcTraitMethods("yo"))
{
Assert.Equal("ProcTraitMethods(yo)", methods.ToString());
}
}
}

[Fact]
public void TestEq()
{
using (var methods = new ProcTraitMethods("yo"))
{
// Values are equal if input is the same
Assert.Equal(methods, new ProcTraitMethods("yo"));
Assert.NotEqual(methods, new ProcTraitMethods("yoyo"));

// Values are not referentially equal
Assert.False(methods == new ProcTraitMethods("yo"));
}
}

[Fact]
public void TestEqNull()
{
ProcTraitMethods? t1 = null;
ProcTraitMethods? t2 = null;
Assert.True(Object.Equals(t1, t2));

Assert.False(new ProcTraitMethods("yo") == null);
}

[Fact]
public void TestEqContains()
{
var tm = new ProcTraitMethods("yo");
var list = new List<ProcTraitMethods>
{
tm
};

Assert.Contains(tm, list);
Assert.Contains(new ProcTraitMethods("yo"), list);
Assert.DoesNotContain(null, list);
Assert.DoesNotContain(new ProcTraitMethods("yoyo"), list);
}

[Fact]
public void TestHash()
{
using (var methods = new ProcTraitMethods("yo"))
{
Assert.Equal(methods.GetHashCode(), new ProcTraitMethods("yo").GetHashCode());
Assert.NotEqual(methods.GetHashCode(), new ProcTraitMethods("yoyo").GetHashCode());
}
}
}
Loading