sober_swag 0.20.0 → 0.21.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/.github/workflows/benchmark.yml +39 -0
- data/.github/workflows/lint.yml +1 -3
- data/.gitignore +1 -0
- data/CHANGELOG.md +9 -1
- data/Gemfile +4 -0
- data/bench/benchmark.rb +34 -0
- data/bench/benchmarks/basic_field_serializer.rb +21 -0
- data/bench/benchmarks/view_selection.rb +47 -0
- data/docs/serializers.md +1 -1
- data/example/Gemfile +2 -2
- data/example/Gemfile.lock +10 -10
- data/lib/sober_swag/input_object.rb +34 -0
- data/lib/sober_swag/output_object/definition.rb +26 -0
- data/lib/sober_swag/output_object.rb +5 -15
- data/lib/sober_swag/serializer/field_list.rb +5 -3
- data/lib/sober_swag/serializer/hash.rb +53 -0
- data/lib/sober_swag/serializer.rb +1 -0
- data/lib/sober_swag/version.rb +1 -1
- metadata +7 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f9dce6daadaff9f7ddb1530ecf5fa69693454a29f04da849eec9bea8969166bc
|
4
|
+
data.tar.gz: a6cd16e93640b2d9c27fab081c3551d8498643044a6ebf9cab8100b51d8d916d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fb2dcb7bee3b89e643b3e5d2d1e3d5b7034161ae563de59909120a3f4c817a8f14ab88d5d1968efb2b914b068cf0370d41f9094bbec7ae8ef96a87dfe3ad64fd
|
7
|
+
data.tar.gz: bfc9bfe3b4e93dca2a774e416496d430dfa63185acc82db780cc4f26d7eec1ff2a6db0f10103fd962243ab46b9799b8e6536dd94cc07758b5f52ea07af71df67
|
@@ -0,0 +1,39 @@
|
|
1
|
+
name: Ruby Benchmark
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [ master ]
|
6
|
+
pull_request:
|
7
|
+
branches: [ master ]
|
8
|
+
|
9
|
+
jobs:
|
10
|
+
benchmark:
|
11
|
+
|
12
|
+
runs-on: ubuntu-latest
|
13
|
+
strategy:
|
14
|
+
matrix:
|
15
|
+
ruby: [ '2.6', '2.7', '3.0' ]
|
16
|
+
|
17
|
+
steps:
|
18
|
+
- uses: actions/checkout@v2
|
19
|
+
- name: Set up Ruby
|
20
|
+
uses: ruby/setup-ruby@v1
|
21
|
+
with:
|
22
|
+
ruby-version: ${{ matrix.ruby }}
|
23
|
+
- uses: actions/cache@v2
|
24
|
+
with:
|
25
|
+
path: vendor/bundle
|
26
|
+
key: ${{ runner.os }}-${{ matrix.ruby }}-gem-deps-${{ hashFiles('**/Gemfile.lock') }}
|
27
|
+
restore-keys: |
|
28
|
+
${{ runner.os }}-${{ matrix.ruby }}-gem-deps-
|
29
|
+
- name: Install dependencies
|
30
|
+
run: |
|
31
|
+
bundle config path vendor/bundle
|
32
|
+
bundle install
|
33
|
+
- name: Run Benchmark
|
34
|
+
run: bundle exec ruby bench/benchmark.rb
|
35
|
+
- uses: actions/upload-artifact@v2
|
36
|
+
with:
|
37
|
+
name: benchmark-result
|
38
|
+
path: benchmark_results.yaml
|
39
|
+
if-no-files-found: error
|
data/.github/workflows/lint.yml
CHANGED
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,9 +1,17 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [v0.21.0] 2021-09-02
|
4
|
+
|
5
|
+
- Added a new method of serializing views based on hash lookups, improving performance
|
6
|
+
- Added a benchmarking suite
|
7
|
+
- Added `except` parameter to the `merge` method, which allows a specified field to be excluded from the merge.
|
8
|
+
- Add `type_key` to output objects, for easily serializing out type fields with a constant string.
|
9
|
+
- Added `type_attribute` to `SoberSwag::InputObject` to add easy constant-value disambiguation.
|
10
|
+
|
3
11
|
## [v0.20.0] 2021-05-17
|
4
12
|
|
5
13
|
- Added YARD documentation to almost every method
|
6
|
-
|
14
|
+
|
7
15
|
|
8
16
|
## [v0.19.0] 2021-03-10
|
9
17
|
|
data/Gemfile
CHANGED
data/bench/benchmark.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'bundler/setup'
|
2
|
+
|
3
|
+
require 'sober_swag'
|
4
|
+
|
5
|
+
require 'yaml'
|
6
|
+
require 'benchmark/ips'
|
7
|
+
|
8
|
+
##
|
9
|
+
# Quick and dirty way to benchmark things.
|
10
|
+
class Bench
|
11
|
+
class << self
|
12
|
+
def report(name, &block)
|
13
|
+
puts name
|
14
|
+
|
15
|
+
data[name] ||= Benchmark.ips(&block).data
|
16
|
+
end
|
17
|
+
|
18
|
+
def data
|
19
|
+
@data ||= {}
|
20
|
+
end
|
21
|
+
|
22
|
+
def write!(filename)
|
23
|
+
File.open(filename, 'w') do |f|
|
24
|
+
f << YAML.dump(data)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
Dir['bench/benchmarks/**/*.rb'].sort.each do |file|
|
31
|
+
require_relative file.gsub(%r{^bench/}, '')
|
32
|
+
end
|
33
|
+
|
34
|
+
Bench.write!('benchmark_results.yaml')
|
@@ -0,0 +1,21 @@
|
|
1
|
+
##
|
2
|
+
# Bench test for serializing multiple fields.
|
3
|
+
class BasicFieldSerializer
|
4
|
+
Idea = Struct.new(:name, :grade, :cool)
|
5
|
+
|
6
|
+
Output = SoberSwag::OutputObject.define do
|
7
|
+
field :name, primitive(:String)
|
8
|
+
field :grade, primitive(:Integer)
|
9
|
+
field :cool, primitive(:Bool)
|
10
|
+
end
|
11
|
+
|
12
|
+
OutputSerializer = Output.serializer
|
13
|
+
|
14
|
+
MyIdea = Idea.new('Bob', 12, false)
|
15
|
+
|
16
|
+
Bench.report 'Basic Field Serializers' do |bm|
|
17
|
+
bm.report('Output Object') { Output.serialize(MyIdea) }
|
18
|
+
bm.report('Serializer of Output Object') { OutputSerializer.serialize(MyIdea) }
|
19
|
+
bm.compare!
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
##
|
2
|
+
# Benchmark for speed of selecting what view to use.
|
3
|
+
class ViewSelection
|
4
|
+
Accomplishment = Struct.new(:name, :description)
|
5
|
+
Person = Struct.new(:first_name, :last_name, :accomplishments)
|
6
|
+
|
7
|
+
MyPerson = Person.new(
|
8
|
+
'Joeseph',
|
9
|
+
'Biden',
|
10
|
+
[
|
11
|
+
Accomplishment.new('Became President', 'Won a Presidential Election'),
|
12
|
+
Accomplishment.new('Oldest President', 'Oldest man to be elected president at time of election'),
|
13
|
+
Accomplishment.new('Became Senator', 'Got Elected to the Senate'),
|
14
|
+
Accomplishment.new('Youngest Senator', 'Youngest person elected Senator at time of election')
|
15
|
+
]
|
16
|
+
)
|
17
|
+
|
18
|
+
AccomplishmentSerializer = SoberSwag::OutputObject.define do
|
19
|
+
field :name, primitive(:String)
|
20
|
+
|
21
|
+
view :detail do
|
22
|
+
field :description, primitive(:String)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
PersonSerializer = SoberSwag::OutputObject.define do
|
27
|
+
field :first_name, primitive(:String)
|
28
|
+
field :last_name, primitive(:String)
|
29
|
+
|
30
|
+
# make a bunch of dummy views
|
31
|
+
1.upto(10).each { |n| view(:"view_#{n}") {} }
|
32
|
+
|
33
|
+
view :detail do
|
34
|
+
field :accomplishments, AccomplishmentSerializer.view(:detail)
|
35
|
+
end
|
36
|
+
|
37
|
+
1.upto(10).each { |n| view(:"view_after_#{n}") {} }
|
38
|
+
end
|
39
|
+
|
40
|
+
Bench.report 'View Selection' do |bm|
|
41
|
+
bm.report('With no view') { PersonSerializer.serialize(MyPerson) }
|
42
|
+
|
43
|
+
bm.report('With a view') { PersonSerializer.serialize(MyPerson, { view: :detail }) }
|
44
|
+
|
45
|
+
bm.compare!
|
46
|
+
end
|
47
|
+
end
|
data/docs/serializers.md
CHANGED
@@ -105,7 +105,7 @@ This changes the type properly too.
|
|
105
105
|
|
106
106
|
98% of the time, when we're writing web APIs, we want to transform our domain objects into JSON objects.
|
107
107
|
We often want different ways to do this, too.
|
108
|
-
Consider, for
|
108
|
+
Consider, for example, an API for a college.
|
109
109
|
We might want to provide one detailed way to serialize a student, which includes their full name, grade, student ID, GPA, and so on.
|
110
110
|
On another page, we might want to display a classroom with a list of students.
|
111
111
|
However, on the classroom page, we don't want to serialize a full student: that's sending too much data.
|
data/example/Gemfile
CHANGED
@@ -8,7 +8,7 @@ gem 'actionpack', '>= 6.0.3.2'
|
|
8
8
|
# Use sqlite3 as the database for Active Record
|
9
9
|
gem 'sqlite3', '~> 1.4'
|
10
10
|
# Use Puma as the app server
|
11
|
-
gem 'puma', '~> 5.
|
11
|
+
gem 'puma', '~> 5.3'
|
12
12
|
# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder
|
13
13
|
# gem 'jbuilder', '~> 2.7'
|
14
14
|
# Use Active Model has_secure_password
|
@@ -34,7 +34,7 @@ group :development, :test do
|
|
34
34
|
end
|
35
35
|
|
36
36
|
group :development do
|
37
|
-
gem 'listen', '>= 3.0.5', '< 3.
|
37
|
+
gem 'listen', '>= 3.0.5', '< 3.7'
|
38
38
|
# Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring
|
39
39
|
gem 'spring'
|
40
40
|
gem 'spring-watcher-listen', '~> 2.0.0'
|
data/example/Gemfile.lock
CHANGED
@@ -64,7 +64,7 @@ GEM
|
|
64
64
|
minitest (~> 5.1)
|
65
65
|
tzinfo (~> 1.1)
|
66
66
|
zeitwerk (~> 2.2, >= 2.2.2)
|
67
|
-
bootsnap (1.7.
|
67
|
+
bootsnap (1.7.5)
|
68
68
|
msgpack (~> 1.0)
|
69
69
|
builder (3.2.4)
|
70
70
|
byebug (11.1.3)
|
@@ -103,13 +103,13 @@ GEM
|
|
103
103
|
dry-types (>= 0.8.1)
|
104
104
|
rails (>= 3)
|
105
105
|
erubi (1.10.0)
|
106
|
-
ffi (1.15.
|
106
|
+
ffi (1.15.3)
|
107
107
|
globalid (0.4.2)
|
108
108
|
activesupport (>= 4.2.0)
|
109
109
|
i18n (1.8.9)
|
110
110
|
concurrent-ruby (~> 1.0)
|
111
111
|
ice_nine (0.11.2)
|
112
|
-
listen (3.
|
112
|
+
listen (3.6.0)
|
113
113
|
rb-fsevent (~> 0.10, >= 0.10.3)
|
114
114
|
rb-inotify (~> 0.9, >= 0.9.10)
|
115
115
|
loofah (2.9.0)
|
@@ -124,17 +124,17 @@ GEM
|
|
124
124
|
nokogiri (~> 1)
|
125
125
|
rake
|
126
126
|
mini_mime (1.0.2)
|
127
|
-
mini_portile2 (2.5.
|
127
|
+
mini_portile2 (2.5.1)
|
128
128
|
minitest (5.14.4)
|
129
129
|
msgpack (1.4.2)
|
130
130
|
nio4r (2.5.7)
|
131
|
-
nokogiri (1.11.
|
131
|
+
nokogiri (1.11.5)
|
132
132
|
mini_portile2 (~> 2.5.0)
|
133
133
|
racc (~> 1.4)
|
134
|
-
pry (0.14.
|
134
|
+
pry (0.14.1)
|
135
135
|
coderay (~> 1.1)
|
136
136
|
method_source (~> 1.0)
|
137
|
-
puma (5.
|
137
|
+
puma (5.3.2)
|
138
138
|
nio4r (~> 2.0)
|
139
139
|
racc (1.5.2)
|
140
140
|
rack (2.2.3)
|
@@ -167,7 +167,7 @@ GEM
|
|
167
167
|
rake (>= 0.8.7)
|
168
168
|
thor (>= 0.20.3, < 2.0)
|
169
169
|
rake (13.0.3)
|
170
|
-
rb-fsevent (0.
|
170
|
+
rb-fsevent (0.11.0)
|
171
171
|
rb-inotify (0.10.1)
|
172
172
|
ffi (~> 1.0)
|
173
173
|
rspec-core (3.10.1)
|
@@ -216,9 +216,9 @@ DEPENDENCIES
|
|
216
216
|
bootsnap (>= 1.4.2)
|
217
217
|
byebug
|
218
218
|
dry-types-rails
|
219
|
-
listen (>= 3.0.5, < 3.
|
219
|
+
listen (>= 3.0.5, < 3.7)
|
220
220
|
pry
|
221
|
-
puma (~> 5.
|
221
|
+
puma (~> 5.3)
|
222
222
|
rails (~> 6.0.2, >= 6.0.2.2)
|
223
223
|
rspec-rails
|
224
224
|
sober_swag!
|
@@ -46,6 +46,40 @@ module SoberSwag
|
|
46
46
|
super(key, parent, &block)
|
47
47
|
end
|
48
48
|
|
49
|
+
##
|
50
|
+
# Add on an attribute which only ever parses from a constant value.
|
51
|
+
# By default, this attribute will be called `type`, but you can override it with the kwarg.
|
52
|
+
# This is useful in situations where you want to emulate a sum type.
|
53
|
+
# For example, if you want to make an API endpoint that can either accept or reject proposals
|
54
|
+
#
|
55
|
+
# ```ruby
|
56
|
+
#
|
57
|
+
# ApiInputType = SoberSwag.input_object {
|
58
|
+
# identifier 'AcceptProposal'
|
59
|
+
# type_attribute 'accept'
|
60
|
+
# attribute(:message, primitive(:String))
|
61
|
+
# } | SoberSwag.input_object {
|
62
|
+
# identifier 'RejectProposal'
|
63
|
+
# type_attribute 'reject'
|
64
|
+
# attribute(:message, primitive(:String))
|
65
|
+
# }
|
66
|
+
# ```
|
67
|
+
#
|
68
|
+
# Under the hood, this basically looks like:
|
69
|
+
#
|
70
|
+
# ```ruby
|
71
|
+
# type_attribute 'archive'
|
72
|
+
# # is equivalent to
|
73
|
+
#
|
74
|
+
# attribute(:type, SoberSwag::Types::String.enum('archive'))
|
75
|
+
# ```
|
76
|
+
#
|
77
|
+
# @param value [String,Symbol] the value to parse
|
78
|
+
# @param attribute_key [Symbol] what key to use
|
79
|
+
def type_attribute(value, attribute_key: :type)
|
80
|
+
attribute(attribute_key, SoberSwag::Types::String.enum(value.to_s))
|
81
|
+
end
|
82
|
+
|
49
83
|
##
|
50
84
|
# @overload attribute(key, parent = SoberSwag::InputObject, &block)
|
51
85
|
# Defines an optional attribute by defining a sub-object inline.
|
@@ -19,6 +19,32 @@ module SoberSwag
|
|
19
19
|
|
20
20
|
include FieldSyntax
|
21
21
|
|
22
|
+
##
|
23
|
+
# Adds a "type key", which is basically a field that will be
|
24
|
+
# serialized out to a constant value.
|
25
|
+
#
|
26
|
+
# This is useful if you have multiple types you may want to serialize out, and want consumers of your API to distinguish between them.
|
27
|
+
#
|
28
|
+
# By default this will have the key "type" but you can set it with the keyword arg.
|
29
|
+
# ```ruby
|
30
|
+
# type_key('MyObject')
|
31
|
+
# # is equivalent to
|
32
|
+
# field :type, SoberSwag::Serializer::Primitive.new(SoberSwag::Types::String.enum('MyObject')) do |_, _|
|
33
|
+
# 'MyObject'
|
34
|
+
# end
|
35
|
+
# ```
|
36
|
+
# @param str [String, Symbol] the value to serialize (will be converted to a string)
|
37
|
+
# @param
|
38
|
+
def type_key(str, field_name: :type)
|
39
|
+
str = str.to_s
|
40
|
+
field(
|
41
|
+
field_name,
|
42
|
+
SoberSwag::Serializer::Primitive.new(
|
43
|
+
SoberSwag::Types::String.enum(str)
|
44
|
+
)
|
45
|
+
) { |_, _| str }
|
46
|
+
end
|
47
|
+
|
22
48
|
##
|
23
49
|
# Adds a new field to the fields array
|
24
50
|
# @param field [SoberSwag::OutputObject::Field]
|
@@ -37,6 +37,7 @@ module SoberSwag
|
|
37
37
|
# the correct thing, with the name you give it. This works for now, though.
|
38
38
|
#
|
39
39
|
# @return [Class] the serializer generated.
|
40
|
+
# @yieldself [SoberSwag::OutputObject::Definition]
|
40
41
|
def self.define(&block)
|
41
42
|
d = Definition.new.tap do |o|
|
42
43
|
o.instance_eval(&block)
|
@@ -99,23 +100,12 @@ module SoberSwag
|
|
99
100
|
# and {SoberSwag::Serializer::FieldList} to do the actual serialization.
|
100
101
|
#
|
101
102
|
# @todo: optimize view selection to use binary instead of linear search
|
102
|
-
def serializer
|
103
|
+
def serializer
|
103
104
|
@serializer ||=
|
104
105
|
begin
|
105
|
-
views.
|
106
|
-
|
107
|
-
|
108
|
-
proc do |object, options|
|
109
|
-
if options[:view].to_s == view.name.to_s
|
110
|
-
[:left, object]
|
111
|
-
else
|
112
|
-
[:right, object]
|
113
|
-
end
|
114
|
-
end,
|
115
|
-
view_serializer,
|
116
|
-
base
|
117
|
-
)
|
118
|
-
end
|
106
|
+
view_choices = views.map { |view| [view.name.to_s, view.serializer] }.to_h
|
107
|
+
view_choices['base'] = base_serializer
|
108
|
+
SoberSwag::Serializer::Hash.new(view_choices, base, proc { |_, options| options[:view]&.to_s })
|
119
109
|
end
|
120
110
|
end
|
121
111
|
|
@@ -27,9 +27,11 @@ module SoberSwag
|
|
27
27
|
# @param options [Hash] arbitrary options
|
28
28
|
# @return [Hash] serialized object.
|
29
29
|
def serialize(object, options = {})
|
30
|
-
|
31
|
-
|
32
|
-
|
30
|
+
{}.tap do |hash|
|
31
|
+
field_list.each do |field|
|
32
|
+
hash[field.name] = field.serializer.serialize(object, options)
|
33
|
+
end
|
34
|
+
end
|
33
35
|
end
|
34
36
|
|
35
37
|
##
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
3
|
+
module SoberSwag
|
4
|
+
module Serializer
|
5
|
+
##
|
6
|
+
# Serialize via hash lookup.
|
7
|
+
# This is used to speed up serialization of views, but it may be useful elsewhere.
|
8
|
+
#
|
9
|
+
class Hash < Base
|
10
|
+
##
|
11
|
+
# @param choices [Hash<Object => SoberSwag::Serializer::Base>] hash of serializers
|
12
|
+
# that we might use.
|
13
|
+
# @param default [SoberSwag::Serializer::Base] default to use if key not found.
|
14
|
+
# @param key_proc [Proc<Object, Hash>] extract the key we are interested in from the proc.
|
15
|
+
# Will be called with the object to serialize and the options hash.
|
16
|
+
def initialize(choices, default, key_proc)
|
17
|
+
@choices = choices
|
18
|
+
@default = default
|
19
|
+
@key_proc = key_proc
|
20
|
+
end
|
21
|
+
|
22
|
+
attr_reader :choices, :default, :key_proc
|
23
|
+
|
24
|
+
def serialize(object, options = {})
|
25
|
+
key = key_proc.call(object, options)
|
26
|
+
|
27
|
+
choices.fetch(key) { default }.serialize(object, options)
|
28
|
+
end
|
29
|
+
|
30
|
+
##
|
31
|
+
# @return [Set<SoberSwag::Serializer::Base>]
|
32
|
+
def possible_serializers
|
33
|
+
@possible_serializers ||= (choices.values + [default]).to_set
|
34
|
+
end
|
35
|
+
|
36
|
+
def lazy_type?
|
37
|
+
possible_serializers.any?(&:lazy_type?)
|
38
|
+
end
|
39
|
+
|
40
|
+
def finalize_lazy_type!
|
41
|
+
possible_serializers.each(&:finalize_lazy_type!)
|
42
|
+
end
|
43
|
+
|
44
|
+
def lazy_type
|
45
|
+
@lazy_type ||= possible_serializers.map(&:lazy_type).reduce(:|)
|
46
|
+
end
|
47
|
+
|
48
|
+
def type
|
49
|
+
@type ||= possible_serializers.map(&:type).reduce(:|)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -10,6 +10,7 @@ module SoberSwag
|
|
10
10
|
autoload(:Mapped, 'sober_swag/serializer/mapped')
|
11
11
|
autoload(:Optional, 'sober_swag/serializer/optional')
|
12
12
|
autoload(:FieldList, 'sober_swag/serializer/field_list')
|
13
|
+
autoload(:Hash, 'sober_swag/serializer/hash')
|
13
14
|
autoload(:Meta, 'sober_swag/serializer/meta')
|
14
15
|
|
15
16
|
class << self
|
data/lib/sober_swag/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sober_swag
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.21.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Anthony Super
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-09-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -173,6 +173,7 @@ extra_rdoc_files: []
|
|
173
173
|
files:
|
174
174
|
- ".github/config/rubocop_linter_action.yml"
|
175
175
|
- ".github/dependabot.yml"
|
176
|
+
- ".github/workflows/benchmark.yml"
|
176
177
|
- ".github/workflows/lint.yml"
|
177
178
|
- ".github/workflows/ruby.yml"
|
178
179
|
- ".gitignore"
|
@@ -186,6 +187,9 @@ files:
|
|
186
187
|
- LICENSE.txt
|
187
188
|
- README.md
|
188
189
|
- Rakefile
|
190
|
+
- bench/benchmark.rb
|
191
|
+
- bench/benchmarks/basic_field_serializer.rb
|
192
|
+
- bench/benchmarks/view_selection.rb
|
189
193
|
- bin/console
|
190
194
|
- bin/rspec
|
191
195
|
- bin/setup
|
@@ -284,6 +288,7 @@ files:
|
|
284
288
|
- lib/sober_swag/serializer/base.rb
|
285
289
|
- lib/sober_swag/serializer/conditional.rb
|
286
290
|
- lib/sober_swag/serializer/field_list.rb
|
291
|
+
- lib/sober_swag/serializer/hash.rb
|
287
292
|
- lib/sober_swag/serializer/mapped.rb
|
288
293
|
- lib/sober_swag/serializer/meta.rb
|
289
294
|
- lib/sober_swag/serializer/optional.rb
|