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

Add support for field functions and deriving default implementations #169

Merged
merged 4 commits into from
Nov 25, 2020

Conversation

udoprog
Copy link
Collaborator

@udoprog udoprog commented Nov 24, 2020

This introduces "field functions", which are functions that can be registered to operate over field accesses. The most famous of which are getters and setters.

The Any derive can also generate default implementations of these field functions through various #[rune(...)] attributes:

#[derive(Any, Debug, Default)]
struct Foo {
    #[rune(get, set, copy)]
    number: i64,
    #[rune(get, set)]
    string: String,
}

Once registered, this allows Foo to be used like this in Rune:

pub fn main(foo) {
    foo.number = foo.number + 1;
    foo.string = `${foo.string} World`;
}

The full list of available field functions and their corresponding derives are:

  • #[rune(get)] - for field getters (Protocol::GET).
  • #[rune(set)] - for field setters (Protocol::SET).
  • #[rune(add_assign)] - the += operation (Protocol::ADD_ASSIGN).
  • #[rune(sub_assign)] - the -= operation (Protocol::SUB_ASSIGN).
  • #[rune(mul_assign)] - the *= operation (Protocol::MUL_ASSIGN).
  • #[rune(div_assign)] - the /= operation (Protocol::DIV_ASSIGN).
  • #[rune(bit_and_assign)] - the &= operation (Protocol::BIT_AND_ASSIGN).
  • #[rune(bit_or_assign)] - the |= operation (Protocol::BIT_OR_ASSIGN).
  • #[rune(bit_xor_assign)] - the ^= operation (Protocol::BIT_XOR_ASSIGN).
  • #[rune(shl_assign)] - the <<= operation (Protocol::SHL_ASSIGN).
  • #[rune(shr_assign)] - the >>= operation (Protocol::SHR_ASSIGN).

The manual way to register these functions is to use the new Module::field_fn function. This clearly showcases that there's no relationship between the field used and the function registered:

struct External {
}

impl External {
    fn field_get(&self) -> String {
        String::from("Hello World")
    }
}

let mut module = Module::empty();
module.field_fn(Protocol::GET, "field", External::field_get)?;

Would allow for this in Rune:

pub fn main(external) {
    println!("{}", external.field);
}

TODO

Make it possible to overload the implementation function by specifying an argument to the given operation, like: #[rune(add_assign = "my_add_assign")].

@udoprog udoprog added enhancement New feature or request vm Issues related to the virtual machine. labels Nov 24, 2020
@udoprog udoprog force-pushed the setters-getters-derive branch from e66d522 to 2f7e102 Compare November 24, 2020 16:58
@udoprog udoprog force-pushed the setters-getters-derive branch from 0fa9ab3 to 98f7908 Compare November 25, 2020 01:01
@udoprog udoprog changed the title Add support for deriving setters and getters through Any Add support for deriving field operations through Any Nov 25, 2020
@udoprog udoprog changed the title Add support for deriving field operations through Any Add support for field functions and deriving default implementations Nov 25, 2020
@udoprog udoprog merged commit fa1297e into main Nov 25, 2020
@udoprog udoprog deleted the setters-getters-derive branch November 25, 2020 01:45
@udoprog udoprog added changelog Issue has been added to the changelog and removed changelog Issue has been added to the changelog labels Jan 19, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
changelog Issue has been added to the changelog enhancement New feature or request vm Issues related to the virtual machine.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant