erlang-etf 1.0.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.
Files changed (107) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +4 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +49 -0
  8. data/Rakefile +6 -0
  9. data/erlang-etf.gemspec +30 -0
  10. data/lib/erlang/etf.rb +40 -0
  11. data/lib/erlang/etf/atom.rb +46 -0
  12. data/lib/erlang/etf/atom_utf8.rb +44 -0
  13. data/lib/erlang/etf/bert.rb +74 -0
  14. data/lib/erlang/etf/binary.rb +44 -0
  15. data/lib/erlang/etf/bit_binary.rb +47 -0
  16. data/lib/erlang/etf/export.rb +44 -0
  17. data/lib/erlang/etf/extensions.rb +157 -0
  18. data/lib/erlang/etf/extensions/array.rb +29 -0
  19. data/lib/erlang/etf/extensions/big_decimal.rb +22 -0
  20. data/lib/erlang/etf/extensions/erlang-export.rb +26 -0
  21. data/lib/erlang/etf/extensions/erlang-list.rb +31 -0
  22. data/lib/erlang/etf/extensions/erlang-nil.rb +22 -0
  23. data/lib/erlang/etf/extensions/erlang-pid.rb +22 -0
  24. data/lib/erlang/etf/extensions/erlang-string.rb +22 -0
  25. data/lib/erlang/etf/extensions/erlang-tuple.rb +31 -0
  26. data/lib/erlang/etf/extensions/false_class.rb +28 -0
  27. data/lib/erlang/etf/extensions/float.rb +20 -0
  28. data/lib/erlang/etf/extensions/hash.rb +32 -0
  29. data/lib/erlang/etf/extensions/integer.rb +48 -0
  30. data/lib/erlang/etf/extensions/nil_class.rb +29 -0
  31. data/lib/erlang/etf/extensions/object.rb +24 -0
  32. data/lib/erlang/etf/extensions/regexp.rb +34 -0
  33. data/lib/erlang/etf/extensions/string.rb +35 -0
  34. data/lib/erlang/etf/extensions/symbol.rb +45 -0
  35. data/lib/erlang/etf/extensions/time.rb +29 -0
  36. data/lib/erlang/etf/extensions/true_class.rb +28 -0
  37. data/lib/erlang/etf/float.rb +57 -0
  38. data/lib/erlang/etf/fun.rb +67 -0
  39. data/lib/erlang/etf/integer.rb +29 -0
  40. data/lib/erlang/etf/large_big.rb +53 -0
  41. data/lib/erlang/etf/large_tuple.rb +55 -0
  42. data/lib/erlang/etf/list.rb +50 -0
  43. data/lib/erlang/etf/new_float.rb +33 -0
  44. data/lib/erlang/etf/new_fun.rb +98 -0
  45. data/lib/erlang/etf/new_reference.rb +59 -0
  46. data/lib/erlang/etf/nil.rb +23 -0
  47. data/lib/erlang/etf/pid.rb +45 -0
  48. data/lib/erlang/etf/port.rb +34 -0
  49. data/lib/erlang/etf/reference.rb +41 -0
  50. data/lib/erlang/etf/small_atom.rb +48 -0
  51. data/lib/erlang/etf/small_atom_utf8.rb +44 -0
  52. data/lib/erlang/etf/small_big.rb +59 -0
  53. data/lib/erlang/etf/small_integer.rb +29 -0
  54. data/lib/erlang/etf/small_tuple.rb +56 -0
  55. data/lib/erlang/etf/string.rb +46 -0
  56. data/lib/erlang/etf/term.rb +101 -0
  57. data/lib/erlang/etf/terms.rb +105 -0
  58. data/lib/erlang/etf/version.rb +5 -0
  59. data/spec/erlang/etf/atom_spec.rb +90 -0
  60. data/spec/erlang/etf/atom_utf8_spec.rb +90 -0
  61. data/spec/erlang/etf/binary_spec.rb +90 -0
  62. data/spec/erlang/etf/bit_binary_spec.rb +99 -0
  63. data/spec/erlang/etf/export_spec.rb +58 -0
  64. data/spec/erlang/etf/extensions/array_spec.rb +40 -0
  65. data/spec/erlang/etf/extensions/big_decimal_spec.rb +26 -0
  66. data/spec/erlang/etf/extensions/erlang-export_spec.rb +32 -0
  67. data/spec/erlang/etf/extensions/erlang-list_spec.rb +76 -0
  68. data/spec/erlang/etf/extensions/erlang-nil_spec.rb +24 -0
  69. data/spec/erlang/etf/extensions/erlang-pid_spec.rb +33 -0
  70. data/spec/erlang/etf/extensions/erlang-string_spec.rb +26 -0
  71. data/spec/erlang/etf/extensions/erlang-tuple_spec.rb +56 -0
  72. data/spec/erlang/etf/extensions/false_class_spec.rb +29 -0
  73. data/spec/erlang/etf/extensions/float_spec.rb +24 -0
  74. data/spec/erlang/etf/extensions/hash_spec.rb +90 -0
  75. data/spec/erlang/etf/extensions/integer_spec.rb +259 -0
  76. data/spec/erlang/etf/extensions/nil_class_spec.rb +29 -0
  77. data/spec/erlang/etf/extensions/object_spec.rb +30 -0
  78. data/spec/erlang/etf/extensions/regexp_spec.rb +35 -0
  79. data/spec/erlang/etf/extensions/string_spec.rb +43 -0
  80. data/spec/erlang/etf/extensions/symbol_spec.rb +64 -0
  81. data/spec/erlang/etf/extensions/time_spec.rb +32 -0
  82. data/spec/erlang/etf/extensions/true_class_spec.rb +29 -0
  83. data/spec/erlang/etf/float_spec.rb +92 -0
  84. data/spec/erlang/etf/fun_spec.rb +132 -0
  85. data/spec/erlang/etf/integer_spec.rb +57 -0
  86. data/spec/erlang/etf/large_big_spec.rb +67 -0
  87. data/spec/erlang/etf/large_tuple_spec.rb +119 -0
  88. data/spec/erlang/etf/list_spec.rb +159 -0
  89. data/spec/erlang/etf/new_float_spec.rb +92 -0
  90. data/spec/erlang/etf/new_fun_spec.rb +146 -0
  91. data/spec/erlang/etf/new_reference_spec.rb +60 -0
  92. data/spec/erlang/etf/nil_spec.rb +50 -0
  93. data/spec/erlang/etf/pid_spec.rb +61 -0
  94. data/spec/erlang/etf/port_spec.rb +58 -0
  95. data/spec/erlang/etf/reference_spec.rb +58 -0
  96. data/spec/erlang/etf/small_atom_spec.rb +90 -0
  97. data/spec/erlang/etf/small_atom_utf8_spec.rb +90 -0
  98. data/spec/erlang/etf/small_big_spec.rb +67 -0
  99. data/spec/erlang/etf/small_integer_spec.rb +57 -0
  100. data/spec/erlang/etf/small_tuple_spec.rb +112 -0
  101. data/spec/erlang/etf/string_spec.rb +92 -0
  102. data/spec/erlang/etf/term_spec.rb +27 -0
  103. data/spec/erlang/etf/terms_spec.rb +23 -0
  104. data/spec/erlang/etf_spec.rb +23 -0
  105. data/spec/erlang_spec.rb +77 -0
  106. data/spec/spec_helper.rb +7 -0
  107. metadata +310 -0
@@ -0,0 +1,105 @@
1
+ module Erlang
2
+ module ETF
3
+ module Terms
4
+ ATOM_CACHE_REF = 82.freeze # not implemented
5
+ SMALL_INTEGER_EXT = 97.freeze
6
+ INTEGER_EXT = 98.freeze
7
+ FLOAT_EXT = 99.freeze
8
+ ATOM_EXT = 100.freeze
9
+ REFERENCE_EXT = 101.freeze
10
+ PORT_EXT = 102.freeze
11
+ PID_EXT = 103.freeze
12
+ SMALL_TUPLE_EXT = 104.freeze
13
+ LARGE_TUPLE_EXT = 105.freeze
14
+ NIL_EXT = 106.freeze
15
+ STRING_EXT = 107.freeze
16
+ LIST_EXT = 108.freeze
17
+ BINARY_EXT = 109.freeze
18
+ SMALL_BIG_EXT = 110.freeze
19
+ LARGE_BIG_EXT = 111.freeze
20
+ NEW_REFERENCE_EXT = 114.freeze
21
+ SMALL_ATOM_EXT = 115.freeze
22
+ FUN_EXT = 117.freeze
23
+ NEW_FUN_EXT = 112.freeze
24
+ EXPORT_EXT = 113.freeze
25
+ BIT_BINARY_EXT = 77.freeze
26
+ NEW_FLOAT_EXT = 70.freeze
27
+ ATOM_UTF8_EXT = 118.freeze
28
+ SMALL_ATOM_UTF8_EXT = 119.freeze
29
+ end
30
+ end
31
+ end
32
+
33
+ require "erlang/etf/term"
34
+ require "erlang/etf/bert"
35
+
36
+ require "erlang/etf/atom"
37
+ require "erlang/etf/atom_utf8"
38
+ require "erlang/etf/binary"
39
+ require "erlang/etf/bit_binary"
40
+ require "erlang/etf/export"
41
+ require "erlang/etf/float"
42
+ require "erlang/etf/fun"
43
+ require "erlang/etf/integer"
44
+ require "erlang/etf/large_big"
45
+ require "erlang/etf/large_tuple"
46
+ require "erlang/etf/list"
47
+ require "erlang/etf/new_float"
48
+ require "erlang/etf/new_fun"
49
+ require "erlang/etf/new_reference"
50
+ require "erlang/etf/nil"
51
+ require "erlang/etf/pid"
52
+ require "erlang/etf/port"
53
+ require "erlang/etf/reference"
54
+ require "erlang/etf/small_atom"
55
+ require "erlang/etf/small_atom_utf8"
56
+ require "erlang/etf/small_big"
57
+ require "erlang/etf/small_integer"
58
+ require "erlang/etf/small_tuple"
59
+ require "erlang/etf/string"
60
+
61
+ module Erlang
62
+ module ETF
63
+ module Terms
64
+ MAP = {}
65
+ # MAP[ATOM_CACHE_REF] = undefined
66
+ MAP[SMALL_INTEGER_EXT] = ETF::SmallInteger
67
+ MAP[INTEGER_EXT] = ETF::Integer
68
+ MAP[FLOAT_EXT] = ETF::Float
69
+ MAP[ATOM_EXT] = ETF::Atom
70
+ MAP[REFERENCE_EXT] = ETF::Reference
71
+ MAP[PORT_EXT] = ETF::Port
72
+ MAP[PID_EXT] = ETF::Pid
73
+ MAP[SMALL_TUPLE_EXT] = ETF::SmallTuple
74
+ MAP[LARGE_TUPLE_EXT] = ETF::LargeTuple
75
+ MAP[NIL_EXT] = ETF::Nil
76
+ MAP[STRING_EXT] = ETF::String
77
+ MAP[LIST_EXT] = ETF::List
78
+ MAP[BINARY_EXT] = ETF::Binary
79
+ MAP[SMALL_BIG_EXT] = ETF::SmallBig
80
+ MAP[LARGE_BIG_EXT] = ETF::LargeBig
81
+ MAP[NEW_REFERENCE_EXT] = ETF::NewReference
82
+ MAP[SMALL_ATOM_EXT] = ETF::SmallAtom
83
+ MAP[FUN_EXT] = ETF::Fun
84
+ MAP[NEW_FUN_EXT] = ETF::NewFun
85
+ MAP[EXPORT_EXT] = ETF::Export
86
+ MAP[BIT_BINARY_EXT] = ETF::BitBinary
87
+ MAP[NEW_FLOAT_EXT] = ETF::NewFloat
88
+ MAP[ATOM_UTF8_EXT] = ETF::AtomUTF8
89
+ MAP[SMALL_ATOM_UTF8_EXT] = ETF::SmallAtomUTF8
90
+
91
+ def self.deserialize(buffer)
92
+ key, = buffer.read(1).unpack(::Binary::Protocol::UINT8_PACK)
93
+ if MAP.key?(key)
94
+ MAP[key].deserialize(buffer)
95
+ else
96
+ raise NotImplementedError, "unknown Erlang External Format tag #{key.inspect} (see http://erlang.org/doc/apps/erts/erl_ext_dist.html)"
97
+ end
98
+ end
99
+
100
+ def self.evolve(buffer)
101
+ deserialize(buffer).__ruby_evolve__
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,5 @@
1
+ module Erlang
2
+ module ETF
3
+ VERSION = "1.0.0"
4
+ end
5
+ end
@@ -0,0 +1,90 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Erlang::ETF::Atom do
6
+ let(:term_class) { Erlang::ETF::Atom }
7
+
8
+ describe '[class]' do
9
+ describe 'deserialize' do
10
+ let(:buffer) { StringIO.new(bytes.pack('C*')) }
11
+ subject { term_class.deserialize(buffer) }
12
+
13
+ context "ASCII bytes" do
14
+ let(:bytes) { [0, 4, 116, 101, 115, 116] }
15
+
16
+ its(:len) { should eq(4) }
17
+ its(:atom_name) { should eq("test") }
18
+ end
19
+
20
+ context "UTF-8 bytes" do
21
+ let(:bytes) { [0, 2, 206, 169] }
22
+
23
+ its(:len) { should eq(2) }
24
+ its(:atom_name) { should eq("Ω") }
25
+ end
26
+ end
27
+
28
+ describe 'new' do
29
+ subject { term_class.new(atom_name) }
30
+
31
+ context "ASCII" do
32
+ let(:atom_name) { "test" }
33
+
34
+ its(:atom_name) { should eq(atom_name) }
35
+ end
36
+
37
+ context "UTF-8" do
38
+ let(:atom_name) { "Ω" }
39
+
40
+ its(:atom_name) { should eq(atom_name) }
41
+ end
42
+ end
43
+ end
44
+
45
+ describe '[instance]' do
46
+ let(:term) { term_class.new(atom_name) }
47
+
48
+ describe 'serialize' do
49
+ subject { term.serialize }
50
+
51
+ context "ASCII" do
52
+ let(:atom_name) { "test" }
53
+ let(:bytes) { [100, 0, 4, 116, 101, 115, 116].pack('C*') }
54
+
55
+ it { should eq(bytes) }
56
+ end
57
+
58
+ context "UTF-8" do
59
+ let(:atom_name) { "Ω" }
60
+ let(:bytes) { [100, 0, 2, 206, 169].pack('C*') }
61
+
62
+ it { should eq(bytes) }
63
+ end
64
+ end
65
+
66
+ describe '__erlang_type__' do
67
+ subject { term.__erlang_type__ }
68
+
69
+ let(:atom_name) { "test" }
70
+ it { should eq(:atom) }
71
+ end
72
+
73
+ describe '__ruby_evolve__' do
74
+ subject { term.__ruby_evolve__ }
75
+
76
+ context "ASCII" do
77
+ let(:atom_name) { "test" }
78
+
79
+ it { should eq(:test) }
80
+ end
81
+
82
+ context "UTF-8" do
83
+ let(:atom_name) { "Ω" }
84
+
85
+ it { should eq(:'Ω') }
86
+ end
87
+ end
88
+ end
89
+
90
+ end
@@ -0,0 +1,90 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Erlang::ETF::AtomUTF8 do
6
+ let(:term_class) { Erlang::ETF::AtomUTF8 }
7
+
8
+ describe '[class]' do
9
+ describe 'deserialize' do
10
+ let(:buffer) { StringIO.new(bytes.pack('C*')) }
11
+ subject { term_class.deserialize(buffer) }
12
+
13
+ context "ASCII bytes" do
14
+ let(:bytes) { [0, 4, 116, 101, 115, 116] }
15
+
16
+ its(:len) { should eq(4) }
17
+ its(:atom_name) { should eq("test") }
18
+ end
19
+
20
+ context "UTF-8 bytes" do
21
+ let(:bytes) { [0, 2, 206, 169] }
22
+
23
+ its(:len) { should eq(2) }
24
+ its(:atom_name) { should eq("Ω") }
25
+ end
26
+ end
27
+
28
+ describe 'new' do
29
+ subject { term_class.new(atom_name) }
30
+
31
+ context "ASCII" do
32
+ let(:atom_name) { "test" }
33
+
34
+ its(:atom_name) { should eq(atom_name) }
35
+ end
36
+
37
+ context "UTF-8" do
38
+ let(:atom_name) { "Ω" }
39
+
40
+ its(:atom_name) { should eq(atom_name) }
41
+ end
42
+ end
43
+ end
44
+
45
+ describe '[instance]' do
46
+ let(:term) { term_class.new(atom_name) }
47
+
48
+ describe 'serialize' do
49
+ subject { term.serialize }
50
+
51
+ context "ASCII" do
52
+ let(:atom_name) { "test" }
53
+ let(:bytes) { [118, 0, 4, 116, 101, 115, 116].pack('C*') }
54
+
55
+ it { should eq(bytes) }
56
+ end
57
+
58
+ context "UTF-8" do
59
+ let(:atom_name) { "Ω" }
60
+ let(:bytes) { [118, 0, 2, 206, 169].pack('C*') }
61
+
62
+ it { should eq(bytes) }
63
+ end
64
+ end
65
+
66
+ describe '__erlang_type__' do
67
+ subject { term.__erlang_type__ }
68
+
69
+ let(:atom_name) { "Ω" }
70
+ it { should eq(:atom_utf8) }
71
+ end
72
+
73
+ describe '__ruby_evolve__' do
74
+ subject { term.__ruby_evolve__ }
75
+
76
+ context "ASCII" do
77
+ let(:atom_name) { "test" }
78
+
79
+ it { should eq(:test) }
80
+ end
81
+
82
+ context "UTF-8" do
83
+ let(:atom_name) { "Ω" }
84
+
85
+ it { should eq(:'Ω') }
86
+ end
87
+ end
88
+ end
89
+
90
+ end
@@ -0,0 +1,90 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Erlang::ETF::Binary do
6
+ let(:term_class) { Erlang::ETF::Binary }
7
+
8
+ describe '[class]' do
9
+ describe 'deserialize' do
10
+ let(:buffer) { StringIO.new(bytes.pack('C*')) }
11
+ subject { term_class.deserialize(buffer) }
12
+
13
+ context "ASCII bytes" do
14
+ let(:bytes) { [0, 0, 0, 4, 116, 101, 115, 116] }
15
+
16
+ its(:len) { should eq(4) }
17
+ its(:data) { should eq("test") }
18
+ end
19
+
20
+ context "UTF-8 bytes" do
21
+ let(:bytes) { [0, 0, 0, 2, 206, 169] }
22
+
23
+ its(:len) { should eq(2) }
24
+ its(:data) { should eq("Ω") }
25
+ end
26
+ end
27
+
28
+ describe 'new' do
29
+ subject { term_class.new(data) }
30
+
31
+ context "ASCII" do
32
+ let(:data) { "test" }
33
+
34
+ its(:data) { should eq(data) }
35
+ end
36
+
37
+ context "UTF-8" do
38
+ let(:data) { "Ω" }
39
+
40
+ its(:data) { should eq(data) }
41
+ end
42
+ end
43
+ end
44
+
45
+ describe '[instance]' do
46
+ let(:term) { term_class.new(data) }
47
+
48
+ describe 'serialize' do
49
+ subject { term.serialize }
50
+
51
+ context "ASCII" do
52
+ let(:data) { "test" }
53
+ let(:bytes) { [109, 0, 0, 0, 4, 116, 101, 115, 116].pack('C*') }
54
+
55
+ it { should eq(bytes) }
56
+ end
57
+
58
+ context "UTF-8" do
59
+ let(:data) { "Ω" }
60
+ let(:bytes) { [109, 0, 0, 0, 2, 206, 169].pack('C*') }
61
+
62
+ it { should eq(bytes) }
63
+ end
64
+ end
65
+
66
+ describe '__erlang_type__' do
67
+ subject { term.__erlang_type__ }
68
+
69
+ let(:data) { "test" }
70
+ it { should eq(:binary) }
71
+ end
72
+
73
+ describe '__ruby_evolve__' do
74
+ subject { term.__ruby_evolve__ }
75
+
76
+ context "ASCII" do
77
+ let(:data) { "test" }
78
+
79
+ it { should eq("test") }
80
+ end
81
+
82
+ context "UTF-8" do
83
+ let(:data) { "Ω" }
84
+
85
+ it { should eq("Ω") }
86
+ end
87
+ end
88
+ end
89
+
90
+ end
@@ -0,0 +1,99 @@
1
+ # encoding: utf-8
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Erlang::ETF::BitBinary do
6
+ let(:term_class) { Erlang::ETF::BitBinary }
7
+
8
+ describe '[class]' do
9
+ describe 'deserialize' do
10
+ let(:buffer) { StringIO.new(bytes.pack('C*')) }
11
+ subject { term_class.deserialize(buffer) }
12
+
13
+ context "ASCII bytes" do
14
+ let(:bytes) { [0, 0, 0, 5, 1, 116, 101, 115, 116, 128] }
15
+
16
+ its(:len) { should eq(5) }
17
+ its(:bits) { should eq(1) }
18
+ its(:data) { should eq("test\x80") }
19
+ end
20
+
21
+ context "UTF-8 bytes" do
22
+ let(:bytes) { [0, 0, 0, 3, 1, 206, 169, 128] }
23
+
24
+ its(:len) { should eq(3) }
25
+ its(:bits) { should eq(1) }
26
+ its(:data) { should eq("Ω\x80") }
27
+ end
28
+ end
29
+
30
+ describe 'new' do
31
+ subject { term_class.new(bits, data) }
32
+
33
+ context "ASCII" do
34
+ let(:bits) { 1 }
35
+ let(:data) { "test\x80" }
36
+
37
+ its(:data) { should eq(data) }
38
+ end
39
+
40
+ context "UTF-8" do
41
+ let(:bits) { 1 }
42
+ let(:data) { "Ω\x80" }
43
+
44
+ its(:data) { should eq(data) }
45
+ end
46
+ end
47
+ end
48
+
49
+ describe '[instance]' do
50
+ let(:term) { term_class.new(bits, data) }
51
+
52
+ describe 'serialize' do
53
+ subject { term.serialize }
54
+
55
+ context "ASCII" do
56
+ let(:bits) { 1 }
57
+ let(:data) { "test\x80" }
58
+ let(:bytes) { [77, 0, 0, 0, 5, 1, 116, 101, 115, 116, 128].pack('C*') }
59
+
60
+ it { should eq(bytes) }
61
+ end
62
+
63
+ context "UTF-8" do
64
+ let(:bits) { 1 }
65
+ let(:data) { "Ω\x80" }
66
+ let(:bytes) { [77, 0, 0, 0, 3, 1, 206, 169, 128].pack('C*') }
67
+
68
+ it { should eq(bytes) }
69
+ end
70
+ end
71
+
72
+ describe '__erlang_type__' do
73
+ subject { term.__erlang_type__ }
74
+
75
+ let(:bits) { 1 }
76
+ let(:data) { "test\x80" }
77
+ it { should eq(:bit_binary) }
78
+ end
79
+
80
+ describe '__ruby_evolve__' do
81
+ subject { term.__ruby_evolve__ }
82
+
83
+ context "ASCII" do
84
+ let(:bits) { 1 }
85
+ let(:data) { "test\x80" }
86
+
87
+ it { should eq(term) }
88
+ end
89
+
90
+ context "UTF-8" do
91
+ let(:bits) { 1 }
92
+ let(:data) { "Ω\x80" }
93
+
94
+ it { should eq(term) }
95
+ end
96
+ end
97
+ end
98
+
99
+ end