Oters - Exporting Rust Code
While Oters is already a pretty powerful language, it is missing all the libraries and community content that a mature language has. To remedy this, Oters provides a mechanism to export certain Rust code so that you can use it from your Oters programs.
Exportable Types
All Rust code exported into Oters must be translated to be compatible with Oters’ type system. This means that we are a bit restricted with the types that we can include in our exported code. The following is a series of mappings of Rust types to Oters types:
Rust Type | Oters Type |
---|---|
i64 | int |
f64 | float |
bool | bool |
String | string |
Vec<T> | [T] |
(T1, ..., Tn) | (T1, ... , Tn) |
Aside from these, exported functions without arguments or a return type take a unit type as input or return unit respectively.
Attempting to export a type not in the list above will result in a compilation error.
Exporting Structs and Enums
Aside from the aforementioned types, you can also export composite types so that you can use them from both Rust and Oters. Note however, tath the structs and enums that you do export must have fields with exportable types. To export a struct or enum you simply add the macro [oters::export_oters]
above its definition.
use oters::export_oters;
#[export_oters]
pub struct Color {
pub r: i64,
pub g: i64,
pub b: i64,
pub a: i64,
}
#[export_oters]
pub enum Shape {
Circle((i64, i64), i64, Color),
Rect((i64, i64), (i64, i64), Color),
Line((i64, i64), (i64, i64), i64, Color),
Triangle((i64, i64), (i64, i64), (i64, i64), Color),
}
Exporting Functions
Exporting a Rust function to Oters is done in the same way as for structs or enums. You just attach the macro [oters::export_oters]
above the function definition.
#[export_oters]
fn shape_area(s: Shape) -> f64 {
match s {
Shape::Circle(_, r, _) => r as f64 * r as f64 * 3.14159265358979,
Shape::Rect(_, dims, _) => (dims.0 * dims.1) as f64,
Shape::Line(..) => 0.0,
Shape::Triangle(a, b, c, _) => (a.0 * (b.1 - c.1) +
b.0 * (c.1 - a.1) +
c.0 * (a.1 - b.1)
) as f64 / 2.0,
}
}
#[export_oters]
fn int_sum(i1: i64, i2: i64) -> i64 {
i1 + i2
}
Functions with multiple arguments will get imported into Oters as taking a tuple of said arguments as input. So the rather contrived function int_sum
will have type (int, int) -> int
in Oters.
Also, unfortunately you can’t pass imported functions as first-order values yet. So, int_sum
above could not be used as an argument to a function in Oters. This can be worked around fairly easily by simply wrapping it in another function like so:
fn i1 i2 -> int_sum (i1, i2)
Importing into Oters
All your exported functions, structs and enums are automatically imported into Oters. It is important to note that they are specifically imported into the first file in the Vec
passed as input to the run!
macro. To use them in your other files you will need to add use
statements. So for example, if I have two Oters files data.rs
and main.rs
in that order, using the exports above in main.rs
may look like the following:
use data::Color
use data::Shape
use data::shape_area
let my_circ = Shape::Circ((100, 100), 20, Color { r: 255, g: 0, b: 0, a: 255 })
let circ_area = shape_area my_circ