Thanks to visit codestin.com
Credit goes to docs.rs

IsEql

Trait IsEql 

Source
pub trait IsEql {
    // Required method
    fn is_eql(&self, other: Value) -> bool;
}
Expand description

Trait for a Ruby-compatible #eql? method.

Automatically implemented for any type implementing Eq and TryConvert.

See also Dup, Inspect, typed_data::Cmp, and typed_data::Hash.

§Examples

use std::hash::Hasher;

use magnus::{
    function, gc, method, prelude::*, typed_data, value::Opaque, DataTypeFunctions, Error,
    Ruby, TypedData, Value,
};

#[derive(TypedData)]
#[magnus(class = "Pair", free_immediately, mark)]
struct Pair {
    #[magnus(opaque_attr_reader)]
    a: Opaque<Value>,
    #[magnus(opaque_attr_reader)]
    b: Opaque<Value>,
}

impl Pair {
    fn new(a: Value, b: Value) -> Self {
        Self {
            a: a.into(),
            b: b.into(),
        }
    }
}

impl DataTypeFunctions for Pair {
    fn mark(&self, marker: &gc::Marker) {
        marker.mark(self.a);
        marker.mark(self.b);
    }
}

impl std::hash::Hash for Pair {
    fn hash<H: Hasher>(&self, state: &mut H) {
        state.write_i64(
            self.a()
                .hash()
                .expect("#hash should not fail")
                .to_i64()
                .expect("#hash result guaranteed to be <= i64"),
        );
        state.write_i64(
            self.b()
                .hash()
                .expect("#hash should not fail")
                .to_i64()
                .expect("#hash result guaranteed to be <= i64"),
        );
    }
}

impl PartialEq for Pair {
    fn eq(&self, other: &Self) -> bool {
        self.a().eql(other.a()).unwrap_or(false) && self.b().eql(other.b()).unwrap_or(false)
    }
}

impl Eq for Pair {}

fn example(ruby: &Ruby) -> Result<(), Error> {
    let class = ruby.define_class("Pair", ruby.class_object())?;
    class.define_singleton_method("new", function!(Pair::new, 2))?;
    class.define_method("hash", method!(<Pair as typed_data::Hash>::hash, 0))?;
    class.define_method("eql?", method!(<Pair as typed_data::IsEql>::is_eql, 1))?;

    let a = Pair::new(
        ruby.str_new("foo").as_value(),
        ruby.integer_from_i64(1).as_value(),
    );
    let hash = ruby.hash_new();
    hash.aset(a, "test value")?;

    let b = Pair::new(
        ruby.str_new("foo").as_value(),
        ruby.integer_from_i64(1).as_value(),
    );
    assert_eq!("test value", hash.fetch::<_, String>(b)?);

    let c = Pair::new(
        ruby.str_new("bar").as_value(),
        ruby.integer_from_i64(2).as_value(),
    );
    assert!(hash.get(c).is_none());

    Ok(())
}

Required Methods§

Source

fn is_eql(&self, other: Value) -> bool

Implementors§

Source§

impl<'a, T> IsEql for T
where T: Eq + 'a, &'a T: TryConvert,