In order to aid the creation of newtype structs, we should generate C# interface implementations and operator overloads that correspond to any derived traits so that the C# types behave as similarly as possible to the Rust types. For by-value types, the generated implementations will operate field-wise, the same way that the derived Rust impls do. For handle types we'll have to call into Rust code to use the Rust impls directly.
So for example, if an exported type derives PartialEq, we should implement the IEquatable interface and overload Equals for the generated C# type. Below are the traits we should detect along with the corresponding C# code that needs to be generated:
Hash - Overload GetHashCode(). It's worth noting that the implementation here will be not at all equivalent to the Rust implementation, due to the massive differences in how hashing is handled between the two languages. As long as the generated implementation meets the requirements for a C# hash (i.e. if the Equals() comparison returns true for two objects, they have the same hash code), it should work well for most use cases.
Additionally, the following traits don't have built-in derives but can be derived using crates like derive_more:
Add - operators + and +=.
Sub - operators - and -=.
Div - operators / and /=.
Mul - operators * and *=.
For these we may not want to automatically detect the derive (at least not without a feature flag), but it should be possible to opt-in to the generated implementations via attributes.
In order to aid the creation of newtype structs, we should generate C# interface implementations and operator overloads that correspond to any derived traits so that the C# types behave as similarly as possible to the Rust types. For by-value types, the generated implementations will operate field-wise, the same way that the derived Rust impls do. For handle types we'll have to call into Rust code to use the Rust impls directly.
So for example, if an exported type derives
PartialEq
, we should implement theIEquatable
interface and overloadEquals
for the generated C# type. Below are the traits we should detect along with the corresponding C# code that needs to be generated:PartialEq
(maybeEq
?) - ImplementIEquatable
, overloadEquals()
, operators==
and!=
.PartialOrd
(maybeOrd
?) - ImplementIComparable
, operators>
,>=
,<
, and<=
.Debug
- OverloadToString()
.Hash
- OverloadGetHashCode()
. It's worth noting that the implementation here will be not at all equivalent to the Rust implementation, due to the massive differences in how hashing is handled between the two languages. As long as the generated implementation meets the requirements for a C# hash (i.e. if theEquals()
comparison returnstrue
for two objects, they have the same hash code), it should work well for most use cases.Additionally, the following traits don't have built-in derives but can be derived using crates like derive_more:
Add
- operators+
and+=
.Sub
- operators-
and-=
.Div
- operators/
and/=
.Mul
- operators*
and*=
.For these we may not want to automatically detect the derive (at least not without a feature flag), but it should be possible to opt-in to the generated implementations via attributes.