surrealist 0.4.0 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +8 -0
- data/CHANGELOG.md +11 -0
- data/Gemfile +2 -0
- data/README.md +358 -152
- data/benchmarks/surrealist_vs_ams.rb +243 -0
- data/lib/surrealist/builder.rb +7 -11
- data/lib/surrealist/carrier.rb +10 -5
- data/lib/surrealist/class_methods.rb +2 -2
- data/lib/surrealist/copier.rb +11 -11
- data/lib/surrealist/exception_raiser.rb +13 -0
- data/lib/surrealist/instance_methods.rb +16 -2
- data/lib/surrealist/schema_definer.rb +51 -12
- data/lib/surrealist/serializer.rb +10 -1
- data/lib/surrealist/string_utils.rb +2 -2
- data/lib/surrealist/type_helper.rb +5 -5
- data/lib/surrealist/value_assigner.rb +13 -13
- data/lib/surrealist/vars_helper.rb +17 -6
- data/lib/surrealist/version.rb +1 -1
- data/lib/surrealist.rb +9 -12
- data/surrealist.gemspec +2 -0
- metadata +17 -2
@@ -10,16 +10,16 @@ module Surrealist
|
|
10
10
|
# @param [Struct] schema containing a single schema key and value
|
11
11
|
#
|
12
12
|
# @return [Hash] schema
|
13
|
-
def assign(instance
|
14
|
-
value = raw_value(instance
|
13
|
+
def assign(schema, instance)
|
14
|
+
value = raw_value(instance, schema)
|
15
15
|
|
16
16
|
# array to track and prevent infinite self references in surrealization
|
17
17
|
@stack ||= []
|
18
18
|
|
19
19
|
if value.respond_to?(:build_schema)
|
20
|
-
yield assign_nested_record(instance
|
20
|
+
yield assign_nested_record(instance, value)
|
21
21
|
elsif value.respond_to?(:each) && !value.empty? && value.all? { |v| Helper.surrealist?(v.class) }
|
22
|
-
yield assign_nested_collection(instance
|
22
|
+
yield assign_nested_collection(instance, value)
|
23
23
|
else
|
24
24
|
yield value
|
25
25
|
end
|
@@ -33,9 +33,9 @@ module Surrealist
|
|
33
33
|
# @param [Struct] schema containing a single schema key and value
|
34
34
|
#
|
35
35
|
# @return [Object] value to be further processed
|
36
|
-
def raw_value(instance
|
36
|
+
def raw_value(instance, schema)
|
37
37
|
value = instance.is_a?(Hash) ? instance[schema.key] : instance.send(schema.key)
|
38
|
-
coerce_value(value, schema
|
38
|
+
coerce_value(value, schema)
|
39
39
|
end
|
40
40
|
|
41
41
|
# Coerces value if type check is passed
|
@@ -46,12 +46,12 @@ module Surrealist
|
|
46
46
|
# @raise +Surrealist::InvalidTypeError+ if type-check failed at some point.
|
47
47
|
#
|
48
48
|
# @return [Object] value to be further processed
|
49
|
-
def coerce_value(value, schema
|
50
|
-
unless TypeHelper.valid_type?(value
|
49
|
+
def coerce_value(value, schema)
|
50
|
+
unless TypeHelper.valid_type?(value, schema.value)
|
51
51
|
raise Surrealist::InvalidTypeError,
|
52
52
|
"Wrong type for key `#{schema.key}`. Expected #{schema.value}, got #{value.class}."
|
53
53
|
end
|
54
|
-
TypeHelper.coerce(
|
54
|
+
TypeHelper.coerce(value, schema.value)
|
55
55
|
end
|
56
56
|
|
57
57
|
# Assists in recursively generating schema for records while preventing infinite self-referencing
|
@@ -60,9 +60,9 @@ module Surrealist
|
|
60
60
|
# @param [Object] value a value that has to be type-checked.
|
61
61
|
#
|
62
62
|
# @return [Array] of schemas
|
63
|
-
def assign_nested_collection(instance
|
63
|
+
def assign_nested_collection(instance, value)
|
64
64
|
return if @stack.include?(value.first.class)
|
65
|
-
@stack
|
65
|
+
@stack.push(instance.class).push(value.first.class)
|
66
66
|
result = Surrealist.surrealize_collection(value, raw: true)
|
67
67
|
@stack.delete(instance.class)
|
68
68
|
result
|
@@ -74,9 +74,9 @@ module Surrealist
|
|
74
74
|
# @param [Object] value a value that has to be type-checked.
|
75
75
|
#
|
76
76
|
# @return [Hash] schema
|
77
|
-
def assign_nested_record(instance
|
77
|
+
def assign_nested_record(instance, value)
|
78
78
|
return if @stack.include?(value.class)
|
79
|
-
@stack
|
79
|
+
@stack.push(instance.class)
|
80
80
|
result = value.build_schema
|
81
81
|
@stack.delete(instance.class)
|
82
82
|
result
|
@@ -9,8 +9,10 @@ module Surrealist
|
|
9
9
|
CLASS_VARIABLE = '@@__surrealist_schema'.freeze
|
10
10
|
# Regexp to resolve ROM structure
|
11
11
|
ROM_REGEXP = /ROM::Struct/o
|
12
|
-
# Instance variable that keeps serializer
|
13
|
-
|
12
|
+
# Instance variable that keeps serializer classes
|
13
|
+
SERIALIZER_CLASSES = '@__surrealist_serializers'.freeze
|
14
|
+
# Tag for default behaviour in multiple serializers
|
15
|
+
DEFAULT_TAG = :default
|
14
16
|
|
15
17
|
class << self
|
16
18
|
# Find the schema
|
@@ -41,18 +43,27 @@ module Surrealist
|
|
41
43
|
# Checks if there is a serializer defined for a given class and returns it
|
42
44
|
#
|
43
45
|
# @param [Class] klass a class to check
|
46
|
+
# @param [Symbol] tag a tag associated with serializer
|
44
47
|
#
|
45
48
|
# @return [Class | nil]
|
46
|
-
def find_serializer(klass)
|
47
|
-
|
49
|
+
def find_serializer(klass, tag: nil)
|
50
|
+
tag ||= DEFAULT_TAG
|
51
|
+
hash = klass.instance_variable_get(SERIALIZER_CLASSES)
|
52
|
+
serializer = hash && hash.fetch(tag.to_sym, nil)
|
53
|
+
Surrealist::ExceptionRaiser.raise_unknown_tag!(tag) if serializer.nil? && tag != DEFAULT_TAG
|
54
|
+
serializer
|
48
55
|
end
|
49
56
|
|
50
57
|
# Sets a serializer for class
|
51
58
|
#
|
52
59
|
# @param [Class] self_class class of object that points to serializer
|
53
60
|
# @param [Class] serializer_class class of serializer
|
54
|
-
|
55
|
-
|
61
|
+
# @param [Symbol] tag a tag associated with serializer
|
62
|
+
def add_serializer(self_class, serializer_class, tag: nil)
|
63
|
+
tag ||= DEFAULT_TAG
|
64
|
+
hash = self_class.instance_variable_get(SERIALIZER_CLASSES) || {}
|
65
|
+
hash[tag.to_sym] = serializer_class
|
66
|
+
self_class.instance_variable_set(SERIALIZER_CLASSES, hash)
|
56
67
|
end
|
57
68
|
|
58
69
|
private
|
data/lib/surrealist/version.rb
CHANGED
data/lib/surrealist.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require '
|
3
|
+
require 'oj'
|
4
4
|
require_relative 'surrealist/any'
|
5
5
|
require_relative 'surrealist/bool'
|
6
6
|
require_relative 'surrealist/builder'
|
@@ -54,13 +54,13 @@ module Surrealist
|
|
54
54
|
# # => "[{\"name\":\"Nikita\",\"age\":23}, {\"name\":\"Alessandro\",\"age\":24}]"
|
55
55
|
# # For more examples see README
|
56
56
|
def surrealize_collection(collection, **args)
|
57
|
-
|
57
|
+
Surrealist::ExceptionRaiser.raise_invalid_collection! unless collection.respond_to?(:each)
|
58
58
|
|
59
59
|
result = collection.map do |object|
|
60
60
|
Helper.surrealist?(object.class) ? __build_schema(object, args) : object
|
61
61
|
end
|
62
62
|
|
63
|
-
args[:raw] ? result :
|
63
|
+
args[:raw] ? result : Oj.dump(result, mode: :compat)
|
64
64
|
end
|
65
65
|
|
66
66
|
# Dumps the object's methods corresponding to the schema
|
@@ -78,7 +78,7 @@ module Surrealist
|
|
78
78
|
# provided in the object's class. Values will be taken from the return values
|
79
79
|
# of appropriate methods from the object.
|
80
80
|
def surrealize(instance:, **args)
|
81
|
-
|
81
|
+
Oj.dump(build_schema(instance: instance, **args), mode: :compat)
|
82
82
|
end
|
83
83
|
|
84
84
|
# Builds hash from schema provided in the object's class and type-checks the values.
|
@@ -126,13 +126,8 @@ module Surrealist
|
|
126
126
|
|
127
127
|
Surrealist::ExceptionRaiser.raise_unknown_schema!(instance) if schema.nil?
|
128
128
|
|
129
|
-
normalized_schema = Surrealist::Copier.deep_copy(
|
130
|
-
|
131
|
-
klass: instance.class.name,
|
132
|
-
carrier: carrier,
|
133
|
-
)
|
134
|
-
|
135
|
-
hash = Builder.new(carrier: carrier, schema: normalized_schema, instance: instance).call
|
129
|
+
normalized_schema = Surrealist::Copier.deep_copy(schema, carrier, instance.class.name)
|
130
|
+
hash = Builder.new(carrier, normalized_schema, instance).call
|
136
131
|
carrier.camelize ? Surrealist::HashUtils.camelize_hash(hash) : hash
|
137
132
|
end
|
138
133
|
|
@@ -148,7 +143,9 @@ module Surrealist
|
|
148
143
|
# provided in the object's class. Values will be taken from the return values
|
149
144
|
# of appropriate methods from the object.
|
150
145
|
def __build_schema(object, **args)
|
151
|
-
|
146
|
+
return args[:serializer].new(object, args[:context].to_h).build_schema(args) if args[:serializer]
|
147
|
+
|
148
|
+
if (serializer = Surrealist::VarsHelper.find_serializer(object.class, tag: args[:for]))
|
152
149
|
serializer.new(object, args[:context].to_h).build_schema(args)
|
153
150
|
else
|
154
151
|
build_schema(instance: object, **args)
|
data/surrealist.gemspec
CHANGED
@@ -24,6 +24,8 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.require_paths = ['lib']
|
25
25
|
spec.required_ruby_version = '>= 2.2.0'
|
26
26
|
|
27
|
+
spec.add_runtime_dependency 'oj', '~> 3'
|
28
|
+
|
27
29
|
spec.add_development_dependency 'bundler', '~> 1.16'
|
28
30
|
spec.add_development_dependency 'pry', '~> 0.11'
|
29
31
|
spec.add_development_dependency 'rake', '~> 12.3'
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: surrealist
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nikita Esaulov
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-02-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: oj
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '3'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '3'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: bundler
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -100,6 +114,7 @@ files:
|
|
100
114
|
- LICENSE.txt
|
101
115
|
- README.md
|
102
116
|
- Rakefile
|
117
|
+
- benchmarks/surrealist_vs_ams.rb
|
103
118
|
- bin/console
|
104
119
|
- gemfiles/activerecord42.gemfile
|
105
120
|
- lib/surrealist.rb
|