schemas 0.0.2

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: feb8ecca43a4e0d7acf0eeb66c41ad5f2bda9651
4
+ data.tar.gz: 0ae00077d484889426f058b38a89d5abd85b5e6d
5
+ SHA512:
6
+ metadata.gz: fed45e27ecbdb3ade5448afaef98e67d40cf65eb2347a09c51fd0bd7263331dbdffc4b24832c4d63dbc787126145e061820552591762b9ae096a0d44ff5ee913
7
+ data.tar.gz: 7243bb874081c3e36b27e3e53a08f1e14008ecd12daa947891b4cb7f68b10a3c03321e766d34c575e60e4186f33f61920c355ff944d0e9131c2cefe28d067779
data/lib/schemas.rb ADDED
@@ -0,0 +1,28 @@
1
+ require 'active_support'
2
+ require 'active_support/core_ext/object/blank'
3
+
4
+ # fields
5
+ require "schemas/fields/field_with_default"
6
+ require "schemas/fields/merged_named_fields"
7
+ require "schemas/fields/missing"
8
+ require "schemas/fields/named_field_from_hash"
9
+ require "schemas/fields/pass_through_field"
10
+ require "schemas/fields/required_field"
11
+
12
+ # ui
13
+ require "schemas/ui/schema.rb"
14
+
15
+ # validators
16
+ require "schemas/validators/validator_chain.rb"
17
+
18
+ # types
19
+ require "schemas/types/integer_type.rb"
20
+ require "schemas/types/type_with_validator.rb"
21
+
22
+ module Schemas
23
+ def self.define(*args, &block)
24
+ Schemas::UI::Schema.define(*args, &block)
25
+ end
26
+
27
+ VERSION = "0.0.2"
28
+ end
@@ -0,0 +1,26 @@
1
+ module Schemas
2
+ module Fields
3
+ class FieldWithDefault
4
+ def initialize(field, default)
5
+ @field = field
6
+ @default = default
7
+ end
8
+
9
+ def errors(input)
10
+ return [] if input.blank?
11
+ @field.errors(input)
12
+ end
13
+
14
+ def parse(input)
15
+ return use_default if input.blank?
16
+ @field.parse(input)
17
+ end
18
+
19
+ private
20
+
21
+ def use_default
22
+ @default.is_a?(Proc) ? @default.call : @default
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,17 @@
1
+ module Schemas
2
+ module Fields
3
+ class MergedNamedFields
4
+ def initialize(named_fields)
5
+ @named_fields = named_fields
6
+ end
7
+
8
+ def errors(input_hash)
9
+ @named_fields.map {|nv| nv.errors(input_hash)}.reduce({}, :merge)
10
+ end
11
+
12
+ def parse(input_hash)
13
+ @named_fields.map {|nv| nv.parse(input_hash)}.reduce({}, :merge)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,9 @@
1
+ module Schemas
2
+ module Fields
3
+ class Missing
4
+ def blank?
5
+ true
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,27 @@
1
+ module Schemas
2
+ module Fields
3
+ class NamedFieldFromHash
4
+ def initialize(name, field)
5
+ @name = name
6
+ @field = field
7
+ end
8
+
9
+ def errors(input_hash)
10
+ input = get_value_from_hash(input_hash)
11
+ errors = @field.errors(input)
12
+ errors.any? ? {@name => errors} : {}
13
+ end
14
+
15
+ def parse(input_hash)
16
+ input = get_value_from_hash(input_hash)
17
+ {@name => @field.parse(input)}
18
+ end
19
+
20
+ private
21
+
22
+ def get_value_from_hash(input_hash)
23
+ input_hash.fetch(@name, Missing.new)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,13 @@
1
+ module Schemas
2
+ module Fields
3
+ class PassThroughField
4
+ def errors(input)
5
+ []
6
+ end
7
+
8
+ def parse(input)
9
+ input
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,18 @@
1
+ module Schemas
2
+ module Fields
3
+ class RequiredField
4
+ def initialize(field)
5
+ @field = field
6
+ end
7
+
8
+ def errors(input)
9
+ return [:required] if input.blank?
10
+ @field.errors(input)
11
+ end
12
+
13
+ def parse(input)
14
+ @field.parse(input)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ module Schemas
2
+ module Types
3
+ class IntegerType
4
+ def errors(string)
5
+ begin
6
+ Integer(string)
7
+ []
8
+ rescue ArgumentError
9
+ [:not_an_integer]
10
+ end
11
+ end
12
+
13
+ def parse(string)
14
+ Integer(string)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,22 @@
1
+ module Schemas
2
+ module Types
3
+ class TypeWithValidator
4
+ def initialize(type, validator)
5
+ @type = type
6
+ @validator = validator
7
+ end
8
+
9
+ def errors(input)
10
+ type_errors = @type.errors(input)
11
+ return type_errors if type_errors.any?
12
+
13
+ parsed = @type.parse(input)
14
+ @validator.errors(parsed)
15
+ end
16
+
17
+ def parse(input)
18
+ @type.parse(input)
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,56 @@
1
+ module Schemas
2
+ module UI
3
+ class Schema
4
+ def initialize
5
+ @params = []
6
+ end
7
+
8
+ def self.define(&block)
9
+ schema = new
10
+ schema.instance_eval(&block)
11
+ schema
12
+ end
13
+
14
+ def parse(input)
15
+ raise CannotParseWhenThereAreErrors if errors(input).any?
16
+ merged_named_fields.parse(input)
17
+ end
18
+
19
+ def errors(input)
20
+ merged_named_fields.errors(input)
21
+ end
22
+
23
+ def required(name, *args)
24
+ type_with_validator = construct_field_from_params(*args)
25
+ required_field = Fields::RequiredField.new(type_with_validator)
26
+ @params << Fields::NamedFieldFromHash.new(name, required_field)
27
+ end
28
+
29
+ def optional(name, *args,
30
+ default: raise("optional requires a default: param, " +
31
+ "either a value or a lambda"), **kwargs)
32
+ type_with_validator = construct_field_from_params(*args, **kwargs)
33
+ optional_field = Fields::FieldWithDefault.new(type_with_validator,
34
+ default)
35
+ @params << Fields::NamedFieldFromHash.new(name, optional_field)
36
+ end
37
+
38
+ private
39
+
40
+ def construct_field_from_params(type: Fields::PassThroughField.new,
41
+ required: true, validator: nil,
42
+ validators: [])
43
+ validator_chain = Validators::ValidatorChain.new(Array(validator) +
44
+ validators)
45
+ Types::TypeWithValidator.new(type, validator_chain)
46
+ end
47
+
48
+ def merged_named_fields
49
+ Fields::MergedNamedFields.new(@params)
50
+ end
51
+
52
+ class CannotParseWhenThereAreErrors < StandardError
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,13 @@
1
+ module Schemas
2
+ module Validators
3
+ class ValidatorChain
4
+ def initialize(validators)
5
+ @validators = validators
6
+ end
7
+
8
+ def errors(obj)
9
+ @validators.map { |v| v.errors(obj) }.flatten
10
+ end
11
+ end
12
+ end
13
+ end
metadata ADDED
@@ -0,0 +1,82 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: schemas
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ platform: ruby
6
+ authors:
7
+ - Sumeet Agarwal
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-12-02 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activesupport
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description:
42
+ email: sumeet.a@gmail.com
43
+ executables: []
44
+ extensions: []
45
+ extra_rdoc_files: []
46
+ files:
47
+ - lib/schemas/fields/field_with_default.rb
48
+ - lib/schemas/fields/merged_named_fields.rb
49
+ - lib/schemas/fields/missing.rb
50
+ - lib/schemas/fields/named_field_from_hash.rb
51
+ - lib/schemas/fields/pass_through_field.rb
52
+ - lib/schemas/fields/required_field.rb
53
+ - lib/schemas/types/integer_type.rb
54
+ - lib/schemas/types/type_with_validator.rb
55
+ - lib/schemas/ui/schema.rb
56
+ - lib/schemas/validators/validator_chain.rb
57
+ - lib/schemas.rb
58
+ homepage: https://github.com/sumeet/schemas
59
+ licenses:
60
+ - MIT
61
+ metadata: {}
62
+ post_install_message:
63
+ rdoc_options: []
64
+ require_paths:
65
+ - lib
66
+ required_ruby_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ requirements: []
77
+ rubyforge_project:
78
+ rubygems_version: 2.0.3
79
+ signing_key:
80
+ specification_version: 4
81
+ summary: A schema parsing and validation library for Ruby
82
+ test_files: []