-
Notifications
You must be signed in to change notification settings - Fork 28
/
typed_data_obj.rs
73 lines (61 loc) · 1.57 KB
/
typed_data_obj.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
use magnus::{
define_class, embed::init, eval, function, gc, method, prelude::*, typed_data::Obj,
DataTypeFunctions, TypedData,
};
#[magnus::wrap(class = "Point", free_immediatly)]
struct Point {
x: isize,
y: isize,
}
impl Point {
fn new(x: isize, y: isize) -> Self {
Self { x, y }
}
}
#[derive(TypedData)]
#[magnus(class = "Line", free_immediatly, mark)]
struct Line {
start: Obj<Point>,
end: Obj<Point>,
}
impl Line {
fn new(start: Obj<Point>, end: Obj<Point>) -> Self {
Self { start, end }
}
fn length(&self) -> f64 {
let start = self.start.get();
let end = self.end.get();
(((end.x - start.x).pow(2) + (end.y - start.y).pow(2)) as f64).sqrt()
}
}
impl DataTypeFunctions for Line {
fn mark(&self) {
gc::mark(self.start);
gc::mark(self.end);
}
}
#[test]
fn it_can_nest_wrapped_structs() {
let _cleanup = unsafe { init() };
let class = define_class("Point", Default::default()).unwrap();
class
.define_singleton_method("new", function!(Point::new, 2))
.unwrap();
let class = define_class("Line", Default::default()).unwrap();
class
.define_singleton_method("new", function!(Line::new, 2))
.unwrap();
class
.define_method("length", method!(Line::length, 0))
.unwrap();
let result: f64 = eval(
r#"
start = Point.new(0, 0)
finish = Point.new(10, 10)
line = Line.new(start, finish)
line.length
"#,
)
.unwrap();
assert!(result - 14.14213 < 0.00001);
}