crystalruby 0.2.3 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +2 -0
- data/README.md +389 -193
- data/Rakefile +4 -3
- data/crystalruby.gemspec +2 -2
- data/exe/crystalruby +1 -0
- data/lib/crystalruby/adapter.rb +131 -65
- data/lib/crystalruby/arc_mutex.rb +47 -0
- data/lib/crystalruby/compilation.rb +32 -3
- data/lib/crystalruby/config.rb +41 -37
- data/lib/crystalruby/function.rb +211 -68
- data/lib/crystalruby/library.rb +153 -48
- data/lib/crystalruby/reactor.rb +40 -23
- data/lib/crystalruby/source_reader.rb +86 -0
- data/lib/crystalruby/template.rb +16 -5
- data/lib/crystalruby/templates/function.cr +11 -10
- data/lib/crystalruby/templates/index.cr +53 -66
- data/lib/crystalruby/templates/inline_chunk.cr +1 -1
- data/lib/crystalruby/templates/ruby_interface.cr +34 -0
- data/lib/crystalruby/templates/top_level_function.cr +62 -0
- data/lib/crystalruby/templates/top_level_ruby_interface.cr +33 -0
- data/lib/crystalruby/typebuilder.rb +11 -55
- data/lib/crystalruby/typemaps.rb +92 -67
- data/lib/crystalruby/types/concerns/allocator.rb +80 -0
- data/lib/crystalruby/types/fixed_width/named_tuple.cr +80 -0
- data/lib/crystalruby/types/fixed_width/named_tuple.rb +86 -0
- data/lib/crystalruby/types/fixed_width/proc.cr +45 -0
- data/lib/crystalruby/types/fixed_width/proc.rb +79 -0
- data/lib/crystalruby/types/fixed_width/tagged_union.cr +53 -0
- data/lib/crystalruby/types/fixed_width/tagged_union.rb +109 -0
- data/lib/crystalruby/types/fixed_width/tuple.cr +82 -0
- data/lib/crystalruby/types/fixed_width/tuple.rb +92 -0
- data/lib/crystalruby/types/fixed_width.cr +138 -0
- data/lib/crystalruby/types/fixed_width.rb +205 -0
- data/lib/crystalruby/types/primitive.cr +21 -0
- data/lib/crystalruby/types/primitive.rb +117 -0
- data/lib/crystalruby/types/primitive_types/bool.cr +34 -0
- data/lib/crystalruby/types/primitive_types/bool.rb +11 -0
- data/lib/crystalruby/types/primitive_types/nil.cr +35 -0
- data/lib/crystalruby/types/primitive_types/nil.rb +16 -0
- data/lib/crystalruby/types/primitive_types/numbers.cr +37 -0
- data/lib/crystalruby/types/primitive_types/numbers.rb +28 -0
- data/lib/crystalruby/types/primitive_types/symbol.cr +55 -0
- data/lib/crystalruby/types/primitive_types/symbol.rb +35 -0
- data/lib/crystalruby/types/primitive_types/time.cr +35 -0
- data/lib/crystalruby/types/primitive_types/time.rb +25 -0
- data/lib/crystalruby/types/type.cr +64 -0
- data/lib/crystalruby/types/type.rb +239 -30
- data/lib/crystalruby/types/variable_width/array.cr +74 -0
- data/lib/crystalruby/types/variable_width/array.rb +88 -0
- data/lib/crystalruby/types/variable_width/hash.cr +146 -0
- data/lib/crystalruby/types/variable_width/hash.rb +117 -0
- data/lib/crystalruby/types/variable_width/string.cr +36 -0
- data/lib/crystalruby/types/variable_width/string.rb +18 -0
- data/lib/crystalruby/types/variable_width.cr +23 -0
- data/lib/crystalruby/types/variable_width.rb +46 -0
- data/lib/crystalruby/types.rb +32 -13
- data/lib/crystalruby/version.rb +2 -2
- data/lib/crystalruby.rb +13 -6
- metadata +41 -19
- data/lib/crystalruby/types/array.rb +0 -15
- data/lib/crystalruby/types/bool.rb +0 -3
- data/lib/crystalruby/types/hash.rb +0 -17
- data/lib/crystalruby/types/named_tuple.rb +0 -28
- data/lib/crystalruby/types/nil.rb +0 -3
- data/lib/crystalruby/types/numbers.rb +0 -5
- data/lib/crystalruby/types/string.rb +0 -3
- data/lib/crystalruby/types/symbol.rb +0 -3
- data/lib/crystalruby/types/time.rb +0 -8
- data/lib/crystalruby/types/tuple.rb +0 -17
- data/lib/crystalruby/types/type_serializer/json.rb +0 -41
- data/lib/crystalruby/types/type_serializer.rb +0 -37
- data/lib/crystalruby/types/typedef.rb +0 -57
- data/lib/crystalruby/types/union_type.rb +0 -43
- data/lib/module.rb +0 -3
@@ -0,0 +1,117 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module CrystalRuby::Types
|
4
|
+
Hash = VariableWidth.build(error: "Hash type must have 2 type parameters. E.g. Hash(Float64, String)")
|
5
|
+
|
6
|
+
def self.Hash(key_type, value_type)
|
7
|
+
VariableWidth.build(:Hash, inner_types: [key_type, value_type], convert_if: [Root::Hash], superclass: Hash) do
|
8
|
+
include Enumerable
|
9
|
+
|
10
|
+
def_delegators :@class, :value_type, :key_type
|
11
|
+
|
12
|
+
# Implement the Enumerable interface
|
13
|
+
# Helps this object to act like a true Hash
|
14
|
+
def each
|
15
|
+
if block_given?
|
16
|
+
size.times { |i| yield key_for_index(i), value_for_index(i) }
|
17
|
+
else
|
18
|
+
to_enum(:each)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def keys
|
23
|
+
each.map { |k, _| k }
|
24
|
+
end
|
25
|
+
|
26
|
+
def values
|
27
|
+
each.map { |_, v| v }
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.key_type
|
31
|
+
inner_types.first
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.value_type
|
35
|
+
inner_types.last
|
36
|
+
end
|
37
|
+
|
38
|
+
# We only accept Hash-like values, from which all elements
|
39
|
+
# can successfully be cast to our inner types
|
40
|
+
def self.cast!(value)
|
41
|
+
unless (value.is_a?(Hash) || value.is_a?(Root::Hash)) && value.keys.all?(&key_type.method(:valid_cast?)) && value.values.all?(&value_type.method(:valid_cast?))
|
42
|
+
raise CrystalRuby::InvalidCastError, "Cannot cast #{value} to #{inspect}"
|
43
|
+
end
|
44
|
+
|
45
|
+
[[key_type, value.keys], [value_type, value.values]].map do |type, values|
|
46
|
+
if type.primitive?
|
47
|
+
values.map(&type.method(:to_ffi_repr))
|
48
|
+
else
|
49
|
+
values
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def self.copy_to!((keys, values), memory:)
|
55
|
+
data_pointer = malloc(values.size * (key_type.refsize + value_type.refsize))
|
56
|
+
|
57
|
+
memory[size_offset].write_uint32(values.size)
|
58
|
+
memory[data_offset].write_pointer(data_pointer)
|
59
|
+
|
60
|
+
[
|
61
|
+
[key_type, data_pointer, keys],
|
62
|
+
[value_type, data_pointer[values.length * key_type.refsize], values]
|
63
|
+
].each do |type, pointer, list|
|
64
|
+
if type.primitive?
|
65
|
+
pointer.send("put_array_of_#{type.ffi_type}", 0, list)
|
66
|
+
else
|
67
|
+
list.each_with_index do |val, i|
|
68
|
+
type.write_single(pointer[i * type.refsize], val)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def index_for_key(key)
|
75
|
+
size.times { |i| return i if key_for_index(i) == key }
|
76
|
+
nil
|
77
|
+
end
|
78
|
+
|
79
|
+
def key_for_index(index)
|
80
|
+
key_type.fetch_single(data_pointer[index * key_type.refsize])
|
81
|
+
end
|
82
|
+
|
83
|
+
def value_for_index(index)
|
84
|
+
value_type.fetch_single(data_pointer[key_type.refsize * size + index * value_type.refsize])
|
85
|
+
end
|
86
|
+
|
87
|
+
def self.each_child_address(pointer)
|
88
|
+
size = pointer[size_offset].read_int32
|
89
|
+
pointer = pointer[data_offset].read_pointer
|
90
|
+
size.times do |i|
|
91
|
+
yield key_type, pointer[i * key_type.refsize]
|
92
|
+
yield value_type, pointer[size * key_type.refsize + i * value_type.refsize]
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def [](key)
|
97
|
+
return nil unless index = index_for_key(key)
|
98
|
+
|
99
|
+
value_for_index(index)
|
100
|
+
end
|
101
|
+
|
102
|
+
def []=(key, value)
|
103
|
+
if index = index_for_key(key)
|
104
|
+
value_type.write_single(data_pointer[key_type.refsize * size + index * value_type.refsize], value)
|
105
|
+
else
|
106
|
+
method_missing(:[]=, key, value)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def value(native: false)
|
111
|
+
keys = key_type.fetch_multi(data_pointer, size, native: native)
|
112
|
+
values = value_type.fetch_multi(data_pointer[key_type.refsize * size], size, native: native)
|
113
|
+
keys.zip(values).to_h
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
class <%= base_crystal_class_name %> < CrystalRuby::Types::VariableWidth
|
2
|
+
|
3
|
+
def initialize(string : ::String)
|
4
|
+
@memory = malloc(data_offset + 8)
|
5
|
+
self.value = string
|
6
|
+
increment_ref_count!
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.copy_to!(value : ::String, memory : Pointer(::UInt8))
|
10
|
+
data_pointer = malloc(value.bytesize.to_u32).as(Pointer(::UInt8))
|
11
|
+
data_pointer.copy_from(value.to_unsafe, value.bytesize)
|
12
|
+
(memory+size_offset).as(Pointer(::UInt32)).value = value.bytesize.to_u32
|
13
|
+
(memory+data_offset).as(Pointer(::UInt64)).value = data_pointer.address
|
14
|
+
end
|
15
|
+
|
16
|
+
def value=(string : ::String)
|
17
|
+
if self.ref_count > 0
|
18
|
+
self.class.decr_inner_ref_counts!(memory)
|
19
|
+
end
|
20
|
+
self.class.copy_to!(string, self.memory)
|
21
|
+
end
|
22
|
+
|
23
|
+
def ==(other : <%= native_type_expr %>)
|
24
|
+
native == other
|
25
|
+
end
|
26
|
+
|
27
|
+
def value : ::String
|
28
|
+
char_ptr = (memory + data_offset).as(Pointer(Pointer(::UInt8)))
|
29
|
+
size = (memory + size_offset).as(Pointer(::UInt32))
|
30
|
+
::String.new(char_ptr[0], size[0])
|
31
|
+
end
|
32
|
+
|
33
|
+
def native : ::String
|
34
|
+
value
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module CrystalRuby::Types
|
2
|
+
String = VariableWidth.build(:String, convert_if: [String, Root::String]) do
|
3
|
+
def self.cast!(rbval)
|
4
|
+
rbval.to_s
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.copy_to!(rbval, memory:)
|
8
|
+
data_pointer = malloc(rbval.bytesize)
|
9
|
+
data_pointer.write_string(rbval)
|
10
|
+
memory[size_offset].write_uint32(rbval.size)
|
11
|
+
memory[data_offset].write_pointer(data_pointer)
|
12
|
+
end
|
13
|
+
|
14
|
+
def value(native: false)
|
15
|
+
data_pointer.read_string(size)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module CrystalRuby
|
2
|
+
module Types
|
3
|
+
class VariableWidth < FixedWidth
|
4
|
+
|
5
|
+
def self.size_offset
|
6
|
+
4
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.data_offset
|
10
|
+
8
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.memsize
|
14
|
+
8
|
15
|
+
end
|
16
|
+
|
17
|
+
def variable_width?
|
18
|
+
true
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
module CrystalRuby
|
2
|
+
module Types
|
3
|
+
# A variable with type operates much like a fixed width type, but
|
4
|
+
# it writes a size and a pointer to the type memory instead of the data itself.
|
5
|
+
# When we decrement our internal ref count we need to resolve the pointer.
|
6
|
+
# The layout is a tiny bit different (data begins at byte 8 to allow room for size uint32 at byte 4)
|
7
|
+
class VariableWidth < FixedWidth
|
8
|
+
def self.variable_width?
|
9
|
+
true
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.crystal_supertype
|
13
|
+
"CrystalRuby::Types::VariableWidth"
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.build(
|
17
|
+
typename = nil,
|
18
|
+
error: nil,
|
19
|
+
inner_types: nil,
|
20
|
+
inner_keys: nil,
|
21
|
+
ffi_type: :pointer,
|
22
|
+
size_offset: 4,
|
23
|
+
data_offset: 8,
|
24
|
+
memsize: FFI.type_size(ffi_type),
|
25
|
+
refsize: 8,
|
26
|
+
convert_if: [],
|
27
|
+
superclass: VariableWidth,
|
28
|
+
&block
|
29
|
+
)
|
30
|
+
inner_types&.each(&Type.method(:validate!))
|
31
|
+
|
32
|
+
Class.new(superclass) do
|
33
|
+
bind_local_vars!(
|
34
|
+
%i[typename error inner_types inner_keys ffi_type memsize convert_if data_offset size_offset
|
35
|
+
refsize], binding
|
36
|
+
)
|
37
|
+
class_eval(&block) if block_given?
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
require_relative "variable_width/string"
|
45
|
+
require_relative "variable_width/array"
|
46
|
+
require_relative "variable_width/hash"
|
data/lib/crystalruby/types.rb
CHANGED
@@ -1,18 +1,37 @@
|
|
1
|
-
require_relative "types/type"
|
2
|
-
require_relative "types/union_type"
|
3
|
-
require_relative "types/typedef"
|
4
|
-
require_relative "types/string"
|
5
|
-
require_relative "types/time"
|
6
|
-
require_relative "types/symbol"
|
7
|
-
require_relative "types/array"
|
8
|
-
require_relative "types/hash"
|
9
|
-
require_relative "types/nil"
|
10
|
-
require_relative "types/bool"
|
11
|
-
require_relative "types/named_tuple"
|
12
|
-
require_relative "types/tuple"
|
13
|
-
require_relative "types/numbers"
|
14
1
|
|
15
2
|
module CrystalRuby
|
16
3
|
module Types
|
4
|
+
# Store references to root types so that we can reference these in places where
|
5
|
+
# we load the CrystalRuby equivalents into the global namespace
|
6
|
+
module Root
|
7
|
+
Symbol = ::Symbol
|
8
|
+
String = ::String
|
9
|
+
Array = ::Array
|
10
|
+
Hash = ::Hash
|
11
|
+
Time = ::Time
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.const_missing(const_name)
|
15
|
+
return @fallback.const_get(const_name) if @fallback&.const_defined?(const_name)
|
16
|
+
super
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.method_missing(method_name, *args)
|
20
|
+
return @fallback.send(method_name, *args) if @fallback&.method_defined?(method_name)
|
21
|
+
super
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.with_binding_fallback(fallback)
|
25
|
+
@fallback, previous_fallback = fallback, @fallback
|
26
|
+
@fallback = @fallback.class unless @fallback.kind_of?(Module)
|
27
|
+
yield binding
|
28
|
+
ensure
|
29
|
+
@fallback = previous_fallback
|
30
|
+
end
|
17
31
|
end
|
18
32
|
end
|
33
|
+
require_relative "types/concerns/allocator"
|
34
|
+
require_relative "types/type"
|
35
|
+
require_relative "types/primitive"
|
36
|
+
require_relative "types/fixed_width"
|
37
|
+
require_relative "types/variable_width"
|
data/lib/crystalruby/version.rb
CHANGED
data/lib/crystalruby.rb
CHANGED
@@ -3,11 +3,12 @@
|
|
3
3
|
require "ffi"
|
4
4
|
require "digest"
|
5
5
|
require "fileutils"
|
6
|
-
require "
|
6
|
+
require "syntax_tree"
|
7
7
|
require "pathname"
|
8
8
|
|
9
9
|
require_relative "crystalruby/config"
|
10
10
|
require_relative "crystalruby/version"
|
11
|
+
require_relative "crystalruby/arc_mutex"
|
11
12
|
require_relative "crystalruby/typemaps"
|
12
13
|
require_relative "crystalruby/types"
|
13
14
|
require_relative "crystalruby/typebuilder"
|
@@ -17,7 +18,7 @@ require_relative "crystalruby/adapter"
|
|
17
18
|
require_relative "crystalruby/reactor"
|
18
19
|
require_relative "crystalruby/library"
|
19
20
|
require_relative "crystalruby/function"
|
20
|
-
require_relative "
|
21
|
+
require_relative "crystalruby/source_reader"
|
21
22
|
|
22
23
|
module CrystalRuby
|
23
24
|
module_function
|
@@ -37,19 +38,25 @@ module CrystalRuby
|
|
37
38
|
def check_crystal_ruby!
|
38
39
|
return if system("which crystal > /dev/null 2>&1")
|
39
40
|
|
40
|
-
|
41
|
-
"See https://crystal-lang.org/install
|
41
|
+
msg = "Crystal executable not found. Please ensure Crystal is installed and in your PATH. " \
|
42
|
+
"See https://crystal-lang.org/install/."
|
43
|
+
|
44
|
+
if config.crystal_missing_ignore
|
45
|
+
config.logger.error msg
|
46
|
+
else
|
47
|
+
raise msg
|
48
|
+
end
|
42
49
|
end
|
43
50
|
|
44
51
|
def check_config!
|
45
52
|
return if config.crystal_src_dir
|
46
53
|
|
47
|
-
raise "Missing config option `crystal_src_dir`. \nProvide this inside crystalruby.yaml "\
|
54
|
+
raise "Missing config option `crystal_src_dir`. \nProvide this inside crystalruby.yaml " \
|
48
55
|
"(run `bundle exec crystalruby init` to generate this file with detaults)"
|
49
56
|
end
|
50
57
|
|
51
58
|
%w[debug info warn error].each do |level|
|
52
|
-
define_method("log_#{level}") do |*msg|
|
59
|
+
define_method(:"log_#{level}") do |*msg|
|
53
60
|
prefix = config.colorize_log_output ? "\e[33mcrystalruby\e[0m\e[90m [#{Thread.current.object_id}]\e[0m" : "[crystalruby] #{Thread.current.object_id}"
|
54
61
|
|
55
62
|
config.logger.send(level, "#{prefix} #{msg.join(", ")}")
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: crystalruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Wouter Coppieters
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-11-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: digest
|
@@ -53,7 +53,7 @@ dependencies:
|
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name:
|
56
|
+
name: syntax_tree
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
59
|
- - ">="
|
@@ -87,35 +87,57 @@ files:
|
|
87
87
|
- exe/crystalruby
|
88
88
|
- lib/crystalruby.rb
|
89
89
|
- lib/crystalruby/adapter.rb
|
90
|
+
- lib/crystalruby/arc_mutex.rb
|
90
91
|
- lib/crystalruby/compilation.rb
|
91
92
|
- lib/crystalruby/config.rb
|
92
93
|
- lib/crystalruby/function.rb
|
93
94
|
- lib/crystalruby/library.rb
|
94
95
|
- lib/crystalruby/reactor.rb
|
96
|
+
- lib/crystalruby/source_reader.rb
|
95
97
|
- lib/crystalruby/template.rb
|
96
98
|
- lib/crystalruby/templates/function.cr
|
97
99
|
- lib/crystalruby/templates/index.cr
|
98
100
|
- lib/crystalruby/templates/inline_chunk.cr
|
101
|
+
- lib/crystalruby/templates/ruby_interface.cr
|
102
|
+
- lib/crystalruby/templates/top_level_function.cr
|
103
|
+
- lib/crystalruby/templates/top_level_ruby_interface.cr
|
99
104
|
- lib/crystalruby/typebuilder.rb
|
100
105
|
- lib/crystalruby/typemaps.rb
|
101
106
|
- lib/crystalruby/types.rb
|
102
|
-
- lib/crystalruby/types/
|
103
|
-
- lib/crystalruby/types/
|
104
|
-
- lib/crystalruby/types/
|
105
|
-
- lib/crystalruby/types/named_tuple.
|
106
|
-
- lib/crystalruby/types/
|
107
|
-
- lib/crystalruby/types/
|
108
|
-
- lib/crystalruby/types/
|
109
|
-
- lib/crystalruby/types/
|
110
|
-
- lib/crystalruby/types/
|
111
|
-
- lib/crystalruby/types/tuple.
|
107
|
+
- lib/crystalruby/types/concerns/allocator.rb
|
108
|
+
- lib/crystalruby/types/fixed_width.cr
|
109
|
+
- lib/crystalruby/types/fixed_width.rb
|
110
|
+
- lib/crystalruby/types/fixed_width/named_tuple.cr
|
111
|
+
- lib/crystalruby/types/fixed_width/named_tuple.rb
|
112
|
+
- lib/crystalruby/types/fixed_width/proc.cr
|
113
|
+
- lib/crystalruby/types/fixed_width/proc.rb
|
114
|
+
- lib/crystalruby/types/fixed_width/tagged_union.cr
|
115
|
+
- lib/crystalruby/types/fixed_width/tagged_union.rb
|
116
|
+
- lib/crystalruby/types/fixed_width/tuple.cr
|
117
|
+
- lib/crystalruby/types/fixed_width/tuple.rb
|
118
|
+
- lib/crystalruby/types/primitive.cr
|
119
|
+
- lib/crystalruby/types/primitive.rb
|
120
|
+
- lib/crystalruby/types/primitive_types/bool.cr
|
121
|
+
- lib/crystalruby/types/primitive_types/bool.rb
|
122
|
+
- lib/crystalruby/types/primitive_types/nil.cr
|
123
|
+
- lib/crystalruby/types/primitive_types/nil.rb
|
124
|
+
- lib/crystalruby/types/primitive_types/numbers.cr
|
125
|
+
- lib/crystalruby/types/primitive_types/numbers.rb
|
126
|
+
- lib/crystalruby/types/primitive_types/symbol.cr
|
127
|
+
- lib/crystalruby/types/primitive_types/symbol.rb
|
128
|
+
- lib/crystalruby/types/primitive_types/time.cr
|
129
|
+
- lib/crystalruby/types/primitive_types/time.rb
|
130
|
+
- lib/crystalruby/types/type.cr
|
112
131
|
- lib/crystalruby/types/type.rb
|
113
|
-
- lib/crystalruby/types/
|
114
|
-
- lib/crystalruby/types/
|
115
|
-
- lib/crystalruby/types/
|
116
|
-
- lib/crystalruby/types/
|
132
|
+
- lib/crystalruby/types/variable_width.cr
|
133
|
+
- lib/crystalruby/types/variable_width.rb
|
134
|
+
- lib/crystalruby/types/variable_width/array.cr
|
135
|
+
- lib/crystalruby/types/variable_width/array.rb
|
136
|
+
- lib/crystalruby/types/variable_width/hash.cr
|
137
|
+
- lib/crystalruby/types/variable_width/hash.rb
|
138
|
+
- lib/crystalruby/types/variable_width/string.cr
|
139
|
+
- lib/crystalruby/types/variable_width/string.rb
|
117
140
|
- lib/crystalruby/version.rb
|
118
|
-
- lib/module.rb
|
119
141
|
- logo.png
|
120
142
|
- sig/crystalruby.rbs
|
121
143
|
homepage: https://github.com/wouterken/crystalruby
|
@@ -140,7 +162,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
140
162
|
- !ruby/object:Gem::Version
|
141
163
|
version: '0'
|
142
164
|
requirements: []
|
143
|
-
rubygems_version: 3.
|
165
|
+
rubygems_version: 3.5.3
|
144
166
|
signing_key:
|
145
167
|
specification_version: 4
|
146
168
|
summary: Embed Crystal code directly in Ruby.
|
@@ -1,15 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module CrystalRuby::Types
|
4
|
-
Array = Type.new(
|
5
|
-
:Array,
|
6
|
-
error: "Array type must have a type parameter. E.g. Array(Float64)"
|
7
|
-
)
|
8
|
-
|
9
|
-
def self.Array(type)
|
10
|
-
Type.validate!(type)
|
11
|
-
Type.new("Array", inner_types: [type], accept_if: [::Array]) do |a|
|
12
|
-
a.map! { |v| type.interpret!(v) }
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module CrystalRuby::Types
|
4
|
-
Hash = Type.new(
|
5
|
-
:Hash,
|
6
|
-
error: "Hash type must have 2 type parameters. E.g. Hash(Float64, String)"
|
7
|
-
)
|
8
|
-
|
9
|
-
def self.Hash(key_type, value_type)
|
10
|
-
Type.validate!(key_type)
|
11
|
-
Type.validate!(value_type)
|
12
|
-
Type.new("Hash", inner_types: [key_type, value_type], accept_if: [::Hash]) do |h|
|
13
|
-
h.transform_keys! { |k| key_type.interpret!(k) }
|
14
|
-
h.transform_values! { |v| value_type.interpret!(v) }
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
@@ -1,28 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module CrystalRuby::Types
|
4
|
-
NamedTuple = Type.new(
|
5
|
-
:NamedTuple,
|
6
|
-
error: "NamedTuple type must contain one or more symbol -> type pairs. E.g. NamedTuple(hello: Int32, world: String)"
|
7
|
-
)
|
8
|
-
|
9
|
-
def self.NamedTuple(types_hash)
|
10
|
-
types_hash.keys.each do |key|
|
11
|
-
raise "NamedTuple keys must be symbols" unless key.is_a?(::Symbol) || key.respond_to?(:to_sym)
|
12
|
-
end
|
13
|
-
types_hash.values.each do |value_type|
|
14
|
-
Type.validate!(value_type)
|
15
|
-
end
|
16
|
-
keys = types_hash.keys.map(&:to_sym)
|
17
|
-
values = types_hash.values
|
18
|
-
Type.new("NamedTuple", inner_types: values, inner_keys: keys, accept_if: [::Hash]) do |h|
|
19
|
-
h.transform_keys! { |k| k.to_sym }
|
20
|
-
raise "Invalid keys for named tuple" unless h.keys.length == keys.length
|
21
|
-
raise "Invalid keys for named tuple" unless h.keys.all? { |k| keys.include?(k) }
|
22
|
-
|
23
|
-
h.each do |key, value|
|
24
|
-
h[key] = values[keys.index(key)].interpret!(value)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
@@ -1,17 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module CrystalRuby::Types
|
4
|
-
Tuple = Type.new(
|
5
|
-
:Tuple,
|
6
|
-
error: "Tuple type must contain one or more types E.g. Tuple(Int32, String)"
|
7
|
-
)
|
8
|
-
|
9
|
-
def self.Tuple(*types)
|
10
|
-
types.each do |value_type|
|
11
|
-
Type.validate!(value_type)
|
12
|
-
end
|
13
|
-
Type.new("Tuple", inner_types: types, accept_if: [::Array]) do |a|
|
14
|
-
a.map!.with_index { |v, i| inner_types[i].interpret!(v) }
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
@@ -1,41 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require "json"
|
4
|
-
|
5
|
-
module CrystalRuby::Types
|
6
|
-
class TypeSerializer
|
7
|
-
class JSON < TypeSerializer
|
8
|
-
def lib_type
|
9
|
-
"UInt8*"
|
10
|
-
end
|
11
|
-
|
12
|
-
def crystal_type
|
13
|
-
type_expr
|
14
|
-
end
|
15
|
-
|
16
|
-
def error_value
|
17
|
-
'"{}".to_unsafe'
|
18
|
-
end
|
19
|
-
|
20
|
-
def ffi_type
|
21
|
-
:string
|
22
|
-
end
|
23
|
-
|
24
|
-
def prepare_argument(arg)
|
25
|
-
arg.to_json
|
26
|
-
end
|
27
|
-
|
28
|
-
def prepare_retval(retval)
|
29
|
-
@typedef.interpret!(::JSON.parse(retval))
|
30
|
-
end
|
31
|
-
|
32
|
-
def lib_to_crystal_type_expr(expr)
|
33
|
-
"(#{type_expr}).from_json(String.new(%s))" % expr
|
34
|
-
end
|
35
|
-
|
36
|
-
def crystal_to_lib_type_expr(expr)
|
37
|
-
"%s.to_json.to_unsafe" % expr
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
41
|
-
end
|
@@ -1,37 +0,0 @@
|
|
1
|
-
module CrystalRuby::Types
|
2
|
-
class TypeSerializer
|
3
|
-
include FFI::DataConverter
|
4
|
-
def self.for(format)
|
5
|
-
case format
|
6
|
-
when :json then JSON
|
7
|
-
else raise "Unknown type format: #{format}"
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
def error_value
|
12
|
-
0
|
13
|
-
end
|
14
|
-
|
15
|
-
def initialize(typedef)
|
16
|
-
@typedef = typedef
|
17
|
-
end
|
18
|
-
|
19
|
-
def type_expr
|
20
|
-
@typedef.type_expr
|
21
|
-
end
|
22
|
-
|
23
|
-
def type_defn
|
24
|
-
@typedef.type_defn
|
25
|
-
end
|
26
|
-
|
27
|
-
def anonymous?
|
28
|
-
@typedef.anonymous?
|
29
|
-
end
|
30
|
-
|
31
|
-
def name
|
32
|
-
@typedef.name
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
require_relative "type_serializer/json"
|