serde 0.0.1 → 0.0.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 56ecad527ba63b8bab91bf3c1f6f69db7b47a2154e61d79163a5a998683682d0
4
- data.tar.gz: 36c782fa69b87ed6e44273b11a73d136665b2e66194d4d6a42d9a9c6f180518e
3
+ metadata.gz: 6451590c25809fc93d4d9a1bcfd3b0792078c0921b6031ec31ce65892ba41c0e
4
+ data.tar.gz: 4efaecacfadf090538b228274d4555781b04c65ee9a07cef4e6266ec7a5b9400
5
5
  SHA512:
6
- metadata.gz: 403cd1c381aeb30ee51cb793ee4fb16b07768d982d6e6654ef498840c66c48584263f7e7590077a43ad31a157341b9f274d8377c102f762714f63ee47b9993ee
7
- data.tar.gz: ae956ed2dd8d82640ea69cc8011308ec904c71019e910136d41cd989d1ebe7c43e09f263d7eb1abee3feeb08c3fcaa1486fefef0b818af331fcd1d8f94d55ba0
6
+ metadata.gz: db9fc2fa1159029b2387ff37768bdde5f008d56dc7a40bf5a6e6bee90650ed01fd5185abd0438aa7fc0b155e68cdb2620db37551e448b6e9f1b1a3ef4e493023
7
+ data.tar.gz: 473f65a45fdebe1d0ed38349441d7810cb4eec559efdf47316f7ce41c4d4bae0da8c691158e9b3503f10467b8ba7ebef6ae8e4f9855d36cabc931940f03e8f61
data/.gitignore CHANGED
@@ -1,3 +1,7 @@
1
+ /.rustc
2
+ /bin/rustc
1
3
  /tmp
2
- /_target_
3
4
  /serde-*.gem
5
+ .ruby-version
6
+ Gemfile.lock
7
+ examples/app/Gemfile.lock
data/.rubocop.yml ADDED
@@ -0,0 +1,29 @@
1
+ inherit_gem:
2
+ armitage-rubocop:
3
+ - lib/rubocop.general.yml
4
+ - lib/rubocop.rspec.yml
5
+
6
+ AllCops:
7
+ TargetRubyVersion: 2.5.3
8
+ Include:
9
+ - serde.gemspec
10
+ - lib/**/*.rb
11
+ - spec/**/*.rb
12
+ - Gemfile
13
+ - examples/**/*.rb
14
+
15
+ Style/TrailingCommaInArguments:
16
+ EnforcedStyleForMultiline: comma
17
+
18
+ Style/TrailingCommaInArrayLiteral:
19
+ EnforcedStyleForMultiline: comma
20
+
21
+ Style/TrailingCommaInHashLiteral:
22
+ EnforcedStyleForMultiline: comma
23
+
24
+ Metrics/AbcSize:
25
+ Max: 40
26
+
27
+ Naming/FileName:
28
+ Exclude:
29
+ - examples/app/Gemfile
data/Gemfile CHANGED
@@ -1,7 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  source 'https://rubygems.org'
2
- gemspec
3
4
 
4
- group :development, :test do
5
- gem 'surrealist'
6
- gem 'benchmark-ips'
7
- end
5
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
6
+
7
+ gemspec
data/README.md CHANGED
@@ -5,15 +5,17 @@ WIP
5
5
  # TODO:
6
6
 
7
7
  - [ ] Write the README
8
- - [ ] Use a temporary directory instead of `_target_`
8
+ - [x] Use a temporary directory instead of `_target_`
9
9
  - [ ] Write specs
10
- - [ ] Set up rubocop
10
+ - [x] Set up rubocop
11
11
  - [ ] Set up CI
12
12
  - [ ] Reuse Rust crate, but generate sources in a temp dir
13
13
  - [ ] Cover all basic types (Integer, String, Float, Boolean)
14
14
  - [ ] Nullable types
15
15
  - [ ] Composite types (ArrayOf, HashMap?, Enum)
16
16
  - [ ] Vendor `rustc` with the gem
17
- - [ ] Write benchmarks, compare with Surrealist
17
+ - [x] Write benchmarks, compare with Surrealist
18
+ - [ ] Support any serde-compatible format
19
+ - [ ] Deserialization
18
20
  - [ ] Allow dynamic hashes?
19
21
  - [ ] Type checks and coercions?
data/Rakefile ADDED
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+ require 'rubocop'
6
+ require 'rubocop-rspec'
7
+ require 'rubocop/rake_task'
8
+
9
+ RuboCop::RakeTask.new(:rubocop) do |t|
10
+ config_path = File.expand_path(File.join('.rubocop.yml'), __dir__)
11
+
12
+ t.options = ['--config', config_path]
13
+ t.requires << 'rubocop-rspec'
14
+ end
15
+
16
+ RSpec::Core::RakeTask.new(:rspec)
17
+
18
+ task :run_example do
19
+ require_relative 'examples/app/new.rb'
20
+ end
21
+
22
+ task :bench do
23
+ require_relative 'bench/bench.rb'
24
+ end
25
+
26
+ task default: :rspec
data/bench/bench.rb ADDED
@@ -0,0 +1,115 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/setup'
4
+
5
+ require 'benchmark/ips'
6
+ require 'serde'
7
+ require 'surrealist'
8
+
9
+ class User
10
+ attr_reader :id, :first_name, :last_name, :email, :age
11
+
12
+ def initialize(id, first_name, last_name, email, age)
13
+ @id = id
14
+ @first_name = first_name
15
+ @last_name = last_name
16
+ @email = email
17
+ @age = age
18
+ end
19
+ end
20
+
21
+ class UserSerdeSerializer < Serde::Serializer
22
+ schema(
23
+ id: Integer,
24
+ first_name: String,
25
+ last_name: String,
26
+ email: String,
27
+ age: Integer
28
+ )
29
+ end
30
+
31
+ class UserSurrealistSerializer < Surrealist::Serializer
32
+ json_schema do
33
+ {
34
+ id: Integer,
35
+ first_name: String,
36
+ last_name: String,
37
+ email: String,
38
+ age: Integer
39
+ }
40
+ end
41
+ end
42
+
43
+ class UserOjSerializer
44
+ def initialize(user)
45
+ @user = user
46
+ end
47
+
48
+ def to_json
49
+ Oj.dump(
50
+ id: @user.id,
51
+ first_name: @user.first_name,
52
+ last_name: @user.last_name,
53
+ email: @user.email,
54
+ age: @user.age
55
+ )
56
+ end
57
+ end
58
+
59
+ user = User.new(1, 'Pavel', 'Yakimov', 'mrpavel@example.com', 24)
60
+ serde_serializer = UserSerdeSerializer.new(user)
61
+ surrealist_serializer = UserSurrealistSerializer.new(user)
62
+ oj_serializer = UserOjSerializer.new(user)
63
+
64
+ puts "-------\nSerialize to JSON\n-------"
65
+ Benchmark.ips do |x|
66
+ x.report('serde') { serde_serializer.to_json }
67
+ x.report('Surrealist') { surrealist_serializer.surrealize }
68
+ x.report('Oj') { oj_serializer.to_json }
69
+
70
+ x.compare!
71
+ end
72
+
73
+ puts "-------\nInitialize + serialize to JSON\n-------"
74
+ Benchmark.ips do |x|
75
+ x.report('serde') { UserSerdeSerializer.new(user).to_json }
76
+ x.report('Surrealist') { UserSurrealistSerializer.new(user).surrealize }
77
+ x.report('Oj') { UserOjSerializer.new(user).to_json }
78
+
79
+ x.compare!
80
+ end
81
+
82
+ # -------
83
+ # Serialize to JSON
84
+ # -------
85
+ # Warming up --------------------------------------
86
+ # serde 76.802k i/100ms
87
+ # Surrealist 3.064k i/100ms
88
+ # Oj 51.183k i/100ms
89
+ # Calculating -------------------------------------
90
+ # serde 898.268k (± 5.1%) i/s - 4.531M in 5.058080s
91
+ # Surrealist 36.268k (± 3.2%) i/s - 183.840k in 5.074885s
92
+ # Oj 689.594k (± 3.4%) i/s - 3.480M in 5.053357s
93
+
94
+ # Comparison:
95
+ # serde: 898267.9 i/s
96
+ # Oj: 689593.9 i/s - 1.30x slower
97
+ # Surrealist: 36268.1 i/s - 24.77x slower
98
+
99
+ # -------
100
+ # Initialize + serialize to JSON
101
+ # -------
102
+ # Warming up --------------------------------------
103
+ # serde 41.158k i/100ms
104
+ # Surrealist 3.087k i/100ms
105
+ # Oj 51.710k i/100ms
106
+ # Calculating -------------------------------------
107
+ # serde 451.324k (± 1.4%) i/s - 2.264M in 5.016647s
108
+ # Surrealist 33.478k (± 6.8%) i/s - 166.698k in 5.003821s
109
+ # Oj 635.098k (± 2.9%) i/s - 3.206M in 5.052618s
110
+
111
+ # Comparison:
112
+ # Oj: 635097.9 i/s
113
+ # serde: 451323.7 i/s - 1.41x slower
114
+ # Surrealist: 33478.1 i/s - 18.97x slower
115
+
data/bin/.keep ADDED
File without changes
data/examples/app/new.rb CHANGED
@@ -3,20 +3,43 @@
3
3
  require 'bundler/setup'
4
4
  require 'serde'
5
5
 
6
- class CowSerializer < Serde::Serializer
7
- schema(
8
- id: Integer,
9
- name: String,
10
- )
6
+ module Kek
7
+ class Cow
8
+ attr_reader :id, :name
9
+
10
+ def initialize(id, name)
11
+ @id = id
12
+ @name = name
13
+ end
14
+ end
15
+
16
+ class CowSerializer < Serde::Serializer
17
+ schema(
18
+ id: Integer,
19
+ name: String,
20
+ )
21
+ end
11
22
  end
12
23
 
13
- class Cow
14
- attr_reader :id, :name
24
+ module Pek
25
+ class Car
26
+ attr_reader :id, :brand, :model
27
+
28
+ def initialize(id, brand, model)
29
+ @id = id
30
+ @brand = brand
31
+ @model = model
32
+ end
33
+ end
15
34
 
16
- def initialize(id, name)
17
- @id = id
18
- @name = name
35
+ class CarSerializer < Serde::Serializer
36
+ schema(
37
+ id: Integer,
38
+ brand: String,
39
+ model: String,
40
+ )
19
41
  end
20
42
  end
21
43
 
22
- puts CowSerializer.new(Cow.new(1, 'Ковыч')).to_json
44
+ puts Kek::CowSerializer.new(Kek::Cow.new(1, 'Ковыч')).to_json
45
+ puts Pek::CarSerializer.new(Pek::Car.new(1, 'Mazda', '6')).to_json
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ Gem.post_install do
4
+ puts 'installing rustc'
5
+ require_relative 'rustc_installer.rb'
6
+ end
@@ -0,0 +1,96 @@
1
+ # frozen_string_literal: true
2
+
3
+ # TODO: test on different systems and architectures
4
+
5
+ require 'tmpdir'
6
+ require 'net/http'
7
+ require 'fileutils'
8
+ require 'rubygems/package'
9
+ require 'zlib'
10
+
11
+ # https://github.com/rust-lang/rustup.rs/blob/243e3d5889a58116fb7eb910e8508b9d0d0a0b04/rustup-init.sh#L172
12
+ # not considering android and mips for now
13
+ ostype = `uname -s`.chomp
14
+ cputype = `uname -m`.chomp
15
+
16
+ if ostype == 'Darwin' && cputype == 'i386' && !`sysctl hw.optional.x86_64 | grep -q ': 1'`.nil?
17
+ cputype = 'x86_64'
18
+ end
19
+
20
+ ostype =
21
+ case ostype
22
+ when 'Linux' then 'unknown-linux-gnu'
23
+ when 'FreeBSD' then 'unknown-freebsd'
24
+ when 'NetBSD' then 'unknown-netbsd'
25
+ when 'DragonFly' then 'unknown-dragonfly'
26
+ when 'Darwin' then 'apple-darwin'
27
+ when /MINGW/, /MSYS/, /CYGWIN/ then 'pc-windows-gnu'
28
+ else raise "unrecognized OS type: #{ostype}"
29
+ end
30
+
31
+ cputype =
32
+ case cputype
33
+ when 'i386', 'i486', 'i686', 'i786', 'x86' then 'i686'
34
+ when 'xscale', 'arm' then 'arm'
35
+ when 'armv6l' then 'armeabihf'
36
+ when 'armv7l', 'armv8l' then 'armv7eabihf'
37
+ when 'aarch64' then 'aarch64'
38
+ when 'x86_64', 'x86-64', 'x64', 'amd64' then 'x86_64'
39
+ when 'ppc' then 'powerpc'
40
+ when 'ppc64' then 'powerpc64'
41
+ when 'ppc64le' then 'powerpc64le'
42
+ else raise "unknown CPU type: #{cputype}"
43
+ end
44
+
45
+ rustc_name = "rustc-beta-#{cputype}-#{ostype}"
46
+ ruststd_name = "rust-std-beta-#{cputype}-#{ostype}"
47
+ TAR_LONGLINK = '././@LongLink'
48
+ DESTINATION = File.expand_path('../.rustc', __dir__)
49
+
50
+ def download_and_extract(name) # rubocop:disable Metrics/MethodLength
51
+ File.write(
52
+ "#{name}.tar.gz",
53
+ Net::HTTP.get(URI("https://static.rust-lang.org/dist/2018-11-27/#{name}.tar.gz")),
54
+ )
55
+
56
+ # https://stackoverflow.com/a/19139114
57
+ Gem::Package::TarReader.new(Zlib::GzipReader.open("#{name}.tar.gz")) do |tar|
58
+ dest = nil
59
+ tar.each do |entry|
60
+ if entry.full_name == TAR_LONGLINK
61
+ dest = File.join DESTINATION, entry.read.strip
62
+ next
63
+ end
64
+ dest ||= File.join DESTINATION, entry.full_name
65
+ if entry.directory?
66
+ File.delete dest if File.file? dest
67
+ FileUtils.mkdir_p dest, mode: entry.header.mode, verbose: false
68
+ elsif entry.file?
69
+ FileUtils.rm_rf dest if File.directory? dest
70
+ File.open dest, 'wb' do |f|
71
+ f.print entry.read
72
+ end
73
+ FileUtils.chmod entry.header.mode, dest, verbose: false
74
+ elsif entry.header.typeflag == '2' # Symlink!
75
+ File.symlink entry.header.linkname, dest
76
+ end
77
+ dest = nil
78
+ end
79
+ end
80
+ end
81
+
82
+ Dir.mktmpdir do |dir|
83
+ Dir.chdir(dir) do
84
+ # manifest = Net::HTTP.get(URI('https://static.rust-lang.org/dist/channel-rust-beta.toml'))
85
+ # puts manifest
86
+
87
+ download_and_extract(rustc_name)
88
+ download_and_extract(ruststd_name)
89
+
90
+ # TODO: windows?
91
+ FileUtils.ln_s(
92
+ "#{DESTINATION}/#{rustc_name}/rustc/bin/rustc",
93
+ File.expand_path('../bin/rustc', __dir__),
94
+ )
95
+ end
96
+ end
@@ -1,14 +1,16 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'erb'
2
4
 
3
- def generate_serializers
4
- def underscore(str)
5
- str.tr('::', '/')
6
- .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
7
- .gsub(/([a-z\d])([A-Z])/, '\1_\2')
8
- .tr('-', '_')
9
- .downcase
10
- end
5
+ def underscore(str)
6
+ str.tr('::', '/')
7
+ .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
8
+ .gsub(/([a-z\d])([A-Z])/, '\1_\2')
9
+ .tr('-', '_')
10
+ .downcase
11
+ end
11
12
 
13
+ def generate_serializers # rubocop:disable Metrics/MethodLength
12
14
  modules = []
13
15
 
14
16
  Serde.subclasses.each do |klass|
@@ -32,7 +34,7 @@ def generate_serializers
32
34
  fields: fields,
33
35
  joint_fields: fields.map do |field|
34
36
  "#{field[:name]}: #{field[:type]}"
35
- end.join(', ')
37
+ end.join(', '),
36
38
  }
37
39
 
38
40
  mod_template = ERB.new(File.read('./rust_template/mod.rs.erb'))
@@ -44,7 +46,7 @@ def generate_serializers
44
46
  lib_template = ERB.new(File.read('./rust_template/lib.rs.erb'))
45
47
  compiled_template = lib_template.result(binding)
46
48
 
47
- File.open("./src/lib.rs", 'w') { |f| f.write(compiled_template) }
49
+ File.open('./src/lib.rs', 'w') { |f| f.write(compiled_template) }
48
50
 
49
51
  `rake build`
50
52
  end
@@ -1,11 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'fileutils'
3
4
  require 'erb'
4
5
 
5
6
  module Serde
6
7
  module SerializerGenerator
7
8
  class << self
8
- def call(klass)
9
+ # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity
10
+ def call(dir, klass)
11
+ FileUtils.cp_r(Dir.glob(File.expand_path('../../templates/extension/*', __dir__)), '.')
12
+
9
13
  schema = klass.instance_variable_get(:@schema)
10
14
 
11
15
  name = underscore(klass.name)
@@ -37,6 +41,18 @@ module Serde
37
41
  { name: k, type: type, rctype: rctype, cdecl: cdecl, ctype: ctype }
38
42
  end
39
43
 
44
+ rust_extras = []
45
+
46
+ schema.each do |k, v|
47
+ next unless v.to_s == 'String'
48
+
49
+ rust_extras.push(<<~RUST)
50
+ let #{k} = unsafe {
51
+ CStr::from_ptr(#{k}).to_string_lossy().into_owned()
52
+ };
53
+ RUST
54
+ end
55
+
40
56
  serializer = {
41
57
  class_name: klass.name,
42
58
  name: name,
@@ -50,28 +66,30 @@ module Serde
50
66
  joint_fields_c: fields.map do |field|
51
67
  "#{field[:ctype]} #{field[:name]}"
52
68
  end.join(', '),
69
+ rust_extras: rust_extras,
53
70
  }
54
71
 
55
- mod_template = ERB.new(File.read('./templates/rust/mod.rs'))
72
+ mod_template = ERB.new(File.read(File.expand_path('../../templates/rust/mod.rs', __dir__)))
56
73
  compiled_template = mod_template.result(binding)
57
74
 
58
- File.write("./rust/src/#{name}.rs", compiled_template)
75
+ File.write(File.expand_path("../../rust/src/#{name}.rs", __dir__), compiled_template)
59
76
 
60
- c_template = ERB.new(File.read('./templates/c/serde_rb.c'))
77
+ c_template = ERB.new(File.read(File.expand_path('../../templates/c/serde_rb.c', __dir__)))
61
78
  compiled_template = c_template.result(binding)
62
79
 
63
- File.write('./_target_/serde_rb/serde_rb.c', compiled_template)
80
+ File.write('./serde_rb/serde_rb.c', compiled_template)
64
81
 
65
- lib_template = ERB.new(File.read('./templates/rust/lib.rs'))
82
+ lib_template = ERB.new(File.read(File.expand_path('../../templates/rust/lib.rs', __dir__)))
66
83
  compiled_template = lib_template.result(binding)
67
84
 
68
- File.write("./rust/src/lib.rs", compiled_template)
85
+ File.write(File.expand_path('../../rust/src/lib.rs', __dir__), compiled_template)
69
86
  end
87
+ # rubocop:enable Metrics/MethodLength, Metrics/AbcSize, Metrics/CyclomaticComplexity
70
88
 
71
89
  private
72
90
 
73
91
  def underscore(str)
74
- str.tr('::', '/')
92
+ str.tr('::', '__')
75
93
  .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
76
94
  .gsub(/([a-z\d])([A-Z])/, '\1_\2')
77
95
  .tr('-', '_')
data/lib/serde.rb CHANGED
@@ -1,20 +1,54 @@
1
- require 'fileutils'
1
+ # frozen_string_literal: true
2
+
3
+ require 'tmpdir'
2
4
  require_relative 'serde/serializer_generator.rb'
3
5
 
4
- FileUtils.rm_r(Dir.glob('_target_/*'))
5
- FileUtils.cp_r(Dir.glob('templates/extension/*'), '_target_')
6
+ trace = TracePoint.new(:end) do |tp|
7
+ klass = tp.self
8
+ if Serde::Serializer.descendants.include?(klass)
9
+ klass.compile!
10
+ end
11
+ end
12
+ trace.enable
6
13
 
7
14
  module Serde
8
15
  class Serializer
16
+ @descendants = []
17
+ @compiled = false
18
+
9
19
  class << self
20
+ attr_reader :descendants
21
+
22
+ def inherited(klass)
23
+ @descendants << klass
24
+ end
25
+
10
26
  def schema(**attrs)
11
27
  @schema = attrs
12
- SerializerGenerator.call(self)
13
- Dir.chdir(File.expand_path('../_target_', __dir__)) do
14
- `make`
28
+ end
29
+
30
+ def compile!
31
+ raise 'already compiled' if @compiled
32
+
33
+ Dir.mktmpdir do |dir|
34
+ Dir.chdir(dir) do
35
+ SerializerGenerator.call(dir, self)
36
+
37
+ root_path = File.expand_path('..', __dir__)
38
+ rust_path = File.expand_path('../rust', __dir__)
39
+ bin_path = File.expand_path('../bin', __dir__)
40
+
41
+ # rubocop:disable Metrics/LineLength
42
+ `cd #{rust_path}; #{bin_path}/rustc --edition=2018 --crate-name serde_rb src/lib.rs --crate-type staticlib --crate-type cdylib --emit=dep-info,link -C opt-level=3 -C metadata=aff563bf4af79579 --out-dir /Users/cow/projects/serde/rust/target/release -L dependency=/Users/cow/projects/serde/rust/target/release/deps --extern serde=/Users/cow/projects/serde/rust/target/release/deps/libserde-6a9e4ab445963d7f.rlib --extern serde_derive=/Users/cow/projects/serde/rust/target/release/deps/libserde_derive-20596753c2ed9015.dylib --extern serde_json=/Users/cow/projects/serde/rust/target/release/deps/libserde_json-489658cb61f64325.rlib -L #{root_path}/.rustc/rust-std-beta-x86_64-apple-darwin/rust-std-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/lib`
43
+ # rubocop:enable Metrics/LineLength
44
+ `cp #{rust_path}/target/release/libserde_rb*.a #{dir}/serde_rb/libserde_rb.a`
45
+ `cd #{dir}/serde_rb; ruby extconf.rb; make clean; make`
46
+
47
+ require_relative "#{dir}/serde_rb/serde_rb"
48
+ end
15
49
  end
16
50
 
17
- require_relative '../_target_/serde_rb/serde_rb'
51
+ @compiled = true
18
52
  end
19
53
 
20
54
  def get_schema
data/serde.gemspec CHANGED
@@ -4,17 +4,17 @@ lib = File.expand_path('../lib', __dir__)
4
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
5
 
6
6
  Gem::Specification.new do |spec|
7
- spec.required_ruby_version = '>= 2.5.0'
7
+ spec.required_ruby_version = '>= 2.5.3'
8
8
 
9
- spec.name = 'serde'
10
- spec.version = '0.0.1'
9
+ spec.name = 'serde'
10
+ spec.version = '0.0.2'
11
11
  spec.authors = ['Alexander Komarov']
12
- spec.email = %w[ak@akxcv.com]
12
+ spec.email = %w[ak@akxcv.com]
13
13
 
14
- spec.summary = %q(Fast, compiled serializers for Ruby.)
15
- spec.description = %q(Fast, compiled serializers for Ruby. Powered by serde.rs.)
16
- spec.homepage = 'https://github.com/akxcv/serde.rb'
17
- spec.license = 'MIT'
14
+ spec.summary = 'Fast, compiled serializers for Ruby.'
15
+ spec.description = 'Fast, compiled serializers for Ruby. Powered by serde.rs.'
16
+ spec.homepage = 'https://github.com/akxcv/serde.rb'
17
+ spec.license = 'MIT'
18
18
 
19
19
  spec.require_paths = %w[lib]
20
20
 
@@ -22,8 +22,10 @@ Gem::Specification.new do |spec|
22
22
  f.match(%r{^(test|spec|features)/})
23
23
  end
24
24
 
25
- spec.add_development_dependency 'bundler', '~> 1.17'
26
- spec.add_development_dependency 'pry', '~> 0.12'
27
- spec.add_development_dependency 'rspec', '~> 3.8'
28
- spec.add_development_dependency 'rubocop', '~> 0.60'
25
+ spec.add_development_dependency 'surrealist', '~> 1.3'
26
+ spec.add_development_dependency 'benchmark-ips', '~> 2.7'
27
+ spec.add_development_dependency 'rspec', '~> 3.8'
28
+ spec.add_development_dependency 'armitage-rubocop', '~> 0.12'
29
+ spec.add_development_dependency 'bundler', '~> 1.17'
30
+ spec.add_development_dependency 'pry', '~> 0.12'
29
31
  end
@@ -9,7 +9,11 @@ VALUE c_to_json(VALUE _instance, <%= serializer[:fields].map { |f| "VALUE #{f[:n
9
9
  }
10
10
 
11
11
  void Init_serde_rb(void) {
12
- VALUE klass = rb_const_get(rb_cObject, rb_intern("<%= serializer[:class_name] %>"));
12
+ VALUE klass = rb_eval_string("Object.const_get('<%= serializer[:class_name] %>')");
13
+ /**
14
+ * FIXME: `rb_const_get` doesn't work with nested modules
15
+ */
16
+ // VALUE klass = rb_const_get(rb_cObject, rb_intern("<%= serializer[:class_name] %>"));
13
17
 
14
18
  rb_define_method(klass, "internal_to_json", c_to_json, <%= serializer[:fields].length %>);
15
19
  }
@@ -1,7 +1,5 @@
1
- extern crate serde;
2
- #[macro_use]
3
- extern crate serde_derive;
4
- extern crate serde_json;
1
+ #![allow(non_snake_case)]
2
+
5
3
  use std::os::raw::c_char;
6
4
  use std::ffi::CStr;
7
5
 
@@ -9,13 +7,11 @@ mod <%= serializer[:name] %>;
9
7
 
10
8
  #[no_mangle]
11
9
  pub extern "C" fn serde_rb_rs_<%= serializer[:name] %> (<%= serializer[:joint_fields_rctype] %>) -> *const u8 {
12
- let name = unsafe {
13
- CStr::from_ptr(name).to_string_lossy().into_owned()
14
- };
10
+ <%= serializer[:rust_extras].join("\n") %>
15
11
  let instance = <%= serializer[:name] %>::Struct {
16
12
  <% serializer[:fields].each do |field| %>
17
13
  <%= field[:name] %>,
18
14
  <% end %>
19
15
  };
20
- serde_json::to_string(&instance).unwrap().as_ptr()
16
+ (serde_json::to_string(&instance).unwrap() + "\0").as_ptr()
21
17
  }
@@ -1,3 +1,5 @@
1
+ use serde_derive::Serialize;
2
+
1
3
  #[derive(Serialize)]
2
4
  pub struct Struct {
3
5
  <% fields.each do |field| %>
metadata CHANGED
@@ -1,43 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: serde
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Alexander Komarov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-11-28 00:00:00.000000000 Z
11
+ date: 2018-11-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: bundler
14
+ name: surrealist
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '1.17'
19
+ version: '1.3'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '1.17'
26
+ version: '1.3'
27
27
  - !ruby/object:Gem::Dependency
28
- name: pry
28
+ name: benchmark-ips
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0.12'
33
+ version: '2.7'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0.12'
40
+ version: '2.7'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -53,19 +53,47 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '3.8'
55
55
  - !ruby/object:Gem::Dependency
56
- name: rubocop
56
+ name: armitage-rubocop
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.12'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.12'
69
+ - !ruby/object:Gem::Dependency
70
+ name: bundler
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '1.17'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '1.17'
83
+ - !ruby/object:Gem::Dependency
84
+ name: pry
57
85
  requirement: !ruby/object:Gem::Requirement
58
86
  requirements:
59
87
  - - "~>"
60
88
  - !ruby/object:Gem::Version
61
- version: '0.60'
89
+ version: '0.12'
62
90
  type: :development
63
91
  prerelease: false
64
92
  version_requirements: !ruby/object:Gem::Requirement
65
93
  requirements:
66
94
  - - "~>"
67
95
  - !ruby/object:Gem::Version
68
- version: '0.60'
96
+ version: '0.12'
69
97
  description: Fast, compiled serializers for Ruby. Powered by serde.rs.
70
98
  email:
71
99
  - ak@akxcv.com
@@ -74,13 +102,16 @@ extensions: []
74
102
  extra_rdoc_files: []
75
103
  files:
76
104
  - ".gitignore"
105
+ - ".rubocop.yml"
77
106
  - Gemfile
78
- - Gemfile.lock
79
107
  - LICENSE
80
108
  - README.md
81
- - examples/app/Gemfile
82
- - examples/app/Gemfile.lock
109
+ - Rakefile
110
+ - bench/bench.rb
111
+ - bin/.keep
83
112
  - examples/app/new.rb
113
+ - lib/rubygems_plugin.rb
114
+ - lib/rustc_installer.rb
84
115
  - lib/serde.rb
85
116
  - lib/serde/generate.rb
86
117
  - lib/serde/serializer_generator.rb
@@ -105,7 +136,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
105
136
  requirements:
106
137
  - - ">="
107
138
  - !ruby/object:Gem::Version
108
- version: 2.5.0
139
+ version: 2.5.3
109
140
  required_rubygems_version: !ruby/object:Gem::Requirement
110
141
  requirements:
111
142
  - - ">="
data/Gemfile.lock DELETED
@@ -1,63 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- serde (0.1.0)
5
-
6
- GEM
7
- remote: https://rubygems.org/
8
- specs:
9
- ast (2.4.0)
10
- benchmark-ips (2.7.2)
11
- coderay (1.1.2)
12
- diff-lcs (1.3)
13
- jaro_winkler (1.5.1)
14
- method_source (0.9.2)
15
- oj (3.7.1)
16
- parallel (1.12.1)
17
- parser (2.5.3.0)
18
- ast (~> 2.4.0)
19
- powerpack (0.1.2)
20
- pry (0.12.2)
21
- coderay (~> 1.1.0)
22
- method_source (~> 0.9.0)
23
- rainbow (3.0.0)
24
- rspec (3.8.0)
25
- rspec-core (~> 3.8.0)
26
- rspec-expectations (~> 3.8.0)
27
- rspec-mocks (~> 3.8.0)
28
- rspec-core (3.8.0)
29
- rspec-support (~> 3.8.0)
30
- rspec-expectations (3.8.2)
31
- diff-lcs (>= 1.2.0, < 2.0)
32
- rspec-support (~> 3.8.0)
33
- rspec-mocks (3.8.0)
34
- diff-lcs (>= 1.2.0, < 2.0)
35
- rspec-support (~> 3.8.0)
36
- rspec-support (3.8.0)
37
- rubocop (0.60.0)
38
- jaro_winkler (~> 1.5.1)
39
- parallel (~> 1.10)
40
- parser (>= 2.5, != 2.5.1.1)
41
- powerpack (~> 0.1)
42
- rainbow (>= 2.2.2, < 4.0)
43
- ruby-progressbar (~> 1.7)
44
- unicode-display_width (~> 1.4.0)
45
- ruby-progressbar (1.10.0)
46
- surrealist (1.3.1)
47
- oj (~> 3.0)
48
- unicode-display_width (1.4.0)
49
-
50
- PLATFORMS
51
- ruby
52
-
53
- DEPENDENCIES
54
- benchmark-ips
55
- bundler (~> 1.17)
56
- pry (~> 0.12)
57
- rspec (~> 3.8)
58
- rubocop (~> 0.60)
59
- serde!
60
- surrealist
61
-
62
- BUNDLED WITH
63
- 1.17.1
data/examples/app/Gemfile DELETED
@@ -1 +0,0 @@
1
- gem 'serde', path: '../..'
@@ -1,16 +0,0 @@
1
- PATH
2
- remote: ../..
3
- specs:
4
- serde (0.1.0)
5
-
6
- GEM
7
- specs:
8
-
9
- PLATFORMS
10
- ruby
11
-
12
- DEPENDENCIES
13
- serde!
14
-
15
- BUNDLED WITH
16
- 1.17.1