shale 1.0.0 → 1.1.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/CHANGELOG.md +12 -0
- data/README.md +98 -2
- data/lib/shale/adapter/nokogiri.rb +1 -1
- data/lib/shale/adapter/ox.rb +2 -1
- data/lib/shale/error.rb +12 -0
- data/lib/shale/mapping/descriptor/dict.rb +10 -1
- data/lib/shale/mapping/dict.rb +4 -3
- data/lib/shale/mapping/dict_base.rb +27 -2
- data/lib/shale/schema/json_generator/base.rb +9 -3
- data/lib/shale/schema/json_generator/collection.rb +17 -2
- data/lib/shale/schema/json_generator/float.rb +6 -1
- data/lib/shale/schema/json_generator/integer.rb +6 -1
- data/lib/shale/schema/json_generator/object.rb +10 -2
- data/lib/shale/schema/json_generator/string.rb +5 -1
- data/lib/shale/schema/json_generator.rb +7 -3
- data/lib/shale/schema/xml_compiler.rb +12 -12
- data/lib/shale/type/complex.rb +11 -0
- data/lib/shale/utils.rb +1 -1
- data/lib/shale/version.rb +1 -1
- data/lib/shale.rb +12 -16
- data/shale.gemspec +3 -1
- metadata +19 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 60a0f059693d5ea371ffca8b475ebb261ee99096509e588d2f1163a96bf8fbc0
|
4
|
+
data.tar.gz: c1af0c61c7d9a93bd601188c50916d4f702228052541adee34456c4d7dac8b9a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 31bd59c352febaf287eda07a79f56e5fe942fd86623f532e48c25ff5e946bb53fc879c3f8bb13121989268057beb4ee740f8aac7b1275dda8b9a2d21a5f75aaf
|
7
|
+
data.tar.gz: 127b46cdeb0960643aa60410597f7ace1815dd19e3845cd0cb7c2ea3d2d44b4326333656bdf96209effcf17daabbc5a70de9f430acd42e21d961e2c356d9be9f
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,15 @@
|
|
1
|
+
## [1.1.0] - 2024-02-17
|
2
|
+
|
3
|
+
### Added
|
4
|
+
- [bkjohnson] Add support for JSON Schema validation keywords (#29)
|
5
|
+
- Add support for Ruby 3.3
|
6
|
+
|
7
|
+
### Changed
|
8
|
+
- Drop support for Ruby 2.6 and Ruby 2.7
|
9
|
+
|
10
|
+
### Fixed
|
11
|
+
- Fix Ox adapter incorrectly handling documents with XML declaration
|
12
|
+
|
1
13
|
## [1.0.0] - 2023-07-15
|
2
14
|
|
3
15
|
### Added
|
data/README.md
CHANGED
@@ -17,7 +17,7 @@ Documentation with interactive examples is available at [Shale website](https://
|
|
17
17
|
|
18
18
|
## Installation
|
19
19
|
|
20
|
-
Shale supports Ruby (MRI)
|
20
|
+
Shale supports Ruby (MRI) 3.0+
|
21
21
|
|
22
22
|
Add this line to your application's Gemfile:
|
23
23
|
|
@@ -353,6 +353,25 @@ person.to_xml
|
|
353
353
|
|
354
354
|
### Converting CSV to object
|
355
355
|
|
356
|
+
To use CSV with Shale you have to set adapter.
|
357
|
+
Shale comes with adapter for [csv](https://github.com/ruby/csv).
|
358
|
+
For details see [Adapters](#adapters) section.
|
359
|
+
|
360
|
+
To set it, first make sure CSV gem is installed:
|
361
|
+
|
362
|
+
```
|
363
|
+
$ gem install csv
|
364
|
+
```
|
365
|
+
|
366
|
+
then setup adapter:
|
367
|
+
|
368
|
+
```ruby
|
369
|
+
require 'shale/adapter/csv'
|
370
|
+
Shale.csv_adapter = Shale::Adapter::CSV
|
371
|
+
```
|
372
|
+
|
373
|
+
Now you can use CSV with Shale.
|
374
|
+
|
356
375
|
CSV represents a flat data structure, so you can't map properties to complex types directly,
|
357
376
|
but you can use methods to map properties to complex types
|
358
377
|
(see [Using methods to extract and generate data](#using-methods-to-extract-and-generate-data)
|
@@ -1155,7 +1174,7 @@ end
|
|
1155
1174
|
### Adapters
|
1156
1175
|
|
1157
1176
|
Shale uses adapters for parsing and generating documents.
|
1158
|
-
By default Ruby's standard JSON
|
1177
|
+
By default Ruby's standard JSON and YAML parsers are used for handling JSON and YAML documents.
|
1159
1178
|
|
1160
1179
|
You can change it by providing your own adapter. For JSON, YAML, TOML and CSV adapter must
|
1161
1180
|
implement `.load` and `.dump` class methods.
|
@@ -1183,6 +1202,14 @@ require 'shale/adapter/toml_rb'
|
|
1183
1202
|
Shale.toml_adapter = Shale::Adapter::TomlRB
|
1184
1203
|
```
|
1185
1204
|
|
1205
|
+
To handle CSV documents you have to set CSV adapter. Shale provides adapter for `csv` parser:
|
1206
|
+
|
1207
|
+
```ruby
|
1208
|
+
require 'shale'
|
1209
|
+
require 'shale/adapter/csv'
|
1210
|
+
Shale.csv_adapter = Shale::Adapter::CSV
|
1211
|
+
```
|
1212
|
+
|
1186
1213
|
To handle XML documents you have to explicitly set XML adapter.
|
1187
1214
|
Shale provides adapters for most popular Ruby XML parsers:
|
1188
1215
|
|
@@ -1288,6 +1315,75 @@ end
|
|
1288
1315
|
Shale::Schema::JSONGenerator.register_json_type(MyEmailType, MyEmailJSONType)
|
1289
1316
|
```
|
1290
1317
|
|
1318
|
+
To add validation keywords to the schema, you can use a custom model and do this:
|
1319
|
+
|
1320
|
+
```ruby
|
1321
|
+
require 'shale/schema'
|
1322
|
+
|
1323
|
+
class PersonMapper < Shale::Mapper
|
1324
|
+
model Person
|
1325
|
+
|
1326
|
+
attribute :first_name, Shale::Type::String
|
1327
|
+
attribute :last_name, Shale::Type::String
|
1328
|
+
attribute :address, Shale::Type::String
|
1329
|
+
attribute :age, Shale::Type::Integer
|
1330
|
+
|
1331
|
+
json do
|
1332
|
+
properties max_properties: 5
|
1333
|
+
|
1334
|
+
map "first_name", to: :first_name, schema: { required: true }
|
1335
|
+
map "last_name", to: :last_name, schema: { required: true }
|
1336
|
+
map "address", to: :age, schema: { max_length: 128 }
|
1337
|
+
map "age", to: :age, schema: { minimum: 1, maximum: 150 }
|
1338
|
+
end
|
1339
|
+
end
|
1340
|
+
|
1341
|
+
Shale::Schema.to_json(
|
1342
|
+
PersonMapper,
|
1343
|
+
pretty: true
|
1344
|
+
)
|
1345
|
+
|
1346
|
+
# =>
|
1347
|
+
#
|
1348
|
+
# {
|
1349
|
+
# "$schema": "https://json-schema.org/draft/2020-12/schema",
|
1350
|
+
# "description": "My description",
|
1351
|
+
# "$ref": "#/$defs/Person",
|
1352
|
+
# "$defs": {
|
1353
|
+
# "Person": {
|
1354
|
+
# "type": "object",
|
1355
|
+
# "maxProperties": 5,
|
1356
|
+
# "properties": {
|
1357
|
+
# "first_name": {
|
1358
|
+
# "type": "string"
|
1359
|
+
# },
|
1360
|
+
# "last_name": {
|
1361
|
+
# "type": "string"
|
1362
|
+
# },
|
1363
|
+
# "age": {
|
1364
|
+
# "type": [
|
1365
|
+
# "integer",
|
1366
|
+
# "null"
|
1367
|
+
# ],
|
1368
|
+
# "minimum": 1,
|
1369
|
+
# "maximum": 150
|
1370
|
+
# },
|
1371
|
+
# "address": {
|
1372
|
+
# "type": [
|
1373
|
+
# "string",
|
1374
|
+
# "null"
|
1375
|
+
# ],
|
1376
|
+
# "maxLength": 128
|
1377
|
+
# }
|
1378
|
+
# },
|
1379
|
+
# "required": ["first_name", "last_name"]
|
1380
|
+
# }
|
1381
|
+
# }
|
1382
|
+
# }
|
1383
|
+
```
|
1384
|
+
|
1385
|
+
Validation keywords are supported for all types, only the global `enum` and `const` types are not supported.
|
1386
|
+
|
1291
1387
|
### Compiling JSON Schema into Shale model
|
1292
1388
|
|
1293
1389
|
:warning: Only **[Draft 2020-12](https://json-schema.org/draft/2020-12/schema)** JSON Schema is supported
|
data/lib/shale/adapter/ox.rb
CHANGED
@@ -22,7 +22,8 @@ module Shale
|
|
22
22
|
#
|
23
23
|
# @api private
|
24
24
|
def self.load(xml)
|
25
|
-
|
25
|
+
element = ::Ox.parse(xml)
|
26
|
+
Node.new(element.respond_to?(:root) ? element.root : element)
|
26
27
|
rescue ::Ox::ParseError => e
|
27
28
|
raise ParseError, "Document is invalid: #{e.message}"
|
28
29
|
end
|
data/lib/shale/error.rb
CHANGED
@@ -38,6 +38,18 @@ module Shale
|
|
38
38
|
Shale.xml_adapter = Shale::Adapter::Ox
|
39
39
|
MSG
|
40
40
|
|
41
|
+
# Error message displayed when CSV adapter is not set
|
42
|
+
# @api private
|
43
|
+
CSV_ADAPTER_NOT_SET_MESSAGE = <<~MSG
|
44
|
+
CSV Adapter is not set.
|
45
|
+
To use Shale with CSV documents you have to install parser and set adapter.
|
46
|
+
|
47
|
+
# To use csv gem:
|
48
|
+
# Make sure csv is installed eg. execute: gem install csv
|
49
|
+
require 'shale/adapter/csv'
|
50
|
+
Shale.csv_adapter = Shale::Adapter::CSV
|
51
|
+
MSG
|
52
|
+
|
41
53
|
# Error for assigning value to not existing attribute
|
42
54
|
#
|
43
55
|
# @api private
|
@@ -49,6 +49,13 @@ module Shale
|
|
49
49
|
# @api private
|
50
50
|
attr_reader :group
|
51
51
|
|
52
|
+
# Return schema hash
|
53
|
+
#
|
54
|
+
# @return [Hash]
|
55
|
+
#
|
56
|
+
# @api private
|
57
|
+
attr_reader :schema
|
58
|
+
|
52
59
|
# Initialize instance
|
53
60
|
#
|
54
61
|
# @param [String] name
|
@@ -57,14 +64,16 @@ module Shale
|
|
57
64
|
# @param [Hash, nil] methods
|
58
65
|
# @param [String, nil] group
|
59
66
|
# @param [true, false] render_nil
|
67
|
+
# @param [Hash, nil] schema
|
60
68
|
#
|
61
69
|
# @api private
|
62
|
-
def initialize(name:, attribute:, receiver:, methods:, group:, render_nil:)
|
70
|
+
def initialize(name:, attribute:, receiver:, methods:, group:, render_nil:, schema: nil)
|
63
71
|
@name = name
|
64
72
|
@attribute = attribute
|
65
73
|
@receiver = receiver
|
66
74
|
@group = group
|
67
75
|
@render_nil = render_nil
|
76
|
+
@schema = schema
|
68
77
|
|
69
78
|
if methods
|
70
79
|
@method_from = methods[:from]
|
data/lib/shale/mapping/dict.rb
CHANGED
@@ -16,12 +16,13 @@ module Shale
|
|
16
16
|
# @param [Symbol, nil] receiver
|
17
17
|
# @param [Hash, nil] using
|
18
18
|
# @param [true, false, nil] render_nil
|
19
|
+
# @param [Hash, nil] schema
|
19
20
|
#
|
20
21
|
# @raise [IncorrectMappingArgumentsError] when arguments are incorrect
|
21
22
|
#
|
22
|
-
# @api
|
23
|
-
def map(key, to: nil, receiver: nil, using: nil, render_nil: nil)
|
24
|
-
super(key, to: to, receiver: receiver, using: using, render_nil: render_nil)
|
23
|
+
# @api public
|
24
|
+
def map(key, to: nil, receiver: nil, using: nil, render_nil: nil, schema: nil)
|
25
|
+
super(key, to: to, receiver: receiver, using: using, render_nil: render_nil, schema: schema)
|
25
26
|
end
|
26
27
|
|
27
28
|
# Set render_nil default
|
@@ -16,6 +16,13 @@ module Shale
|
|
16
16
|
# @api private
|
17
17
|
attr_reader :keys
|
18
18
|
|
19
|
+
# Return hash for hash with properties for root Object
|
20
|
+
#
|
21
|
+
# @return [Hash]
|
22
|
+
#
|
23
|
+
# @api private
|
24
|
+
attr_reader :root
|
25
|
+
|
19
26
|
# Initialize instance
|
20
27
|
#
|
21
28
|
# @param [true, false] render_nil_default
|
@@ -23,6 +30,7 @@ module Shale
|
|
23
30
|
# @api private
|
24
31
|
def initialize(render_nil_default: false)
|
25
32
|
@keys = {}
|
33
|
+
@root = {}
|
26
34
|
@finalized = false
|
27
35
|
@render_nil_default = render_nil_default
|
28
36
|
end
|
@@ -35,11 +43,12 @@ module Shale
|
|
35
43
|
# @param [Hash, nil] using
|
36
44
|
# @param [String, nil] group
|
37
45
|
# @param [true, false, nil] render_nil
|
46
|
+
# @param [Hash, nil] schema
|
38
47
|
#
|
39
48
|
# @raise [IncorrectMappingArgumentsError] when arguments are incorrect
|
40
49
|
#
|
41
50
|
# @api private
|
42
|
-
def map(key, to: nil, receiver: nil, using: nil, group: nil, render_nil: nil)
|
51
|
+
def map(key, to: nil, receiver: nil, using: nil, group: nil, render_nil: nil, schema: nil)
|
43
52
|
Validator.validate_arguments(key, to, receiver, using)
|
44
53
|
|
45
54
|
@keys[key] = Descriptor::Dict.new(
|
@@ -48,10 +57,26 @@ module Shale
|
|
48
57
|
receiver: receiver,
|
49
58
|
methods: using,
|
50
59
|
group: group,
|
51
|
-
render_nil: render_nil.nil? ? @render_nil_default : render_nil
|
60
|
+
render_nil: render_nil.nil? ? @render_nil_default : render_nil,
|
61
|
+
schema: schema
|
52
62
|
)
|
53
63
|
end
|
54
64
|
|
65
|
+
# Allow schema properties to be set on the object
|
66
|
+
#
|
67
|
+
# @param [Integer] min_properties
|
68
|
+
# @param [Integer] max_properties
|
69
|
+
# @param [Hash] dependent_required
|
70
|
+
#
|
71
|
+
# @api public
|
72
|
+
def properties(min_properties: nil, max_properties: nil, dependent_required: nil)
|
73
|
+
@root = {
|
74
|
+
min_properties: min_properties,
|
75
|
+
max_properties: max_properties,
|
76
|
+
dependent_required: dependent_required,
|
77
|
+
}
|
78
|
+
end
|
79
|
+
|
55
80
|
# Set the "finalized" instance variable to true
|
56
81
|
#
|
57
82
|
# @api private
|
@@ -12,15 +12,21 @@ module Shale
|
|
12
12
|
# @api private
|
13
13
|
attr_reader :name
|
14
14
|
|
15
|
-
# Return
|
15
|
+
# Return schema hash
|
16
|
+
#
|
17
|
+
# @api private
|
18
|
+
attr_reader :schema
|
19
|
+
|
20
|
+
# Set nullable
|
16
21
|
#
|
17
22
|
# @api private
|
18
23
|
attr_writer :nullable
|
19
24
|
|
20
|
-
def initialize(name, default: nil)
|
25
|
+
def initialize(name, default: nil, schema: nil)
|
21
26
|
@name = name.gsub('::', '_')
|
22
27
|
@default = default
|
23
|
-
@
|
28
|
+
@schema = schema || {}
|
29
|
+
@nullable = !schema&.[](:required)
|
24
30
|
end
|
25
31
|
|
26
32
|
# Return JSON Schema fragment as Ruby Hash
|
@@ -7,13 +7,20 @@ module Shale
|
|
7
7
|
#
|
8
8
|
# @api private
|
9
9
|
class Collection
|
10
|
+
# Return schema hash
|
11
|
+
#
|
12
|
+
# @api private
|
13
|
+
attr_reader :schema
|
14
|
+
|
10
15
|
# Initialize Collection object
|
11
16
|
#
|
12
17
|
# @param [Shale::Schema::JSONGenerator::Base] type
|
18
|
+
# @param [Hash] schema
|
13
19
|
#
|
14
20
|
# @api private
|
15
|
-
def initialize(type)
|
21
|
+
def initialize(type, schema: nil)
|
16
22
|
@type = type
|
23
|
+
@schema = schema
|
17
24
|
end
|
18
25
|
|
19
26
|
# Delegate name to wrapped type object
|
@@ -31,7 +38,15 @@ module Shale
|
|
31
38
|
#
|
32
39
|
# @api private
|
33
40
|
def as_json
|
34
|
-
|
41
|
+
schema = @schema || {}
|
42
|
+
|
43
|
+
{ 'type' => 'array',
|
44
|
+
'items' => @type.as_type,
|
45
|
+
'minItems' => schema[:min_items],
|
46
|
+
'maxItems' => schema[:max_items],
|
47
|
+
'uniqueItems' => schema[:unique],
|
48
|
+
'minContains' => schema[:min_contains],
|
49
|
+
'maxContains' => schema[:max_contains] }.compact
|
35
50
|
end
|
36
51
|
end
|
37
52
|
end
|
@@ -15,7 +15,12 @@ module Shale
|
|
15
15
|
#
|
16
16
|
# @api private
|
17
17
|
def as_type
|
18
|
-
{ 'type' => 'number'
|
18
|
+
{ 'type' => 'number',
|
19
|
+
'exclusiveMinimum' => schema[:exclusive_minimum],
|
20
|
+
'exclusiveMaximum' => schema[:exclusive_maximum],
|
21
|
+
'minimum' => schema[:minimum],
|
22
|
+
'maximum' => schema[:maximum],
|
23
|
+
'multipleOf' => schema[:multiple_of] }.compact
|
19
24
|
end
|
20
25
|
end
|
21
26
|
end
|
@@ -15,7 +15,12 @@ module Shale
|
|
15
15
|
#
|
16
16
|
# @api private
|
17
17
|
def as_type
|
18
|
-
{ 'type' => 'integer'
|
18
|
+
{ 'type' => 'integer',
|
19
|
+
'exclusiveMinimum' => schema[:exclusive_minimum],
|
20
|
+
'exclusiveMaximum' => schema[:exclusive_maximum],
|
21
|
+
'minimum' => schema[:minimum],
|
22
|
+
'maximum' => schema[:maximum],
|
23
|
+
'multipleOf' => schema[:multiple_of] }.compact
|
19
24
|
end
|
20
25
|
end
|
21
26
|
end
|
@@ -16,10 +16,12 @@ module Shale
|
|
16
16
|
# Array<Shale::Schema::JSONGenerator::Base,
|
17
17
|
# Shale::Schema::JSONGenerator::Collection>
|
18
18
|
# ] properties
|
19
|
+
# @param [Hash] root
|
19
20
|
#
|
20
21
|
# @api private
|
21
|
-
def initialize(name, properties)
|
22
|
+
def initialize(name, properties, root)
|
22
23
|
super(name)
|
24
|
+
@root = root
|
23
25
|
@properties = properties
|
24
26
|
end
|
25
27
|
|
@@ -29,10 +31,16 @@ module Shale
|
|
29
31
|
#
|
30
32
|
# @api private
|
31
33
|
def as_type
|
34
|
+
required_props = @properties.filter_map { |prop| prop.name if prop&.schema&.[](:required) }
|
35
|
+
|
32
36
|
{
|
33
37
|
'type' => 'object',
|
34
38
|
'properties' => @properties.to_h { |el| [el.name, el.as_json] },
|
35
|
-
|
39
|
+
'required' => required_props.empty? ? nil : required_props,
|
40
|
+
'minProperties' => @root[:min_properties],
|
41
|
+
'maxProperties' => @root[:max_properties],
|
42
|
+
'dependentRequired' => @root[:dependent_required],
|
43
|
+
}.compact
|
36
44
|
end
|
37
45
|
end
|
38
46
|
end
|
@@ -15,7 +15,11 @@ module Shale
|
|
15
15
|
#
|
16
16
|
# @api private
|
17
17
|
def as_type
|
18
|
-
{ 'type' => 'string'
|
18
|
+
{ 'type' => 'string',
|
19
|
+
'format' => schema[:format],
|
20
|
+
'minLength' => schema[:min_length],
|
21
|
+
'maxLength' => schema[:max_length],
|
22
|
+
'pattern' => schema[:pattern] }.compact
|
19
23
|
end
|
20
24
|
end
|
21
25
|
end
|
@@ -96,14 +96,18 @@ module Shale
|
|
96
96
|
default = attribute.type.as_json(value)
|
97
97
|
end
|
98
98
|
|
99
|
-
json_type = json_klass.new(
|
99
|
+
json_type = json_klass.new(
|
100
|
+
mapping.name,
|
101
|
+
default: default,
|
102
|
+
schema: mapping.schema
|
103
|
+
)
|
100
104
|
end
|
101
105
|
|
102
|
-
json_type = Collection.new(json_type) if attribute.collection?
|
106
|
+
json_type = Collection.new(json_type, schema: mapping.schema) if attribute.collection?
|
103
107
|
properties << json_type
|
104
108
|
end
|
105
109
|
|
106
|
-
objects << Object.new(type.model.name, properties)
|
110
|
+
objects << Object.new(type.model.name, properties, type.json_mapping.root)
|
107
111
|
end
|
108
112
|
|
109
113
|
Schema.new(objects, id: id, title: title, description: description).as_json
|
@@ -34,51 +34,51 @@ module Shale
|
|
34
34
|
|
35
35
|
# XML Schema "schema" element name
|
36
36
|
# @api private
|
37
|
-
XS_SCHEMA = "#{XS_NAMESPACE_URI}:schema"
|
37
|
+
XS_SCHEMA = "#{XS_NAMESPACE_URI}:schema".freeze
|
38
38
|
|
39
39
|
# XML Schema "element" element name
|
40
40
|
# @api private
|
41
|
-
XS_ELEMENT = "#{XS_NAMESPACE_URI}:element"
|
41
|
+
XS_ELEMENT = "#{XS_NAMESPACE_URI}:element".freeze
|
42
42
|
|
43
43
|
# XML Schema "attribute" element name
|
44
44
|
# @api private
|
45
|
-
XS_ATTRIBUTE = "#{XS_NAMESPACE_URI}:attribute"
|
45
|
+
XS_ATTRIBUTE = "#{XS_NAMESPACE_URI}:attribute".freeze
|
46
46
|
|
47
47
|
# XML Schema "attribute" element name
|
48
48
|
# @api private
|
49
|
-
XS_SIMPLE_TYPE = "#{XS_NAMESPACE_URI}:simpleType"
|
49
|
+
XS_SIMPLE_TYPE = "#{XS_NAMESPACE_URI}:simpleType".freeze
|
50
50
|
|
51
51
|
# XML Schema "simpleContent" element name
|
52
52
|
# @api private
|
53
|
-
XS_SIMPLE_CONTENT = "#{XS_NAMESPACE_URI}:simpleContent"
|
53
|
+
XS_SIMPLE_CONTENT = "#{XS_NAMESPACE_URI}:simpleContent".freeze
|
54
54
|
|
55
55
|
# XML Schema "restriction" element name
|
56
56
|
# @api private
|
57
|
-
XS_RESTRICTION = "#{XS_NAMESPACE_URI}:restriction"
|
57
|
+
XS_RESTRICTION = "#{XS_NAMESPACE_URI}:restriction".freeze
|
58
58
|
|
59
59
|
# XML Schema "group" element name
|
60
60
|
# @api private
|
61
|
-
XS_GROUP = "#{XS_NAMESPACE_URI}:group"
|
61
|
+
XS_GROUP = "#{XS_NAMESPACE_URI}:group".freeze
|
62
62
|
|
63
63
|
# XML Schema "attributeGroup" element name
|
64
64
|
# @api private
|
65
|
-
XS_ATTRIBUTE_GROUP = "#{XS_NAMESPACE_URI}:attributeGroup"
|
65
|
+
XS_ATTRIBUTE_GROUP = "#{XS_NAMESPACE_URI}:attributeGroup".freeze
|
66
66
|
|
67
67
|
# XML Schema "complexType" element name
|
68
68
|
# @api private
|
69
|
-
XS_COMPLEX_TYPE = "#{XS_NAMESPACE_URI}:complexType"
|
69
|
+
XS_COMPLEX_TYPE = "#{XS_NAMESPACE_URI}:complexType".freeze
|
70
70
|
|
71
71
|
# XML Schema "complexContent" element name
|
72
72
|
# @api private
|
73
|
-
XS_COMPLEX_CONTENT = "#{XS_NAMESPACE_URI}:complexContent"
|
73
|
+
XS_COMPLEX_CONTENT = "#{XS_NAMESPACE_URI}:complexContent".freeze
|
74
74
|
|
75
75
|
# XML Schema "extension" element name
|
76
76
|
# @api private
|
77
|
-
XS_EXTENSION = "#{XS_NAMESPACE_URI}:extension"
|
77
|
+
XS_EXTENSION = "#{XS_NAMESPACE_URI}:extension".freeze
|
78
78
|
|
79
79
|
# XML Schema "anyType" type
|
80
80
|
# @api private
|
81
|
-
XS_TYPE_ANY = "#{XS_NAMESPACE_URI}:anyType"
|
81
|
+
XS_TYPE_ANY = "#{XS_NAMESPACE_URI}:anyType".freeze
|
82
82
|
|
83
83
|
# XML Schema "date" types
|
84
84
|
# @api private
|
data/lib/shale/type/complex.rb
CHANGED
@@ -373,6 +373,7 @@ module Shale
|
|
373
373
|
#
|
374
374
|
# @api public
|
375
375
|
def from_csv(csv, only: nil, except: nil, context: nil, headers: false, **csv_options)
|
376
|
+
validate_csv_adapter
|
376
377
|
data = Shale.csv_adapter.load(csv, **csv_options.merge(headers: csv_mapping.keys.keys))
|
377
378
|
|
378
379
|
data.shift if headers
|
@@ -398,6 +399,7 @@ module Shale
|
|
398
399
|
#
|
399
400
|
# @api public
|
400
401
|
def to_csv(instance, only: nil, except: nil, context: nil, headers: false, **csv_options)
|
402
|
+
validate_csv_adapter
|
401
403
|
data = as_csv([*instance], only: only, except: except, context: context)
|
402
404
|
|
403
405
|
cols = csv_mapping.keys.values
|
@@ -892,6 +894,15 @@ module Shale
|
|
892
894
|
raise AdapterError, XML_ADAPTER_NOT_SET_MESSAGE unless Shale.xml_adapter
|
893
895
|
end
|
894
896
|
|
897
|
+
# Validate CSV adapter
|
898
|
+
#
|
899
|
+
# @raise [AdapterError]
|
900
|
+
#
|
901
|
+
# @api private
|
902
|
+
def validate_csv_adapter
|
903
|
+
raise AdapterError, CSV_ADAPTER_NOT_SET_MESSAGE unless Shale.csv_adapter
|
904
|
+
end
|
905
|
+
|
895
906
|
# Convert array with attributes to a hash
|
896
907
|
#
|
897
908
|
# @param [Array] ary
|
data/lib/shale/utils.rb
CHANGED
@@ -31,7 +31,7 @@ module Shale
|
|
31
31
|
# @api private
|
32
32
|
def self.classify(str)
|
33
33
|
# names may include a period, which will need to be stripped out
|
34
|
-
str = str.to_s.gsub(
|
34
|
+
str = str.to_s.gsub('.', '')
|
35
35
|
|
36
36
|
str = str.sub(/^[a-z\d]*/) { |match| upcase_first(match) || match }
|
37
37
|
|
data/lib/shale/version.rb
CHANGED
data/lib/shale.rb
CHANGED
@@ -3,7 +3,6 @@
|
|
3
3
|
require 'yaml'
|
4
4
|
|
5
5
|
require_relative 'shale/mapper'
|
6
|
-
require_relative 'shale/adapter/csv'
|
7
6
|
require_relative 'shale/adapter/json'
|
8
7
|
require_relative 'shale/type/boolean'
|
9
8
|
require_relative 'shale/type/date'
|
@@ -52,6 +51,12 @@ require_relative 'shale/version'
|
|
52
51
|
# Shale.xml_adapter = Shale::Adapter::Ox
|
53
52
|
# Shale.xml_adapter # => Shale::Adapter::Ox
|
54
53
|
#
|
54
|
+
# @example setting CSV adapter for handling CSV documents
|
55
|
+
# require 'shale/adapter/csv'
|
56
|
+
#
|
57
|
+
# Shale.csv_adapter = Shale::Adapter::CSV
|
58
|
+
# Shale.csv_adapter # => Shale::Adapter::CSV
|
59
|
+
#
|
55
60
|
# @api public
|
56
61
|
module Shale
|
57
62
|
class << self
|
@@ -93,11 +98,15 @@ module Shale
|
|
93
98
|
#
|
94
99
|
# @param [.load, .dump] adapter
|
95
100
|
#
|
96
|
-
# @example
|
101
|
+
# @example setting adapter
|
97
102
|
# Shale.csv_adapter = Shale::Adapter::CSV
|
98
103
|
#
|
104
|
+
# @example getting adapter
|
105
|
+
# Shale.csv_adapter
|
106
|
+
# # => Shale::Adapter::CSV
|
107
|
+
#
|
99
108
|
# @api public
|
100
|
-
|
109
|
+
attr_accessor :csv_adapter
|
101
110
|
|
102
111
|
# XML adapter accessor. Available adapters are Shale::Adapter::REXML,
|
103
112
|
# Shale::Adapter::Nokogiri and Shale::Adapter::Ox
|
@@ -139,18 +148,5 @@ module Shale
|
|
139
148
|
def yaml_adapter
|
140
149
|
@yaml_adapter || YAML
|
141
150
|
end
|
142
|
-
|
143
|
-
# Return CSV adapter. By default CSV is used
|
144
|
-
#
|
145
|
-
# @return [.load, .dump]
|
146
|
-
#
|
147
|
-
# @example
|
148
|
-
# Shale.csv_adapter
|
149
|
-
# # => Shale::Adapter::CSV
|
150
|
-
#
|
151
|
-
# @api public
|
152
|
-
def csv_adapter
|
153
|
-
@csv_adapter || Adapter::CSV
|
154
|
-
end
|
155
151
|
end
|
156
152
|
end
|
data/shale.gemspec
CHANGED
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: shale
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kamil Giszczak
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
12
|
-
dependencies:
|
11
|
+
date: 2024-02-17 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bigdecimal
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
description: Ruby object mapper and serializer for XML, JSON, TOML, CSV and YAML.
|
14
28
|
email:
|
15
29
|
- beerkg@gmail.com
|
@@ -118,14 +132,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
118
132
|
requirements:
|
119
133
|
- - ">="
|
120
134
|
- !ruby/object:Gem::Version
|
121
|
-
version:
|
135
|
+
version: 3.0.0
|
122
136
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
123
137
|
requirements:
|
124
138
|
- - ">="
|
125
139
|
- !ruby/object:Gem::Version
|
126
140
|
version: '0'
|
127
141
|
requirements: []
|
128
|
-
rubygems_version: 3.
|
142
|
+
rubygems_version: 3.5.3
|
129
143
|
signing_key:
|
130
144
|
specification_version: 4
|
131
145
|
summary: Ruby object mapper and serializer for XML, JSON, TOML, CSV and YAML.
|