panko_serializer 0.5.0 → 0.5.1
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/.clang-format +3 -12
- data/benchmarks/setup.rb +2 -11
- data/ext/panko_serializer/attributes_writer/active_record.c +12 -28
- data/ext/panko_serializer/attributes_writer/active_record.h +1 -0
- data/ext/panko_serializer/common.h +8 -0
- data/ext/panko_serializer/panko_serializer.c +14 -13
- data/ext/panko_serializer/serialization_descriptor/attribute.c +1 -1
- data/ext/panko_serializer/serialization_descriptor/attribute.h +4 -0
- data/ext/panko_serializer/serialization_descriptor/serialization_descriptor.c +0 -6
- data/lib/panko/array_serializer.rb +2 -4
- data/lib/panko/serialization_descriptor.rb +2 -2
- data/lib/panko/serializer.rb +22 -7
- data/lib/panko/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3a76c5943a2aa638978b5c044203810bbd993e66a9d18c584149ec0fab559a27
|
4
|
+
data.tar.gz: b7e7337631ba79c9226e5a1e95f2190f2598ca768056b98bf160159ac7b192b4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c366b1a541ccc4575bef00ffacb06fe18693e0018f7f2c08bd6350dba7a39832f58cf1ba69f0bfcdd82e1b6bbd2b28274089382d521e070fb307a2b064ff1e1f
|
7
|
+
data.tar.gz: 02cec8e1f86cae29072071d52c0249400fbf73b6ffaa12a70653b0f6f18754269a31af6534ef36051e49ed3d83c5c61e094d7068c9c53ad6b19a28cfa20537d8
|
data/.clang-format
CHANGED
@@ -81,10 +81,9 @@ MacroBlockBegin: ''
|
|
81
81
|
MacroBlockEnd: ''
|
82
82
|
MaxEmptyLinesToKeep: 1
|
83
83
|
NamespaceIndentation: None
|
84
|
-
ObjCBinPackProtocolList: Never
|
85
84
|
ObjCBlockIndentWidth: 2
|
86
85
|
ObjCSpaceAfterProperty: false
|
87
|
-
ObjCSpaceBeforeProtocolList:
|
86
|
+
ObjCSpaceBeforeProtocolList: false
|
88
87
|
PenaltyBreakAssignment: 2
|
89
88
|
PenaltyBreakBeforeFirstCallParameter: 1
|
90
89
|
PenaltyBreakComment: 300
|
@@ -94,13 +93,8 @@ PenaltyExcessCharacter: 1000000
|
|
94
93
|
PenaltyReturnTypeOnItsOwnLine: 200
|
95
94
|
PointerAlignment: Left
|
96
95
|
RawStringFormats:
|
97
|
-
-
|
98
|
-
|
99
|
-
- pb
|
100
|
-
- PB
|
101
|
-
- proto
|
102
|
-
- PROTO
|
103
|
-
CanonicalDelimiter: ''
|
96
|
+
- Delimiter: pb
|
97
|
+
Language: TextProto
|
104
98
|
BasedOnStyle: google
|
105
99
|
ReflowComments: true
|
106
100
|
SortIncludes: true
|
@@ -108,10 +102,7 @@ SortUsingDeclarations: true
|
|
108
102
|
SpaceAfterCStyleCast: false
|
109
103
|
SpaceAfterTemplateKeyword: true
|
110
104
|
SpaceBeforeAssignmentOperators: true
|
111
|
-
SpaceBeforeCtorInitializerColon: true
|
112
|
-
SpaceBeforeInheritanceColon: true
|
113
105
|
SpaceBeforeParens: ControlStatements
|
114
|
-
SpaceBeforeRangeBasedForLoopColon: true
|
115
106
|
SpaceInEmptyParentheses: false
|
116
107
|
SpacesBeforeTrailingComments: 2
|
117
108
|
SpacesInAngles: false
|
data/benchmarks/setup.rb
CHANGED
@@ -27,14 +27,6 @@ ActiveRecord::Schema.define do
|
|
27
27
|
t.references :author
|
28
28
|
t.timestamps(null: false)
|
29
29
|
end
|
30
|
-
|
31
|
-
create_table :profiles, force: true do |t|
|
32
|
-
t.text :project_url
|
33
|
-
t.text :bio
|
34
|
-
t.date :birthday
|
35
|
-
t.references :author
|
36
|
-
t.timestamps(null: false)
|
37
|
-
end
|
38
30
|
end
|
39
31
|
|
40
32
|
class Author < ActiveRecord::Base
|
@@ -46,9 +38,8 @@ class Post < ActiveRecord::Base
|
|
46
38
|
belongs_to :author
|
47
39
|
end
|
48
40
|
|
49
|
-
|
50
|
-
|
51
|
-
end
|
41
|
+
Post.destroy_all
|
42
|
+
Author.destroy_all
|
52
43
|
|
53
44
|
# Build out the data to serialize
|
54
45
|
Post.transaction do
|
@@ -9,19 +9,15 @@ static ID delegate_hash_id;
|
|
9
9
|
static ID value_before_type_cast_id;
|
10
10
|
static ID type_id;
|
11
11
|
|
12
|
-
VALUE read_attributes(VALUE obj) {
|
13
|
-
return rb_ivar_get(obj, attributes_id);
|
14
|
-
}
|
15
|
-
|
16
12
|
VALUE panko_read_lazy_attributes_hash(VALUE object) {
|
17
13
|
volatile VALUE attributes_set, lazy_attributes_hash;
|
18
14
|
|
19
|
-
attributes_set =
|
20
|
-
if (attributes_set
|
15
|
+
attributes_set = rb_ivar_get(object, attributes_id);
|
16
|
+
if (NIL_P(attributes_set)) {
|
21
17
|
return Qnil;
|
22
18
|
}
|
23
19
|
|
24
|
-
lazy_attributes_hash =
|
20
|
+
lazy_attributes_hash = rb_ivar_get(attributes_set, attributes_id);
|
25
21
|
return lazy_attributes_hash;
|
26
22
|
}
|
27
23
|
|
@@ -34,14 +30,6 @@ void panko_read_types_and_value(VALUE attributes_hash,
|
|
34
30
|
*values = rb_ivar_get(attributes_hash, values_id);
|
35
31
|
}
|
36
32
|
|
37
|
-
bool panko_is_empty_hash(VALUE hash) {
|
38
|
-
if (hash == Qnil || hash == Qundef) {
|
39
|
-
return true;
|
40
|
-
}
|
41
|
-
|
42
|
-
return RHASH_SIZE(hash) == 0;
|
43
|
-
}
|
44
|
-
|
45
33
|
void read_attribute_from_hash(VALUE attributes_hash,
|
46
34
|
VALUE member,
|
47
35
|
volatile VALUE* value,
|
@@ -50,7 +38,7 @@ void read_attribute_from_hash(VALUE attributes_hash,
|
|
50
38
|
if (attribute_metadata != Qnil) {
|
51
39
|
*value = rb_ivar_get(attribute_metadata, value_before_type_cast_id);
|
52
40
|
|
53
|
-
if (*type
|
41
|
+
if (NIL_P(*type)) {
|
54
42
|
*type = rb_ivar_get(attribute_metadata, type_id);
|
55
43
|
}
|
56
44
|
}
|
@@ -80,17 +68,13 @@ struct attributes init_context(VALUE obj) {
|
|
80
68
|
|
81
69
|
volatile VALUE lazy_attribute_hash = panko_read_lazy_attributes_hash(obj);
|
82
70
|
|
83
|
-
if (lazy_attribute_hash == Qnil) {
|
84
|
-
// TODO: handle
|
85
|
-
}
|
86
|
-
|
87
71
|
if (RB_TYPE_P(lazy_attribute_hash, T_HASH)) {
|
88
72
|
attributes_ctx.attributes_hash = lazy_attribute_hash;
|
89
73
|
attributes_ctx.shouldReadFromHash = true;
|
90
74
|
} else {
|
91
75
|
volatile VALUE delegate_hash =
|
92
76
|
rb_ivar_get(lazy_attribute_hash, delegate_hash_id);
|
93
|
-
if (!
|
77
|
+
if (!PANKO_EMPTY_HASH(delegate_hash)) {
|
94
78
|
attributes_ctx.attributes_hash = delegate_hash;
|
95
79
|
attributes_ctx.shouldReadFromHash = true;
|
96
80
|
}
|
@@ -100,7 +84,7 @@ struct attributes init_context(VALUE obj) {
|
|
100
84
|
&attributes_ctx.values);
|
101
85
|
|
102
86
|
attributes_ctx.tryToReadFromAdditionalTypes =
|
103
|
-
!
|
87
|
+
!PANKO_EMPTY_HASH(attributes_ctx.additional_types);
|
104
88
|
}
|
105
89
|
|
106
90
|
return attributes_ctx;
|
@@ -110,9 +94,9 @@ VALUE read_attribute(struct attributes attributes_ctx, Attribute attribute) {
|
|
110
94
|
VALUE member = attribute->name_str;
|
111
95
|
volatile VALUE value = Qundef;
|
112
96
|
|
113
|
-
if (attributes_ctx.values
|
97
|
+
if (!NIL_P(attributes_ctx.values)) {
|
114
98
|
value = rb_hash_aref(attributes_ctx.values, member);
|
115
|
-
if (value
|
99
|
+
if (NIL_P(value)) {
|
116
100
|
value = Qundef;
|
117
101
|
}
|
118
102
|
}
|
@@ -122,17 +106,17 @@ VALUE read_attribute(struct attributes attributes_ctx, Attribute attribute) {
|
|
122
106
|
&attribute->type);
|
123
107
|
}
|
124
108
|
|
125
|
-
if (attribute->type
|
109
|
+
if (NIL_P(attribute->type) && !NIL_P(value)) {
|
126
110
|
if (attributes_ctx.tryToReadFromAdditionalTypes) {
|
127
111
|
attribute->type = rb_hash_aref(attributes_ctx.additional_types, member);
|
128
112
|
}
|
129
113
|
|
130
|
-
if (attributes_ctx.types
|
114
|
+
if (!NIL_P(attributes_ctx.types) && NIL_P(attribute->type)) {
|
131
115
|
attribute->type = rb_hash_aref(attributes_ctx.types, member);
|
132
116
|
}
|
133
117
|
}
|
134
118
|
|
135
|
-
if (attribute->type
|
119
|
+
if (!NIL_P(attribute->type) && !NIL_P(value)) {
|
136
120
|
return type_cast(attribute->type, value);
|
137
121
|
}
|
138
122
|
|
@@ -149,7 +133,7 @@ VALUE active_record_attributes_writer(VALUE obj,
|
|
149
133
|
|
150
134
|
for (i = 0; i < RARRAY_LEN(attributes); i++) {
|
151
135
|
volatile VALUE raw_attribute = RARRAY_AREF(attributes, i);
|
152
|
-
Attribute attribute =
|
136
|
+
Attribute attribute = PANKO_ATTRIBUTE_READ(raw_attribute);
|
153
137
|
attribute_try_invalidate(attribute, record_class);
|
154
138
|
|
155
139
|
volatile VALUE value = read_attribute(attributes_ctx, attribute);
|
@@ -19,23 +19,25 @@ void write_value(VALUE str_writer, VALUE key, VALUE value) {
|
|
19
19
|
void serialize_method_fields(VALUE subject,
|
20
20
|
VALUE str_writer,
|
21
21
|
SerializationDescriptor descriptor) {
|
22
|
-
|
22
|
+
if (RARRAY_LEN(descriptor->method_fields) == 0) {
|
23
|
+
return;
|
24
|
+
}
|
25
|
+
|
26
|
+
volatile VALUE method_fields, serializer;
|
23
27
|
long i;
|
24
28
|
|
25
29
|
method_fields = descriptor->method_fields;
|
26
|
-
if (RARRAY_LEN(method_fields) == 0) {
|
27
|
-
return;
|
28
|
-
}
|
29
30
|
|
30
31
|
serializer = descriptor->serializer;
|
31
32
|
rb_ivar_set(serializer, object_id, subject);
|
32
33
|
|
33
34
|
for (i = 0; i < RARRAY_LEN(method_fields); i++) {
|
34
|
-
volatile VALUE
|
35
|
-
|
36
|
-
|
35
|
+
volatile VALUE raw_attribute = RARRAY_AREF(method_fields, i);
|
36
|
+
Attribute attribute = PANKO_ATTRIBUTE_READ(raw_attribute);
|
37
|
+
|
38
|
+
volatile VALUE result = rb_funcall(serializer, attribute->name_id, 0);
|
37
39
|
|
38
|
-
write_value(str_writer,
|
40
|
+
write_value(str_writer, attribute->name_str, result);
|
39
41
|
}
|
40
42
|
|
41
43
|
rb_ivar_set(serializer, object_id, Qnil);
|
@@ -61,7 +63,7 @@ void serialize_has_one_associations(VALUE subject,
|
|
61
63
|
|
62
64
|
volatile VALUE value = rb_funcall(subject, association->name_id, 0);
|
63
65
|
|
64
|
-
if (value
|
66
|
+
if (NIL_P(value)) {
|
65
67
|
write_value(str_writer, association->name_str, value);
|
66
68
|
} else {
|
67
69
|
serialize_subject(association->name_str, value, str_writer,
|
@@ -81,7 +83,7 @@ void serialize_has_many_associations(VALUE subject,
|
|
81
83
|
|
82
84
|
volatile VALUE value = rb_funcall(subject, association->name_id, 0);
|
83
85
|
|
84
|
-
if (value
|
86
|
+
if (NIL_P(value)) {
|
85
87
|
write_value(str_writer, association->name_str, value);
|
86
88
|
} else {
|
87
89
|
serialize_subjects(association->name_str, value, str_writer,
|
@@ -100,12 +102,12 @@ VALUE serialize_subject(VALUE key,
|
|
100
102
|
|
101
103
|
serialize_fields(subject, str_writer, descriptor);
|
102
104
|
|
103
|
-
if (RARRAY_LEN(descriptor->has_one_associations)
|
105
|
+
if (RARRAY_LEN(descriptor->has_one_associations) > 0) {
|
104
106
|
serialize_has_one_associations(subject, str_writer, descriptor,
|
105
107
|
descriptor->has_one_associations);
|
106
108
|
}
|
107
109
|
|
108
|
-
if (RARRAY_LEN(descriptor->has_many_associations)
|
110
|
+
if (RARRAY_LEN(descriptor->has_many_associations) > 0) {
|
109
111
|
serialize_has_many_associations(subject, str_writer, descriptor,
|
110
112
|
descriptor->has_many_associations);
|
111
113
|
}
|
@@ -163,7 +165,6 @@ void Init_panko_serializer() {
|
|
163
165
|
object_id = rb_intern("@object");
|
164
166
|
serialization_context_id = rb_intern("@serialization_context");
|
165
167
|
|
166
|
-
|
167
168
|
VALUE mPanko = rb_define_module("Panko");
|
168
169
|
|
169
170
|
rb_define_singleton_method(mPanko, "serialize_subject", serialize_subject_api,
|
@@ -59,7 +59,7 @@ void attribute_try_invalidate(Attribute attribute, VALUE new_record_class) {
|
|
59
59
|
volatile VALUE ar_aliases_hash =
|
60
60
|
rb_funcall(new_record_class, attribute_aliases_id, 0);
|
61
61
|
|
62
|
-
if (!
|
62
|
+
if (!PANKO_EMPTY_HASH(ar_aliases_hash)) {
|
63
63
|
volatile VALUE aliasedValue =
|
64
64
|
rb_hash_aref(ar_aliases_hash, attribute->name_str);
|
65
65
|
if (aliasedValue != Qnil) {
|
@@ -3,6 +3,8 @@
|
|
3
3
|
#ifndef __ATTRIBUTE_H__
|
4
4
|
#define __ATTRIBUTE_H__
|
5
5
|
|
6
|
+
#include "../common.h"
|
7
|
+
|
6
8
|
typedef struct _Attribute {
|
7
9
|
VALUE name_str;
|
8
10
|
ID name_id;
|
@@ -20,4 +22,6 @@ Attribute attribute_read(VALUE attribute);
|
|
20
22
|
void attribute_try_invalidate(Attribute attribute, VALUE record);
|
21
23
|
void panko_init_attribute(VALUE mPanko);
|
22
24
|
|
25
|
+
#define PANKO_ATTRIBUTE_READ(attribute) (Attribute)DATA_PTR(attribute)
|
26
|
+
|
23
27
|
#endif
|
@@ -140,12 +140,6 @@ VALUE sd_aliases_aref(VALUE self, VALUE aliases) {
|
|
140
140
|
return sd->aliases;
|
141
141
|
}
|
142
142
|
|
143
|
-
// Exposing this for testing
|
144
|
-
VALUE public_sd_build_serializer(VALUE self) {
|
145
|
-
SerializationDescriptor sd = (SerializationDescriptor)DATA_PTR(self);
|
146
|
-
return sd_build_serializer(sd);
|
147
|
-
}
|
148
|
-
|
149
143
|
void panko_init_serialization_descriptor(VALUE mPanko) {
|
150
144
|
object_id = rb_intern("@object");
|
151
145
|
sc_id = rb_intern("@sc");
|
@@ -22,9 +22,7 @@ Please pass valid each_serializer to ArraySerializer, for example:
|
|
22
22
|
scope: options[:scope]
|
23
23
|
}
|
24
24
|
|
25
|
-
@serialization_context =
|
26
|
-
SerializationContext.new(options[:context], options[:scope])
|
27
|
-
end
|
25
|
+
@serialization_context = SerializationContext.create(options)
|
28
26
|
@descriptor = Panko::SerializationDescriptor.build(@each_serializer, serializer_options, @serialization_context)
|
29
27
|
end
|
30
28
|
|
@@ -43,7 +41,7 @@ Please pass valid each_serializer to ArraySerializer, for example:
|
|
43
41
|
def serialize_to_json(subjects)
|
44
42
|
writer = Oj::StringWriter.new(mode: :rails)
|
45
43
|
Panko.serialize_subjects(subjects.to_a, writer, @descriptor)
|
46
|
-
@descriptor.set_serialization_context(nil)
|
44
|
+
@descriptor.set_serialization_context(nil) unless @serialization_context.is_a?(EmptySerializerContext)
|
47
45
|
writer.to_s
|
48
46
|
end
|
49
47
|
end
|
@@ -39,7 +39,7 @@ module Panko
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def set_serialization_context(context)
|
42
|
-
serializer.
|
42
|
+
serializer.serialization_context = context if !method_fields.empty? && !serializer.nil?
|
43
43
|
|
44
44
|
has_many_associations.each do |assoc|
|
45
45
|
assoc.descriptor.set_serialization_context context
|
@@ -65,7 +65,7 @@ module Panko
|
|
65
65
|
attributes_except_filters
|
66
66
|
)
|
67
67
|
|
68
|
-
self.method_fields =
|
68
|
+
self.method_fields = apply_attribute_filters(
|
69
69
|
method_fields,
|
70
70
|
attributes_only_filters,
|
71
71
|
attributes_except_filters
|
data/lib/panko/serializer.rb
CHANGED
@@ -10,6 +10,24 @@ class SerializationContext
|
|
10
10
|
@context = context
|
11
11
|
@scope = scope
|
12
12
|
end
|
13
|
+
|
14
|
+
def self.create(options)
|
15
|
+
if options.key?(:context) || options.key?(:scope)
|
16
|
+
SerializationContext.new(options[:context], options[:scope])
|
17
|
+
else
|
18
|
+
EmptySerializerContext.new
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class EmptySerializerContext
|
24
|
+
def scope
|
25
|
+
nil
|
26
|
+
end
|
27
|
+
|
28
|
+
def context
|
29
|
+
nil
|
30
|
+
end
|
13
31
|
end
|
14
32
|
|
15
33
|
module Panko
|
@@ -47,7 +65,7 @@ module Panko
|
|
47
65
|
def method_added(method)
|
48
66
|
return if @_descriptor.nil?
|
49
67
|
deleted_attr = @_descriptor.attributes.delete(method)
|
50
|
-
@_descriptor.method_fields << method unless deleted_attr.nil?
|
68
|
+
@_descriptor.method_fields << Attribute.create(method) unless deleted_attr.nil?
|
51
69
|
end
|
52
70
|
|
53
71
|
def has_one(name, options = {})
|
@@ -81,10 +99,7 @@ module Panko
|
|
81
99
|
# this "_skip_init" trick is so I can create serializers from serialization descriptor
|
82
100
|
return if options[:_skip_init]
|
83
101
|
|
84
|
-
@serialization_context =
|
85
|
-
SerializationContext.new(options[:context], options[:scope])
|
86
|
-
end
|
87
|
-
|
102
|
+
@serialization_context = SerializationContext.create(options)
|
88
103
|
@descriptor = Panko::SerializationDescriptor.build(self.class, options, @serialization_context)
|
89
104
|
end
|
90
105
|
|
@@ -96,6 +111,7 @@ module Panko
|
|
96
111
|
@serialization_context.scope
|
97
112
|
end
|
98
113
|
|
114
|
+
attr_writer :serialization_context
|
99
115
|
attr_reader :object
|
100
116
|
|
101
117
|
def serialize(object)
|
@@ -105,8 +121,7 @@ module Panko
|
|
105
121
|
def serialize_to_json(object)
|
106
122
|
writer = Oj::StringWriter.new(mode: :rails)
|
107
123
|
Panko.serialize_subject(object, writer, @descriptor)
|
108
|
-
|
109
|
-
@descriptor.set_serialization_context(nil) if @serialization_context.present?
|
124
|
+
@descriptor.set_serialization_context(nil) unless @serialization_context.is_a?(EmptySerializerContext)
|
110
125
|
writer.to_s
|
111
126
|
end
|
112
127
|
end
|
data/lib/panko/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: panko_serializer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yosi Attias
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-08-
|
11
|
+
date: 2018-08-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: oj
|
@@ -77,6 +77,7 @@ files:
|
|
77
77
|
- ext/panko_serializer/attributes_writer/type_cast/type_cast.h
|
78
78
|
- ext/panko_serializer/attributes_writer/writer.c
|
79
79
|
- ext/panko_serializer/attributes_writer/writer.h
|
80
|
+
- ext/panko_serializer/common.h
|
80
81
|
- ext/panko_serializer/extconf.rb
|
81
82
|
- ext/panko_serializer/panko_serializer.c
|
82
83
|
- ext/panko_serializer/panko_serializer.h
|