Skip to main content

Module all_equal_derive

Module all_equal_derive 

Source
Expand description

§#[derive(AllEqual)] - all.equal() for a pointer-backed class (#2149)

all.equal() on two objects of a class backed by an external pointer returns TRUE whatever they hold: all.equal.default() compares only data.class() for an external pointer, and an env-based (R6) or S4 object leads base R to the pointer, which it again can’t look into. The derive gives the type’s class an all.equal() method that compares the struct field by field, each with base all.equal() on the field’s R value, so each field dispatches on its own class: numbers keep R’s tolerance, lists and data frames use base’s methods, and a field holding another pointer class (T, ExternalPtr<T>, Option<ExternalPtr<T>>, or a Vec of T or ExternalPtr<T>) uses T’s method.

§What the derive emits

  • One .Call entry, C_<crate>__mx_all_equal_<Type>(x, i), of the sidecar accessors’ kind (no call slot): it returns compared field i (1-based) of the Rust value x carries, x being any receiver sidecar_r_struct reads (a pointer, or an R6 / S4 / S7 object, a list or an environment holding one in .ptr). Reading the value refuses a restored object with the type’s miniextendr_restored_* error. A field’s R value is

    • by default a clone converted with IntoR (Clone + IntoR);
    • #[all_equal(with = "Self::f")]: the getter’s value, a fn(&Self) -> impl IntoR;
    • a Computed field (#[r_data(get = "Self::f")]): its getter’s value;
    • a Sidecar<T> field: its slot in the pointer’s protection list;
    • an ExternalPtr<T> or Option<ExternalPtr<T>> field: the pointer itself (no copy).

    The RSidecar selector holds nothing and is never compared. Each call returns one value, so no R value is held across an allocation.

  • The R value of a field whose type names a pointer class is a bare external pointer (or a list of them), which base all.equal() would find equal to any other. The method gives it the class’s R class, as a method returning that type does (.__MX_WRAP_RETURN_T__ and .__MX_WRAP_LIST_RETURN_T__, resolved when the wrappers are written), so the comparison dispatches to the class’s own all.equal(). The field types are read as the method return types are (ParsedMethod::inner_class_ident), so T, ExternalPtr<T>, Option<ExternalPtr<T>> and a Vec of T or ExternalPtr<T> are wrapped (Option<T> of a class T is not IntoR, so it does not compile); a T that is not a class is left as it is. A getter’s type (with, Computed) is not known to the derive, so a getter returning a pointer gives a bare pointer (#2191).

  • A registry::AllEqualEntry with the method’s R source and its page. The class system and R class name are on the type’s impl block, a separate expansion, so the wrapper writer names and registers the method (registry::all_equal_fragments).

§The method

all.equal.<Class>(target, current, tolerance, scale, ..., check.attributes, check.names), in the argument order of all.equal.numeric(), so a third positional argument is the tolerance as it is for numbers:

  • A current whose data.class() differs from target’s gives base’s one string, "target is <class>, current is <class>", before any field is read.
  • Each compared field is compared with all.equal(target_field, current_field, <settings>, ...). A setting is passed only when something sets it, so a field’s own method keeps its default otherwise: the field’s #[all_equal(...)] fixes it, else the call gives it, else the struct’s #[all_equal(...)] is the formal’s default. The settings are formals, so a call’s check.attributes can’t also reach a field through ....
  • The result is TRUE, or every field’s messages in field order, each with all.equal.list()’s prefix (Component “estimates”: , or Component 1: for a tuple field) or the field’s #[all_equal(label = "...")] (Estimates: ).

Structs§

ClassWrap 🔒
The class the method gives a field’s R value: the R class of the Rust type class, on the value (list: on each element of the list), unless the value is NULL (optional: an Option field’s None).
ComparedField 🔒
A field the method compares.
FieldOptions 🔒
A field’s #[all_equal(...)].

Enums§

FieldValue 🔒
Where a compared field’s R value comes from (see the module docs).
Setting 🔒
An argument of base all.equal() the struct or a field can set.

Functions§

class_wrap 🔒
The class of a field of type ty when it names a pointer class, read as a method’s return type is: T or ExternalPtr<T> (T a capitalized path that is not a builtin), in Option<..>, Vec<..> or Option<Vec<..>>. Whether T is a class is known when the wrappers are written; a T that is not keeps the value as it is.
compared_fields 🔒
The fields the method compares, in declaration order.
derive_all_equal 🔒
#[derive(AllEqual)]: see the module docs.
getter_path 🔒
A getter path from with = "...", its leading Self replaced by the struct’s name: the .Call entry is a free function, outside any impl.
is_external_ptr 🔒
Whether ty is ExternalPtr<T>.
option_inner 🔒
T of Option<T>.
parse_field_options 🔒
parse_struct_settings 🔒
The struct’s #[all_equal(...)]: the defaults of the method’s formals.
path_name 🔒
push_setting 🔒
Adds the setting meta names to settings, refusing a second one.
r_docs 🔒
The roxygen lines of the method’s page after its title.
r_method 🔒
The method’s R source, function(target, current, ...) { ... }, reading the fields through the .Call entry c_name.
r_number 🔒
A finite number as R source: a whole number without a fraction (0, 2), any other in Rust’s shortest form (1e-6, 0.5).
setting_value 🔒
The value settings gives setting.

Type Aliases§

Settings 🔒
The settings given, with their values as R source, in source order.