mirror of https://github.com/tildeio/helix
commit
32d6a67b11
|
@ -3,7 +3,7 @@ cache:
|
|||
- '%HOMEDRIVE%%HOMEPATH%\.multirust -> .appveyor.yml'
|
||||
|
||||
environment:
|
||||
EXAMPLES: duration calculator console membership text_transform turbo_blank json_builder
|
||||
EXAMPLES: duration calculator console geometry membership text_transform turbo_blank json_builder
|
||||
VERBOSE: true
|
||||
RUST_BACKTRACE: 1
|
||||
matrix:
|
||||
|
|
|
@ -21,7 +21,7 @@ cache:
|
|||
|
||||
env:
|
||||
global:
|
||||
- EXAMPLES="duration calculator console membership text_transform turbo_blank json_builder"
|
||||
- EXAMPLES="duration calculator console geometry membership text_transform turbo_blank json_builder"
|
||||
- VERBOSE=true
|
||||
- RUST_BACKTRACE=1
|
||||
- RUST_VERSION=stable
|
||||
|
|
|
@ -21,7 +21,7 @@ appveyor = { repository = "tildeio/helix", branch = "master", service = "github"
|
|||
|
||||
[workspace]
|
||||
|
||||
members = ["examples/calculator", "examples/console", "examples/duration", "examples/membership", "examples/text_transform", "examples/turbo_blank", "examples/json_builder"]
|
||||
members = ["examples/calculator", "examples/console", "examples/geometry", "examples/duration", "examples/membership", "examples/text_transform", "examples/turbo_blank", "examples/json_builder"]
|
||||
|
||||
[dependencies]
|
||||
libc = "0.2.0"
|
||||
|
|
4
Rakefile
4
Rakefile
|
@ -4,7 +4,7 @@ task :test do
|
|||
sh "bundle exec rake"
|
||||
end
|
||||
|
||||
examples = ENV["EXAMPLES"] || "duration calculator console membership text_transform turbo_blank json_builder"
|
||||
examples = ENV["EXAMPLES"] || "duration calculator console geometry membership text_transform turbo_blank json_builder"
|
||||
|
||||
sh "bash ./examples/runner default #{examples}"
|
||||
end
|
||||
|
@ -15,7 +15,7 @@ task :install do
|
|||
sh "bundle"
|
||||
end
|
||||
|
||||
examples = ENV["EXAMPLES"] || "duration calculator console membership text_transform turbo_blank json_builder"
|
||||
examples = ENV["EXAMPLES"] || "duration calculator console geometry membership text_transform turbo_blank json_builder"
|
||||
|
||||
sh "bash ./examples/runner install #{examples}"
|
||||
end
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
target
|
||||
*.bundle
|
||||
*.gem
|
|
@ -0,0 +1,11 @@
|
|||
[package]
|
||||
name = "geometry"
|
||||
version = "0.1.0"
|
||||
authors = ["Godfrey Chan <godfrey@tilde.io>"]
|
||||
|
||||
[lib]
|
||||
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies.helix]
|
||||
path = "../.."
|
|
@ -0,0 +1,5 @@
|
|||
source 'https://rubygems.org'
|
||||
|
||||
gem 'helix_runtime', path: '../../ruby'
|
||||
gem 'rake', '~> 10.0'
|
||||
gem 'rspec', '~> 3.4'
|
|
@ -0,0 +1,20 @@
|
|||
require 'bundler/setup'
|
||||
require 'helix_runtime/build_task'
|
||||
require 'rspec/core/rake_task'
|
||||
require_relative '../shared.rb'
|
||||
|
||||
# For Windows
|
||||
$stdout.sync = true
|
||||
|
||||
HelixRuntime::BuildTask.new do |t|
|
||||
t.build_root = File.expand_path("../..", __dir__)
|
||||
t.helix_lib_dir = File.expand_path("../../ruby/windows_build", __dir__)
|
||||
t.pre_build = HelixRuntime::Tests.pre_build
|
||||
end
|
||||
|
||||
RSpec::Core::RakeTask.new(:spec) do |t|
|
||||
t.verbose = false
|
||||
end
|
||||
|
||||
task :spec => :build
|
||||
task :default => :spec
|
|
@ -0,0 +1,2 @@
|
|||
require 'helix_runtime'
|
||||
require 'geometry/native'
|
|
@ -0,0 +1,35 @@
|
|||
require "spec_helper"
|
||||
|
||||
describe Point do
|
||||
let(:origin) { Point.new(0,0) }
|
||||
|
||||
let(:north) { Point.new(0,1) }
|
||||
let(:east) { Point.new(1,0) }
|
||||
let(:south) { Point.new(0,-1) }
|
||||
let(:west) { Point.new(-1,0) }
|
||||
|
||||
it "has the right coordinates" do
|
||||
expect(origin.x).to eq(0)
|
||||
expect(origin.y).to eq(0)
|
||||
|
||||
expect(north.x).to eq(0)
|
||||
expect(north.y).to eq(1)
|
||||
|
||||
expect(east.x).to eq(1)
|
||||
expect(east.y).to eq(0)
|
||||
|
||||
expect(south.x).to eq(0)
|
||||
expect(south.y).to eq(-1)
|
||||
|
||||
expect(west.x).to eq(-1)
|
||||
expect(west.y).to eq(0)
|
||||
end
|
||||
|
||||
it "can be turned into an array" do
|
||||
expect(origin.to_a).to eq([0,0])
|
||||
expect(north.to_a).to eq([0,1])
|
||||
expect(east.to_a).to eq([1,0])
|
||||
expect(south.to_a).to eq([0,-1])
|
||||
expect(west.to_a).to eq([-1,0])
|
||||
end
|
||||
end
|
|
@ -0,0 +1,2 @@
|
|||
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
|
||||
require 'geometry'
|
|
@ -0,0 +1,29 @@
|
|||
#![recursion_limit="1024"]
|
||||
|
||||
#[macro_use]
|
||||
extern crate helix;
|
||||
|
||||
ruby! {
|
||||
class Point {
|
||||
struct {
|
||||
x: f64,
|
||||
y: f64
|
||||
}
|
||||
|
||||
def initialize(helix, x: f64, y: f64) {
|
||||
Point { helix, x, y }
|
||||
}
|
||||
|
||||
def x(&self) -> f64 {
|
||||
self.x
|
||||
}
|
||||
|
||||
def y(&self) -> f64 {
|
||||
self.y
|
||||
}
|
||||
|
||||
def to_a(&self) -> (f64, f64) {
|
||||
(self.x, self.y)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@ mod integers;
|
|||
mod float;
|
||||
mod symbol;
|
||||
mod string;
|
||||
mod tuples;
|
||||
mod option;
|
||||
mod result;
|
||||
mod slice;
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
use sys::{self, VALUE};
|
||||
|
||||
use super::{CheckResult, FromRuby, ToRuby, ToRubyResult};
|
||||
use super::super::{inspect};
|
||||
|
||||
#[doc(hidden)]
|
||||
macro_rules! impl_tuple_coercions {
|
||||
($($name:ident),*) => {
|
||||
impl_tuple_from_ruby!(count_items!($($name),*), $($name),*);
|
||||
impl_tuple_to_ruby!(count_items!($($name),*), $($name),*);
|
||||
};
|
||||
|
||||
($($any:tt)*) => {
|
||||
compile_error!(stringify!("impl_tuple_coercions" $($any)*));
|
||||
};
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
macro_rules! impl_tuple_from_ruby {
|
||||
($count:expr, $($name:ident),*) => {
|
||||
impl<$($name: FromRuby,)*> FromRuby for ($($name,)*) {
|
||||
type Checked = ($($name::Checked,)*);
|
||||
|
||||
fn from_ruby(value: VALUE) -> CheckResult<Self::Checked> {
|
||||
if unsafe { sys::RB_TYPE_P(value, sys::T_ARRAY) } {
|
||||
// Make sure we can actually do the conversions for the values.
|
||||
let len = unsafe { sys::RARRAY_LEN(value) };
|
||||
|
||||
if len != $count {
|
||||
type_error!(value, format!("an array with {} {}", $count, { if $count == 1 { "element" } else { "elements" } }))
|
||||
}
|
||||
|
||||
extract_tuple_elements_from_ruby!(value, (0), $($name),*);
|
||||
|
||||
Ok(($($name,)*))
|
||||
} else {
|
||||
type_error!(value, "an array")
|
||||
}
|
||||
}
|
||||
|
||||
fn from_checked(checked: Self::Checked) -> Self {
|
||||
#[allow(non_snake_case)]
|
||||
let ($($name,)*) = checked;
|
||||
($($name::from_checked($name),)*)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
($($any:tt)*) => {
|
||||
compile_error!(stringify!("impl_tuple_from_ruby" $($any)*));
|
||||
};
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
macro_rules! extract_tuple_elements_from_ruby {
|
||||
($value:ident, $offset:tt) => {};
|
||||
($value:ident, $offset:tt, $name:ident $($rest:tt)*) => {
|
||||
#[allow(non_snake_case)]
|
||||
let $name = {
|
||||
let val = unsafe { sys::rb_ary_entry($value, $offset as isize) };
|
||||
match $name::from_ruby(val) {
|
||||
Ok(v) => v,
|
||||
Err(e) => type_error!(format!("Failed to convert {}, element {} has the wrong type: {}", inspect($value), $offset, e)),
|
||||
}
|
||||
};
|
||||
|
||||
extract_tuple_elements_from_ruby!($value, ($offset + 1) $($rest)*);
|
||||
};
|
||||
|
||||
($($any:tt)*) => {
|
||||
compile_error!(stringify!("extract_tuple_elements_from_ruby" $($any)*));
|
||||
};
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
macro_rules! impl_tuple_to_ruby {
|
||||
($count:expr, $($name:ident),*) => {
|
||||
impl<$($name: ToRuby,)*> ToRuby for ($($name,)*) {
|
||||
fn to_ruby(self) -> ToRubyResult {
|
||||
let ary = unsafe { sys::rb_ary_new_capa($count as isize) };
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
let ($($name,)*) = self;
|
||||
|
||||
|
||||
$(
|
||||
unsafe { sys::rb_ary_push(ary, $name.to_ruby()?); }
|
||||
)*;
|
||||
|
||||
Ok(ary)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
($($any:tt)*) => {
|
||||
compile_error!(stringify!("impl_tuple_to_ruby" $($any)*));
|
||||
};
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
macro_rules! count_items {
|
||||
() => { 0 };
|
||||
($item:tt $(, $rest:tt)*) => { 1 + count_items!($($rest),*) };
|
||||
|
||||
($($any:tt)*) => {
|
||||
compile_error!(stringify!("count_items" $($any)*));
|
||||
};
|
||||
}
|
||||
|
||||
impl_tuple_coercions!(A);
|
||||
impl_tuple_coercions!(A, B);
|
||||
impl_tuple_coercions!(A, B, C);
|
||||
impl_tuple_coercions!(A, B, C, D);
|
||||
impl_tuple_coercions!(A, B, C, D, E);
|
||||
impl_tuple_coercions!(A, B, C, D, E, F);
|
||||
impl_tuple_coercions!(A, B, C, D, E, F, G);
|
||||
impl_tuple_coercions!(A, B, C, D, E, F, G, H);
|
||||
impl_tuple_coercions!(A, B, C, D, E, F, G, H, I);
|
||||
impl_tuple_coercions!(A, B, C, D, E, F, G, H, I, J);
|
||||
impl_tuple_coercions!(A, B, C, D, E, F, G, H, I, J, K);
|
||||
impl_tuple_coercions!(A, B, C, D, E, F, G, H, I, J, K, L);
|
|
@ -303,6 +303,8 @@ macro_rules! parse {
|
|||
ast: [ $($ast:tt)* ]
|
||||
}
|
||||
} => {
|
||||
assert_has_initialize!($class, "Classes defining a struct must implement `initialize`");
|
||||
|
||||
parse! {
|
||||
state: top_level,
|
||||
buffer: $program,
|
||||
|
@ -863,6 +865,29 @@ macro_rules! assert_not_reopen {
|
|||
{ { reopen: false }, $($message:expr),* } => {};
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[macro_export]
|
||||
macro_rules! assert_has_initialize {
|
||||
{
|
||||
{
|
||||
type: class,
|
||||
rust_name: $rust_name:tt,
|
||||
ruby_name: $ruby_name:tt,
|
||||
meta: $meta:tt,
|
||||
struct: $struct:tt,
|
||||
methods: $methods:tt
|
||||
},
|
||||
$($message:expr),*
|
||||
} => { assert_has_initialize!({ struct: $struct }, $methods, $($message),*); };
|
||||
|
||||
{ { struct: () }, $methods:tt, $($message:expr),* } => {};
|
||||
{ { struct: $struct:tt }, [ ], $($message:expr),* } => { parse_error!($($message),*); };
|
||||
{ { struct: $struct:tt }, [ { type: initializer, $($rest:tt)* } $($methods:tt)* ], $($message:expr),* } => {};
|
||||
{ { struct: $struct:tt }, [ $method:tt $($methods:tt)* ], $($message:expr),* } => {
|
||||
assert_has_initialize!({ struct: $struct }, [ $($methods)* ], $($message),*);
|
||||
};
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
#[macro_export]
|
||||
macro_rules! assert_has_struct {
|
||||
|
|
Loading…
Reference in New Issue