Operators

The export macro recognizes the derives of standard Rust traits such as Clone, PartialEq, Debug, etc.

By exporting these trait implementations, you enable certain features that the script user can utilize with the type instances.

If the exported structure has a #[derive(...)] attribute, this attribute must follow the #[export] attribute.

#[export]
// These derives will be recognized by the export macro.
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct Vector {
    pub x: f64,
    pub y: f64,
}

Alternatively, you can export these traits manually by exporting the corresponding implementations.

#[export]
impl Display for Vector {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        f.write_fmt(format_args!("vec({}, {})", self.x, self.y))
    }
}

Supported Traits

In addition to standard derivable traits, the export system supports the majority of traits from the std::ops module and some other standard Rust traits.

Rust TraitScript Operators
Clone and/or CopyCopying: *foo
Debug and/or DisplayStringification: ["Foo is ", foo]
PartialEq and/or EqEquality: a == b and a != b
PartialOrd and/or OrdComparison: a >= b, a < b, etc.
HashUsed implicitly
DefaultUsed implicitly
Add / AddAssignAddition: a + b / a += b
Sub / SubAssignSubtraction: a - b / a -= b
Mul / MulAssignMultiplication: a * b / a *= b
Div / DivAssignDivision: a / b / a /= b
NotLogical negation: !a
NegNumeric negation: -a
BitAnd / BitAndAssignBitwise conjunction: a & b / a &= b
BitOr / BitOrAssignBitwise disjunction: a | b / a |= b
BitXor / BitXorAssignBitwise exclusive disjunction: a ^ b / a ^= b
Shl / ShlAssignBitwise left shift: a << b / a <<= b
Shr / ShrAssignBitwise right shift: a >> b / a >>= b
Rem / RemAssignRemainder of division: a % b / a %= b

Note that the assignment script operator (a = b) is implicitly implemented for exported Rust structures. For this reason, exporting just the Add trait implementation is enough to enable the a += b script operator.

// Implements + operator between two vectors.
#[export]
impl Add for Vector {
    type Output = Self;

    fn add(mut self, rhs: Self) -> Self::Output {
        self.x += rhs.x;
        self.y += rhs.y;

        self
    }
}
let v = vec(0.0, 1.0) + vec(1.0, 0.5);

// In this case, this is a syntax sugar for using `v + vec(-5.0, 0.0)`,
// where the result is then assigned to the left-hand side.
v += vec(-5.0, 0.0);

v == vec(-4.0, 1.5);