dynamicschema 1.0.0.beta02 → 1.0.0.beta04

Sign up to get free protection for your applications and to get access to all the features.
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