rhaiscript / rhai

Rhai - An embedded scripting language for Rust.
https://crates.io/crates/rhai
Apache License 2.0
3.63k stars 174 forks source link

Defining operators for CustomType #886

Closed madser123 closed 1 month ago

madser123 commented 1 month ago

In the documentation, it states:

It is strongly recommended that, when defining operators for custom types, always define the full set of six operators together, or at least the == and != pair.

But i can't find any example for defining operators for a custom type?

I've tried:

        tb.with_fn("<", |a, b| {
            Self::compare(a, b).expect("Could not compare prices") == Ordering::Less
        });
        tb.with_fn(">", |a, b| {
            Self::compare(a, b).expect("Could not compare prices") == Ordering::Greater
        });
        tb.with_fn("<=", |a, b| {
            let cmp = Self::compare(a, b).expect("Could not compare prices");
            cmp == Ordering::Less || cmp == Ordering::Equal
        });
        tb.with_fn(">=", |a, b| {
            let cmp = Self::compare(a, b).expect("Could not compare prices");
            cmp == Ordering::Greater || cmp == Ordering::Equal
        });
        tb.with_fn("!=", |a, b| {
            Self::compare(a, b).expect("Could not compare prices") != Ordering::Equal
        });
        tb.with_fn("==", |a, b| {
            Self::compare(a, b).expect("Could not compare prices") == Ordering::Equal
        });

But i still get an error that the function ">" wasn't found?

How do you define operators for custom types?

madser123 commented 1 month ago

After some more digging, i managed to find the solution: I had to use the Engine, not the typebuilder.

    engine.register_fn("==", |a: MyType, b: MyType| a == b);

Is it possible this could be in the typebuilder aswell? I have no idea how the two interact, so it's more of a question/suggestion.

And also, maybe adding a link to an example in the tip, would be awesome šŸ˜„

schungx commented 1 month ago

It should work, as the type builder simply delegates to the Engine for registration... they use the same code.

How about putting in the types for a and b? You'll find that suddenly you require & for compare.

tb.with_fn("<", |a: MyType, b: MyType| {
            Self::compare(&a, &b).expect("Could not compare prices") == Ordering::Less
        });

That's because, without types, Rust infers a and b to be &MyType instead of MyType.

madser123 commented 1 month ago

@schungx thank you for the swift reply. I will definitely try this later :+1:

madser123 commented 1 month ago

It worked wonders. Thank you šŸ‘