dynamicschema 1.0.0.beta02 → 1.0.0.beta04

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: 0251af8d67cb7dbbaeea74a21dd72dd2385e2449d4aa41c48753f4b05428dfed
4
- data.tar.gz: ce213906df2fe4facdf469717c61f5138aa3cae7469ba0ac3d5dc21e6dadd958
3
+ metadata.gz: 2bbda4319f58741ceca992dec756544aeaa8f9b293afa0bee507ba94636405f4
4
+ data.tar.gz: 67283d904c6d84994d724d2e5a934332f78661bfa1173b0e0a6b4026a1b0a788
5
5
  SHA512:
6
- metadata.gz: 48b889c8c37b1a454819a5ea8de9d63179348b7cede7ce043f0972bef384012cb9ed3a4aaabe8a739f3d51e21bee0f3315231fc5ea6b80cab48c945f3ac17919
7
- data.tar.gz: 3b317ae13cfb0d558fe8f77267136e2132842780f39331ccf192e7f5b65d397ea1ac8bb3fa8d615f38afb9c1adf09a227a689921d63237525b8f6fc04b040cfa
6
+ metadata.gz: 2fa81eb8ff0e153e2d9900eea14f26dbdc71ce90bb1b4595c9091330da1d8f6c7fdcd0fa2e8273a64346c08f5baca9a4d2519db7e67b35ea20da6d49a1adde16
7
+ data.tar.gz: 3d86d903925519d2813c379d528ada3a678e80cdf3c24287697c19ab0b3fb9ad9062f21c36bc219f5dceef384fb19bcc1208117416e964906e5cee5b4d9ae7db
data/README.md CHANGED
@@ -139,7 +139,7 @@ as well as a `Hash` of options, all of which are optional:
139
139
  require 'dynamic_schema'
140
140
 
141
141
  # define a schema structure with values
142
- schema = DynamicSchema::Builder.new.define do
142
+ schema = DynamicSchema.define do
143
143
  api_key
144
144
  version, String, default: '1.0'
145
145
  end
@@ -189,12 +189,12 @@ Notice an *object* does not accept a type as it is always of type `Object`.
189
189
  ```ruby
190
190
  require 'dynamic_schema'
191
191
 
192
- schema = DynamicSchema::Builder.new do
192
+ schema = DynamicSchema.define do
193
193
  api_key, String
194
194
  chat_options do
195
195
  model String, default: 'claude-3'
196
196
  max_tokens Integer, default: 1024
197
- temperature, Float, default: 0.5, in: 0..1
197
+ temperature Float, default: 0.5, in: 0..1
198
198
  stream [ TrueClass, FalseClass ]
199
199
  end
200
200
  end
@@ -236,7 +236,7 @@ the value. If you want to specify multiple types simply provide an array of type
236
236
  ```ruby
237
237
  require 'dynamic_schema'
238
238
 
239
- schema = DynamicSchema::Builder.new do
239
+ schema = DynamicSchema.define do
240
240
  typeless_value
241
241
  symbol_value Symbol
242
242
  boolean_value [ TrueClass, FalseClass ]
@@ -424,16 +424,30 @@ their definition and construction.
424
424
 
425
425
  ### Definable
426
426
 
427
- The `Definable` module, when inclued in a class, will add a `schema` class method to your class.
428
- You can call `schema` with a block and define a schema directly inside your class. The `schema`
429
- method can be called repeatedly, with subsequent calls augmenting, any preexsiting schema.
427
+ The `Definable` module, when inclued in a class, will add the `schema` and the `builder` class
428
+ methods.
430
429
 
431
- This can be used in a class hierarchy to augment base class schemas in derived classes.
430
+ By calling `schema` with a block you can define a schema for that specific class. You may also
431
+ retrieve the defined schema by calling 'schema' ( with or without a block ). The 'schema' method
432
+ may be called repeatedly to build up a schema with each call adding to the existing schema
433
+ ( replacing values and objects of the same name if they appear in subsequent calls ).
432
434
 
433
- ```
434
- class DatabaSettings
435
+ The `schema` method will integrate with a class hierarchy. By including Definable in a base class
436
+ you can call `schema` to define a schema for that base class and then in subsequent dervied classes
437
+ to augment it for those classes.
438
+
439
+ The `builder` method will return a memoized builder of the schema defined by calls to the `schema`
440
+ method which can be used to build and validate schema conformant hashes.
441
+
442
+ ```ruby
443
+ class Setting
435
444
  include DynamicSchema::Definable
436
-
445
+ schema do
446
+ name String
447
+ end
448
+ end
449
+
450
+ class DatabaSetting < Setting
437
451
  schema do
438
452
  database do
439
453
  host String
@@ -444,12 +458,9 @@ class DatabaSettings
444
458
 
445
459
  def initalize( attributes = {} )
446
460
  # validate the attributes
447
- schema_builder = DynamicSchema::Builder.new.define( &class.schema )
448
- schema_builder.validate!( attributes )
449
- # initialize from the given attributes here
450
- @host = attributes[ :database ][ :host ]
451
- @port = attributes[ :database ][ :port ]
452
- @name = attributes[ :database ][ :name ]
461
+ self.class.builder.validate!( attributes )
462
+ # retain them for future access
463
+ @attributes = attributes&.dup
453
464
  end
454
465
 
455
466
  end
@@ -462,19 +473,25 @@ building that class using a schema assisted builder pattern. The `Buildable` mod
462
473
  `build!` and `build` methods to the class which can be used to build that class, with and
463
474
  without validation respectivelly.
464
475
 
465
- These methods accept both a hash with attitbutes that follow the schema, as well as a block
476
+ These methods accept both a hash with attributes that follow the schema, as well as a block
466
477
  that can be used to build the class instance. The attributes and block can be used simultanously.
467
478
 
468
- **Important** Note that `Buildable` requires that the initializer accept a `Hash` of attributes.
479
+ **Important** Note that `Buildable` requires a class method `builder` ( which `Definable`
480
+ provides ) and an initializer that accepts a `Hash` of attributes.
469
481
 
470
- ```
471
- class DatabaSettings
482
+ ```ruby
483
+ class Setting
472
484
  include DynamicSchema::Definable
473
485
  include DynamicSchema::Buildable
474
-
486
+ schema do
487
+ name String
488
+ end
489
+ end
490
+
491
+ class DatabaSetting < Setting
475
492
  schema do
476
493
  database do
477
- adapter Symbol
494
+ adapter Symbol,
478
495
  host String
479
496
  port String
480
497
  name String
@@ -482,18 +499,20 @@ class DatabaSettings
482
499
  end
483
500
 
484
501
  def initalize( attributes = {} )
485
- # assign the attributes
486
- # ...
502
+ # validate the attributes
503
+ self.class.builder.validate!( attributes )
504
+ # retain them for the future
505
+ @attributes = attributes&.dup
487
506
  end
488
-
489
507
  end
490
508
 
491
- database_settings = DatabaSettings.build! adapter: :pg do
492
- host "localhost"
493
- port "127.0.0.1"
494
- name "mydb"
509
+ database_settings = DatabaSettings.build! name: 'settings.database' do
510
+ database adapter: :pg do
511
+ host "localhost"
512
+ port "127.0.0.1"
513
+ name "mydb"
514
+ end
495
515
  end
496
-
497
516
  ```
498
517
 
499
518
  ## Validation
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do | spec |
2
2
 
3
3
  spec.name = 'dynamicschema'
4
- spec.version = '1.0.0.beta02'
4
+ spec.version = '1.0.0.beta04'
5
5
  spec.authors = [ 'Kristoph Cichocki-Romanov' ]
6
6
  spec.email = [ 'rubygems.org@kristoph.net' ]
7
7
 
@@ -8,13 +8,11 @@ module DynamicSchema
8
8
  module ClassMethods
9
9
 
10
10
  def build( attributes = nil, &block )
11
- @_builder ||= Builder.new.define( &self.schema )
12
- new( @_builder.build( attributes, &block ) )
11
+ new( builder.build( attributes, &block ) )
13
12
  end
14
13
 
15
14
  def build!( attributes = nil, &block )
16
- @_builder ||= Builder.new.define( &self.schema )
17
- new( @_builder.build!( attributes, &block ) )
15
+ new( builder.build!( attributes, &block ) )
18
16
  end
19
17
 
20
18
  end
@@ -15,7 +15,7 @@ module DynamicSchema
15
15
  end
16
16
 
17
17
  def define( &block )
18
- self.schema = Resolver.new( self.schema ).resolve( &block ).schema
18
+ self.schema = Resolver.new( self.schema ).resolve( &block )._schema
19
19
  self
20
20
  end
21
21
 
@@ -61,7 +61,7 @@ module DynamicSchema
61
61
  if criteria[ :type ] == Object
62
62
  traverse_and_validate_values(
63
63
  values[ name ],
64
- schema: criteria[ :schema ] ||= criteria[ :resolver ].schema,
64
+ schema: criteria[ :schema ] ||= criteria[ :resolver ]._schema,
65
65
  path: "#{ ( path || '' ) + ( path ? '/' : '' ) + key.to_s }",
66
66
  &block
67
67
  )
@@ -80,7 +80,7 @@ module DynamicSchema
80
80
  groups.each do | group |
81
81
  traverse_and_validate_values(
82
82
  group,
83
- schema: criteria[ :schema ] ||= criteria[ :resolver ].schema,
83
+ schema: criteria[ :schema ] ||= criteria[ :resolver ]._schema,
84
84
  path: "#{ ( path || '' ) + ( path ? '/' : '' ) + key.to_s }",
85
85
  &block
86
86
  )
@@ -8,8 +8,15 @@ module DynamicSchema
8
8
  module ClassMethods
9
9
 
10
10
  def schema( &block )
11
- @_schema ||= []
12
- @_schema << block if block_given?
11
+ @_schema ||= []
12
+ if block_given?
13
+ # note that the memoized builder is reset when schema is called with a new block so
14
+ # that additions to the schema are incorporated into future builder ( but this does
15
+ # not work if the schema is updated on a superclass after this class' builder has
16
+ # been returned )
17
+ @_builder = nil
18
+ @_schema << block
19
+ end
13
20
  schema_blocks = _collect_schema
14
21
  proc do
15
22
  schema_blocks.each do | block |
@@ -18,6 +25,10 @@ module DynamicSchema
18
25
  end
19
26
  end
20
27
 
28
+ def builder
29
+ @_builder ||= DynamicSchema.define( &schema )
30
+ end
31
+
21
32
  protected
22
33
 
23
34
  def _collect_schema
@@ -197,7 +197,7 @@ module DynamicSchema
197
197
  Receiver.new(
198
198
  attributes,
199
199
  converters: @converters,
200
- schema: criteria[ :schema ] ||= criteria[ :resolver ].schema
200
+ schema: criteria[ :schema ] ||= criteria[ :resolver ]._schema
201
201
  )
202
202
  end
203
203
  value.instance_eval( &block ) if block
@@ -213,7 +213,7 @@ module DynamicSchema
213
213
  receiver = Receiver.new(
214
214
  a,
215
215
  converters: @converters,
216
- schema: criteria[ :schema ] ||= criteria[ :resolver ].schema
216
+ schema: criteria[ :schema ] ||= criteria[ :resolver ]._schema
217
217
  )
218
218
  receiver.instance_eval( &block ) if block
219
219
  receiver
@@ -22,7 +22,8 @@ module DynamicSchema
22
22
  self
23
23
  end
24
24
 
25
- def schema
25
+ def _schema
26
+
26
27
  if !@resolved && @block
27
28
  @resolved_blocks << @block unless @resolved_blocks.include?( @block )
28
29
  self.instance_eval( &@block )
@@ -31,6 +32,29 @@ module DynamicSchema
31
32
  @schema
32
33
  end
33
34
 
35
+ def _value( name, options )
36
+ name = name.to_sym
37
+ ::Kernel.raise ::NameError, "The name '#{name}' is reserved and cannot be used for parameters." \
38
+ if ::DynamicSchema::Receiver.instance_methods.include?( name )
39
+
40
+ _validate_in!( name, options[ :type ], options[ :in ] ) if options[ :in ]
41
+
42
+ @schema[ name ] = options
43
+ self
44
+ end
45
+
46
+ def _object( name, options = {}, &block )
47
+ name = name.to_sym
48
+ ::Kernel.raise ::NameError, "The name '#{name}' is reserved and cannot be used for parameters." \
49
+ if ::DynamicSchema::Receiver.instance_methods.include?( name )
50
+
51
+ @schema[ name ] = options.merge( {
52
+ type: ::Object,
53
+ resolver: Resolver.new( resolved_blocks: @resolved_blocks ).resolve( &block )
54
+ } )
55
+ self
56
+ end
57
+
34
58
  def method_missing( method, *args, &block )
35
59
  first = args.first
36
60
  options = nil
@@ -58,9 +82,9 @@ module DynamicSchema
58
82
 
59
83
  type = options[ :type ]
60
84
  if type == ::Object || type.nil? && block
61
- _append_object( method, options, &block )
85
+ _object( method, options, &block )
62
86
  else
63
- _append_value( method, options )
87
+ _value( method, options )
64
88
  end
65
89
 
66
90
  end
@@ -92,27 +116,6 @@ module DynamicSchema
92
116
 
93
117
  private
94
118
 
95
- def _append_value( name, options )
96
- ::Kernel.raise ::NameError, "The name '#{name}' is reserved and cannot be used for parameters." \
97
- if ::DynamicSchema::Receiver.instance_methods.include?( name )
98
-
99
- _validate_in!( name, options[ :type ], options[ :in ] ) if options[ :in ]
100
-
101
- @schema[ name ] = options
102
- self
103
- end
104
-
105
- def _append_object( name, options = {}, &block )
106
- ::Kernel.raise ::NameError, "The name '#{name}' is reserved and cannot be used for parameters." \
107
- if ::DynamicSchema::Receiver.instance_methods.include?( name )
108
-
109
- @schema[ name ] = options.merge( {
110
- type: ::Object,
111
- resolver: Resolver.new( resolved_blocks: @resolved_blocks ).resolve( &block )
112
- } )
113
- self
114
- end
115
-
116
119
  def _validate_in!( name, type, in_option )
117
120
  ::Kernel.raise ::TypeError,
118
121
  "The parameter '#{name}' includes the :in option but it does not respond to 'include?'." \
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dynamicschema
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.beta02
4
+ version: 1.0.0.beta04
5
5
  platform: ruby
6
6
  authors:
7
7
  - Kristoph Cichocki-Romanov
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-10-27 00:00:00.000000000 Z
11
+ date: 2024-11-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec