dynamicschema 1.0.0.beta01 → 1.0.0.beta03

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: 32cb8398626d7ac822a228c89778e566ef62182b054ab267b8edf45bc718eda3
4
- data.tar.gz: 3475b1a090f57e4702076677b426300c892d91a06ac55841cd6e48657f69d7aa
3
+ metadata.gz: 5685a6ff1c79676a075f3f7f2cd5863c35466a402c79f3af46c2e164eb37581a
4
+ data.tar.gz: 374fbd61c218c4dc4bc6620d18fa3a973d197aa96032c6c2998bb4d3ed8da378
5
5
  SHA512:
6
- metadata.gz: a39f196fc0f7e3a657a6e776163ac5d1d90d42ff8cba556b99691074dead341d42bc9e8230cfab4ece6fd81617540a09462278ce4d5fbca97eadec218ee09902
7
- data.tar.gz: bd2c0f880a7c088ccecd5df2574acf32e6242dacac8b730d44141d9b95f334828c0b39c860a24f7abd7e815eaf82c97499119c95664f565b557f80688ad955ac
6
+ metadata.gz: 80c7ae562b99ddabf6fe6220a995d845beda151c13683aff13891c47e089700579cb7a099b08a4ac789569ab0499612c2f467222661082b1794cbb75d424a1d9
7
+ data.tar.gz: 2da0f6cf54388b6e2e5d3f3ac05214c6f3ea27c8c763fb1ac9a84bbbddbad92d21b29db328c70388653ffd4317a409a58b0165323626e2e2ea2988b188df14c3
data/README.md CHANGED
@@ -57,6 +57,9 @@ You can find a full OpenAI request example in the `/examples` folder of this rep
57
57
  - [as Option](#as-option)
58
58
  - [in Option (Values Only)](#in-option)
59
59
  - [arguments Option](#arguments-option)
60
+ - [Class Schema](#class-schemas)
61
+ - [Definable](#definable)
62
+ - [Buildable](#buildable)
60
63
  - [Validation Methods](#validation-methods)
61
64
  - [Validation Rules](#validation-rules)
62
65
  - [validate!](#validate)
@@ -136,7 +139,7 @@ as well as a `Hash` of options, all of which are optional:
136
139
  require 'dynamic_schema'
137
140
 
138
141
  # define a schema structure with values
139
- schema = DynamicSchema::Builder.new.define do
142
+ schema = DynamicSchema.define do
140
143
  api_key
141
144
  version, String, default: '1.0'
142
145
  end
@@ -186,7 +189,7 @@ Notice an *object* does not accept a type as it is always of type `Object`.
186
189
  ```ruby
187
190
  require 'dynamic_schema'
188
191
 
189
- schema = DynamicSchema::Builder.new do
192
+ schema = DynamicSchema.define do
190
193
  api_key, String
191
194
  chat_options do
192
195
  model String, default: 'claude-3'
@@ -233,7 +236,7 @@ the value. If you want to specify multiple types simply provide an array of type
233
236
  ```ruby
234
237
  require 'dynamic_schema'
235
238
 
236
- schema = DynamicSchema::Builder.new do
239
+ schema = DynamicSchema.define do
237
240
  typeless_value
238
241
  symbol_value Symbol
239
242
  boolean_value [ TrueClass, FalseClass ]
@@ -414,6 +417,104 @@ result = schema.build! do
414
417
  end
415
418
  ```
416
419
 
420
+ ## Class Schemas
421
+
422
+ DynamicSchema provides a number of modules you can include into your own classes to simplify
423
+ their definition and construction.
424
+
425
+ ### Definable
426
+
427
+ The `Definable` module, when inclued in a class, will add the `schema` and the `builder` class
428
+ methods.
429
+
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 ).
434
+
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
444
+ include DynamicSchema::Definable
445
+ schema do
446
+ name String
447
+ end
448
+ end
449
+
450
+ class DatabaSetting < Setting
451
+ schema do
452
+ database do
453
+ host String
454
+ port String
455
+ name String
456
+ end
457
+ end
458
+
459
+ def initalize( attributes = {} )
460
+ # validate the attributes
461
+ self.class.builder.validate!( attributes )
462
+ # retain them for future access
463
+ @attributes = attributes&.dup
464
+ end
465
+
466
+ end
467
+ ```
468
+
469
+ ### Buildable
470
+
471
+ The `Buildable` module can be included in a class, in addition to `Definable` to faciliate
472
+ building that class using a schema assisted builder pattern. The `Buildable` module adds
473
+ `build!` and `build` methods to the class which can be used to build that class, with and
474
+ without validation respectivelly.
475
+
476
+ These methods accept both a hash with attributes that follow the schema, as well as a block
477
+ that can be used to build the class instance. The attributes and block can be used simultanously.
478
+
479
+ **Important** Note that `Buildable` requires a class method `builder` ( which `Definable`
480
+ provides ) and an initializer that accepts a `Hash` of attributes.
481
+
482
+ ```ruby
483
+ class Setting
484
+ include DynamicSchema::Definable
485
+ include DynamicSchema::Buildable
486
+ schema do
487
+ name String
488
+ end
489
+ end
490
+
491
+ class DatabaSetting < Setting
492
+ schema do
493
+ database do
494
+ adapter Symbol,
495
+ host String
496
+ port String
497
+ name String
498
+ end
499
+ end
500
+
501
+ def initalize( attributes = {} )
502
+ # validate the attributes
503
+ self.class.builder.validate!( attributes )
504
+ # retain them for the future
505
+ @attributes = attributes&.dup
506
+ end
507
+ end
508
+
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
515
+ end
516
+ ```
517
+
417
518
  ## Validation
418
519
 
419
520
  DynamicSchema provides three different methods for validating Hash structures against your
@@ -1,7 +1,7 @@
1
1
  Gem::Specification.new do | spec |
2
2
 
3
3
  spec.name = 'dynamicschema'
4
- spec.version = '1.0.0.beta01'
4
+ spec.version = '1.0.0.beta03'
5
5
  spec.authors = [ 'Kristoph Cichocki-Romanov' ]
6
6
  spec.email = [ 'rubygems.org@kristoph.net' ]
7
7
 
@@ -0,0 +1,22 @@
1
+ module DynamicSchema
2
+ module Buildable
3
+
4
+ def self.included( base )
5
+ base.extend ClassMethods
6
+ end
7
+
8
+ module ClassMethods
9
+
10
+ def build( attributes = nil, &block )
11
+ new( builder.build( attributes, &block ) )
12
+ end
13
+
14
+ def build!( attributes = nil, &block )
15
+ new( builder.build!( attributes, &block ) )
16
+ end
17
+
18
+ end
19
+
20
+ end
21
+ end
22
+
@@ -0,0 +1,47 @@
1
+ module DynamicSchema
2
+ module Definable
3
+
4
+ def self.included( base )
5
+ base.extend ClassMethods
6
+ end
7
+
8
+ module ClassMethods
9
+
10
+ def schema( &block )
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
20
+ schema_blocks = _collect_schema
21
+ proc do
22
+ schema_blocks.each do | block |
23
+ instance_eval( &block )
24
+ end
25
+ end
26
+ end
27
+
28
+ def builder
29
+ @_builder ||= DynamicSchema.define( &schema )
30
+ end
31
+
32
+ protected
33
+
34
+ def _collect_schema
35
+ schema_blocks = []
36
+ if superclass.singleton_methods.include?( :_collect_schema )
37
+ schema_blocks.concat( superclass._collect_schema )
38
+ end
39
+ schema_blocks.concat( @_schema ) if defined?( @_schema )
40
+ schema_blocks
41
+ end
42
+
43
+ end
44
+
45
+ end
46
+ end
47
+
@@ -103,7 +103,9 @@ module DynamicSchema
103
103
  @defaults_assigned[ method ] = false
104
104
  @values[ name ] = value
105
105
  else
106
- super
106
+ ::Kernel.raise ::NoMethodError,
107
+ "There is no schema value or object '#{method}' defined in this scope which includes: " \
108
+ "#{@schema.keys.join( ', ' )}."
107
109
  end
108
110
  end
109
111
 
@@ -1,6 +1,8 @@
1
1
  require_relative 'dynamic_schema/errors'
2
2
  require_relative 'dynamic_schema/builder'
3
- require_relative 'dynamic_schema/definition'
3
+
4
+ require_relative 'dynamic_schema/definable'
5
+ require_relative 'dynamic_schema/buildable'
4
6
 
5
7
  module DynamicSchema
6
8
  def self.define( schema = {}, &block )
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.beta01
4
+ version: 1.0.0.beta03
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-25 00:00:00.000000000 Z
11
+ date: 2024-10-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rspec
@@ -55,10 +55,11 @@ files:
55
55
  - README.md
56
56
  - dynamicschema.gemspec
57
57
  - lib/dynamic_schema.rb
58
+ - lib/dynamic_schema/buildable.rb
58
59
  - lib/dynamic_schema/builder.rb
59
60
  - lib/dynamic_schema/builder_methods/conversion.rb
60
61
  - lib/dynamic_schema/builder_methods/validation.rb
61
- - lib/dynamic_schema/definition.rb
62
+ - lib/dynamic_schema/definable.rb
62
63
  - lib/dynamic_schema/errors.rb
63
64
  - lib/dynamic_schema/receiver.rb
64
65
  - lib/dynamic_schema/resolver.rb
@@ -1,23 +0,0 @@
1
- require_relative 'builder'
2
-
3
- module DynamicSchema
4
- module Definition
5
-
6
- def schema( schema = nil, &block )
7
- return @_schema_builder if ( schema.nil? || schema.empty? ) && !block
8
- @_schema_builder = DynamicSchema::Builder.new( schema ).define( &block )
9
- end
10
-
11
- def build_with_schema( attributes = nil, &block )
12
- raise RuntimeError, "The schema has not been defined." if @_schema_builder.nil?
13
- @_schema_builder.build( attributes, &block )
14
- end
15
-
16
- def build_with_schema!( attributes = nil, &block )
17
- raise RuntimeError, "The schema has not been defined." if @_schema_builder.nil?
18
- @_schema_builder.build!( attributes, &block )
19
- end
20
-
21
- end
22
- end
23
-