dry-types 0.14.1 → 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (100) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +12 -0
  3. data/.github/ISSUE_TEMPLATE/----please-don-t-ask-for-support-via-issues.md +10 -0
  4. data/.github/ISSUE_TEMPLATE/---bug-report.md +34 -0
  5. data/.github/ISSUE_TEMPLATE/---feature-request.md +18 -0
  6. data/.github/workflows/custom_ci.yml +76 -0
  7. data/.github/workflows/docsite.yml +34 -0
  8. data/.github/workflows/sync_configs.yml +34 -0
  9. data/.gitignore +1 -0
  10. data/.rspec +3 -1
  11. data/.rubocop.yml +89 -0
  12. data/.yardopts +6 -2
  13. data/CHANGELOG.md +303 -0
  14. data/CODE_OF_CONDUCT.md +13 -0
  15. data/CONTRIBUTING.md +2 -2
  16. data/Gemfile +16 -8
  17. data/LICENSE +17 -17
  18. data/README.md +4 -3
  19. data/Rakefile +4 -2
  20. data/benchmarks/hash_schemas.rb +12 -8
  21. data/benchmarks/lax_schema.rb +15 -0
  22. data/benchmarks/profile_invalid_input.rb +15 -0
  23. data/benchmarks/profile_lax_schema_valid.rb +16 -0
  24. data/benchmarks/profile_valid_input.rb +15 -0
  25. data/benchmarks/schema_valid_vs_invalid.rb +21 -0
  26. data/benchmarks/setup.rb +17 -0
  27. data/docsite/source/array-with-member.html.md +13 -0
  28. data/docsite/source/built-in-types.html.md +116 -0
  29. data/docsite/source/constraints.html.md +31 -0
  30. data/docsite/source/custom-types.html.md +93 -0
  31. data/docsite/source/default-values.html.md +91 -0
  32. data/docsite/source/enum.html.md +69 -0
  33. data/docsite/source/extensions.html.md +15 -0
  34. data/docsite/source/extensions/maybe.html.md +57 -0
  35. data/docsite/source/extensions/monads.html.md +61 -0
  36. data/docsite/source/getting-started.html.md +57 -0
  37. data/docsite/source/hash-schemas.html.md +169 -0
  38. data/docsite/source/index.html.md +156 -0
  39. data/docsite/source/map.html.md +17 -0
  40. data/docsite/source/optional-values.html.md +35 -0
  41. data/docsite/source/sum.html.md +21 -0
  42. data/dry-types.gemspec +21 -19
  43. data/lib/dry-types.rb +2 -0
  44. data/lib/dry/types.rb +115 -50
  45. data/lib/dry/types/any.rb +31 -11
  46. data/lib/dry/types/array.rb +18 -5
  47. data/lib/dry/types/array/constructor.rb +32 -0
  48. data/lib/dry/types/array/member.rb +75 -16
  49. data/lib/dry/types/builder.rb +71 -7
  50. data/lib/dry/types/builder_methods.rb +46 -20
  51. data/lib/dry/types/coercions.rb +84 -19
  52. data/lib/dry/types/coercions/json.rb +22 -3
  53. data/lib/dry/types/coercions/params.rb +99 -29
  54. data/lib/dry/types/compat.rb +0 -2
  55. data/lib/dry/types/compiler.rb +54 -39
  56. data/lib/dry/types/constrained.rb +81 -29
  57. data/lib/dry/types/constrained/coercible.rb +36 -6
  58. data/lib/dry/types/constraints.rb +15 -1
  59. data/lib/dry/types/constructor.rb +94 -58
  60. data/lib/dry/types/constructor/function.rb +200 -0
  61. data/lib/dry/types/container.rb +7 -0
  62. data/lib/dry/types/core.rb +48 -17
  63. data/lib/dry/types/decorator.rb +39 -11
  64. data/lib/dry/types/default.rb +48 -16
  65. data/lib/dry/types/enum.rb +39 -17
  66. data/lib/dry/types/errors.rb +74 -8
  67. data/lib/dry/types/extensions.rb +6 -0
  68. data/lib/dry/types/extensions/maybe.rb +62 -5
  69. data/lib/dry/types/extensions/monads.rb +29 -0
  70. data/lib/dry/types/fn_container.rb +5 -0
  71. data/lib/dry/types/hash.rb +92 -67
  72. data/lib/dry/types/hash/constructor.rb +33 -0
  73. data/lib/dry/types/inflector.rb +2 -0
  74. data/lib/dry/types/json.rb +12 -10
  75. data/lib/dry/types/{safe.rb → lax.rb} +36 -17
  76. data/lib/dry/types/map.rb +76 -33
  77. data/lib/dry/types/meta.rb +51 -0
  78. data/lib/dry/types/module.rb +120 -0
  79. data/lib/dry/types/nominal.rb +210 -0
  80. data/lib/dry/types/options.rb +13 -26
  81. data/lib/dry/types/params.rb +23 -12
  82. data/lib/dry/types/predicate_inferrer.rb +197 -0
  83. data/lib/dry/types/predicate_registry.rb +34 -0
  84. data/lib/dry/types/primitive_inferrer.rb +97 -0
  85. data/lib/dry/types/printable.rb +16 -0
  86. data/lib/dry/types/printer.rb +315 -0
  87. data/lib/dry/types/result.rb +28 -2
  88. data/lib/dry/types/schema.rb +395 -0
  89. data/lib/dry/types/schema/key.rb +143 -0
  90. data/lib/dry/types/spec/types.rb +54 -7
  91. data/lib/dry/types/sum.rb +81 -33
  92. data/lib/dry/types/type.rb +49 -0
  93. data/lib/dry/types/version.rb +3 -1
  94. metadata +92 -48
  95. data/.travis.yml +0 -27
  96. data/lib/dry/types/compat/form_types.rb +0 -27
  97. data/lib/dry/types/compat/int.rb +0 -14
  98. data/lib/dry/types/definition.rb +0 -113
  99. data/lib/dry/types/hash/schema.rb +0 -199
  100. data/lib/dry/types/hash/schema_builder.rb +0 -75
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 56b7935633ed4d23fa17d30082254f98e3e7f642a482c17bdb6f77629f88a399
4
- data.tar.gz: f9860f5500c746b10dcdd0aec29c70737d31615dc2342ee2ad7bc1f3e12c9250
3
+ metadata.gz: 6a22d275ce9f27a5be0edd1ce02714dbf571ee95abab2ab8e127b88e61317ac3
4
+ data.tar.gz: 8708d3ceb67ff3a726ae0363fe04fd08da440f3fdf7ae4e2f5632104fdf33810
5
5
  SHA512:
6
- metadata.gz: 363ff8a7854062a51c71ff646d5e6c3c9ae1c964be5b99267c77b4cbfc5efa9d99b0466cdc736d142859aa624be99bb9fba1cf89bf9282eeb71f234eb5e3898f
7
- data.tar.gz: 6f6b1714103ea16df7a837c9e0a5b9488adf59f6eddeb8f28228c09daeb843edabacdae54ce9d4b461010c4851f75f8da5860f210b943b1a879105dd85dfd2bf
6
+ metadata.gz: 5ff0c69309f200eef77442aef6e9452046f75394c16b00f0be12cdbad04a8c34a1a02e87e0347fb1875fc0241a83f79e1b70576ad4d4e5202cde40257af3e3bb
7
+ data.tar.gz: 6eef147d7238f8ead4f254f37a0f018d5fc932ea3dd87bf334c06c3f0eb4110372078c4dcfad27c80a1dcfe161cc6955942d1daeffda6cd8980f3770b7a3c8b1
data/.codeclimate.yml ADDED
@@ -0,0 +1,12 @@
1
+ # this file is managed by dry-rb/devtools project
2
+
3
+ version: "2"
4
+
5
+ exclude_patterns:
6
+ - "benchmarks/"
7
+ - "examples/"
8
+ - "spec/"
9
+
10
+ plugins:
11
+ rubocop:
12
+ enabled: true
@@ -0,0 +1,10 @@
1
+ ---
2
+ name: "⚠️ Please don't ask for support via issues"
3
+ about: See CONTRIBUTING.md for more information
4
+ title: ''
5
+ labels: ''
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+
@@ -0,0 +1,34 @@
1
+ ---
2
+ name: "\U0001F41B Bug report"
3
+ about: See CONTRIBUTING.md for more information
4
+ title: ''
5
+ labels: bug
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+ **Before you submit this: WE ONLY ACCEPT BUG REPORTS AND FEATURE REQUESTS**
11
+
12
+ For more information see [our contribution guidelines](https://github.com/rom-rb/rom/blob/master/CONTRIBUTING.md)
13
+
14
+ **Before you report**
15
+
16
+ :warning: If you have a problem related to a schema, please **report it under [dry-schema issues](https://github.com/dry-rb/dry-schema/issues/new?assignees=&labels=bug&template=---bug-report.md&title=)** instead.
17
+
18
+ **Describe the bug**
19
+
20
+ A clear and concise description of what the bug is.
21
+
22
+ **To Reproduce**
23
+
24
+ Provide detailed steps to reproduce, an executable script would be best.
25
+
26
+ **Expected behavior**
27
+
28
+ A clear and concise description of what you expected to happen.
29
+
30
+ **Your environment**
31
+
32
+ - Affects my production application: **YES/NO**
33
+ - Ruby version: ...
34
+ - OS: ...
@@ -0,0 +1,18 @@
1
+ ---
2
+ name: "\U0001F6E0 Feature request"
3
+ about: See CONTRIBUTING.md for more information
4
+ title: ''
5
+ labels: feature
6
+ assignees: ''
7
+
8
+ ---
9
+
10
+ Summary of what the feature is supposed to do.
11
+
12
+ ## Examples
13
+
14
+ Code examples showing how the feature could be used.
15
+
16
+ ## Resources
17
+
18
+ Additional information, like a link to the discussion forum thread where the feature was discussed etc.
@@ -0,0 +1,76 @@
1
+ name: ci
2
+
3
+ on:
4
+ push:
5
+ paths:
6
+ - .github/workflows/ci.yml
7
+ - lib/**
8
+ - spec/**
9
+
10
+ jobs:
11
+ tests-mri:
12
+ runs-on: ubuntu-latest
13
+ strategy:
14
+ fail-fast: false
15
+ matrix:
16
+ ruby: ["2.6.x", "2.5.x", "2.4.x"]
17
+ dry_logic_from_master: ["true", "false"]
18
+ include:
19
+ - ruby: "2.6.x"
20
+ dry_logic_from_master: "false"
21
+ coverage: "true"
22
+ steps:
23
+ - uses: actions/checkout@v1
24
+ - name: Set up Ruby
25
+ uses: actions/setup-ruby@v1
26
+ with:
27
+ ruby-version: ${{matrix.ruby}}
28
+ - name: Download test reporter
29
+ if: "matrix.coverage == 'true'"
30
+ run: |
31
+ mkdir -p tmp/
32
+ curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./tmp/cc-test-reporter
33
+ chmod +x ./tmp/cc-test-reporter
34
+ ./tmp/cc-test-reporter before-build
35
+ - name: Run all tests
36
+ env:
37
+ COVERAGE: ${{matrix.coverage}}
38
+ DRY_LOGIC_FROM_MASTER: ${{matrix.dry_logic_from_master}}
39
+ run: |
40
+ gem install bundler
41
+ bundle install --jobs 4 --retry 3 --without tools docs
42
+ bundle exec rake
43
+ - name: Send coverage results
44
+ if: "matrix.coverage == 'true'"
45
+ env:
46
+ CC_TEST_REPORTER_ID: ${{secrets.CC_TEST_REPORTER_ID}}
47
+ GIT_COMMIT_SHA: ${{github.sha}}
48
+ GIT_BRANCH: ${{github.ref}}
49
+ GIT_COMMITTED_AT: ${{github.event.head_commit.timestamp}}
50
+ run: |
51
+ GIT_BRANCH=`ruby -e "puts ENV['GITHUB_REF'].split('/', 3).last"` \
52
+ GIT_COMMITTED_AT=`ruby -r time -e "puts Time.iso8601(ENV['GIT_COMMITTED_AT']).to_i"` \
53
+ ./tmp/cc-test-reporter after-build
54
+
55
+ tests-others:
56
+ runs-on: ubuntu-latest
57
+ strategy:
58
+ fail-fast: false
59
+ matrix:
60
+ image: ["jruby:9.2.8", "ruby:rc"]
61
+ dry_logic_from_master: ["true", "false"]
62
+ container:
63
+ image: ${{matrix.image}}
64
+ steps:
65
+ - uses: actions/checkout@v1
66
+ - name: Install git
67
+ run: |
68
+ apt-get update
69
+ apt-get install -y --no-install-recommends git
70
+ - name: Run all tests
71
+ env:
72
+ DRY_LOGIC_FROM_MASTER: ${{matrix.dry_logic_from_master}}
73
+ run: |
74
+ gem install bundler
75
+ bundle install --jobs 4 --retry 3 --without tools docs
76
+ bundle exec rspec
@@ -0,0 +1,34 @@
1
+ # this file is managed by dry-rb/devtools project
2
+
3
+ name: docsite
4
+
5
+ on:
6
+ push:
7
+ paths:
8
+ - docsite/**
9
+ - .github/workflows/docsite.yml
10
+ branches:
11
+ - master
12
+ - release-**
13
+ tags:
14
+
15
+ jobs:
16
+ update-docs:
17
+ runs-on: ubuntu-latest
18
+ steps:
19
+ - uses: actions/checkout@v1
20
+ - name: Set up Ruby
21
+ uses: actions/setup-ruby@v1
22
+ with:
23
+ ruby-version: "2.6.x"
24
+ - name: Install dependencies
25
+ run: |
26
+ gem install bundler
27
+ bundle install --jobs 4 --retry 3 --without benchmarks sql
28
+ - name: Symlink ossy
29
+ run: mkdir -p bin && ln -sf "$(bundle show ossy)/bin/ossy" bin/ossy
30
+ - name: Trigger dry-rb.org deploy
31
+ env:
32
+ GITHUB_LOGIN: dry-bot
33
+ GITHUB_TOKEN: ${{ secrets.GH_PAT }}
34
+ run: bin/ossy github workflow dry-rb/dry-rb.org ci
@@ -0,0 +1,34 @@
1
+ # this file is managed by dry-rb/devtools project
2
+
3
+ name: sync_configs
4
+
5
+ on:
6
+ repository_dispatch:
7
+
8
+ jobs:
9
+ sync-configs:
10
+ runs-on: ubuntu-latest
11
+ if: github.event.action == 'sync_configs'
12
+ steps:
13
+ - uses: actions/checkout@v1
14
+ - name: Update configuration files from devtools
15
+ env:
16
+ GITHUB_LOGIN: dry-bot
17
+ GITHUB_TOKEN: ${{ secrets.GH_PAT }}
18
+ run: |
19
+ git clone https://github.com/dry-rb/devtools.git tmp/devtools
20
+
21
+ if [ -f ".github/workflows/custom_ci.yml" ]; then
22
+ rsync -av --exclude '.github/workflows/ci.yml' tmp/devtools/shared/ . ;
23
+ else
24
+ rsync -av tmp/devtools/shared/ . ;
25
+ fi
26
+
27
+ git config --local user.email "dry-bot@dry-rb.org"
28
+ git config --local user.name "dry-bot"
29
+ git add -A
30
+ git commit -m "[devtools] config sync" || echo "nothing changed"
31
+ - name: Push changes
32
+ uses: ad-m/github-push-action@master
33
+ with:
34
+ github_token: ${{ secrets.GH_PAT }}
data/.gitignore CHANGED
@@ -8,3 +8,4 @@
8
8
  /spec/reports/
9
9
  /tmp/
10
10
  log/
11
+
data/.rspec CHANGED
@@ -1,2 +1,4 @@
1
1
  --color
2
- --require ./spec/spec_helper
2
+ --require spec_helper
3
+ --order random
4
+
data/.rubocop.yml ADDED
@@ -0,0 +1,89 @@
1
+ # this file is managed by dry-rb/devtools project
2
+
3
+ AllCops:
4
+ TargetRubyVersion: 2.4
5
+
6
+ Style/EachWithObject:
7
+ Enabled: false
8
+
9
+ Style/StringLiterals:
10
+ Enabled: true
11
+ EnforcedStyle: single_quotes
12
+
13
+ Style/Alias:
14
+ Enabled: false
15
+
16
+ Style/LambdaCall:
17
+ Enabled: false
18
+
19
+ Style/StabbyLambdaParentheses:
20
+ Enabled: false
21
+
22
+ Style/FormatString:
23
+ Enabled: false
24
+
25
+ Style/Documentation:
26
+ Enabled: false
27
+
28
+ Layout/SpaceInLambdaLiteral:
29
+ Enabled: false
30
+
31
+ Layout/MultilineMethodCallIndentation:
32
+ Enabled: true
33
+ EnforcedStyle: indented
34
+
35
+ Metrics/LineLength:
36
+ Max: 100
37
+
38
+ Metrics/MethodLength:
39
+ Max: 22
40
+
41
+ Metrics/ClassLength:
42
+ Max: 150
43
+
44
+ Metrics/AbcSize:
45
+ Max: 20
46
+
47
+ Metrics/BlockLength:
48
+ Enabled: false
49
+
50
+ Metrics/CyclomaticComplexity:
51
+ Enabled: true
52
+ Max: 10
53
+
54
+ Lint/BooleanSymbol:
55
+ Enabled: false
56
+
57
+ Style/AccessModifierDeclarations:
58
+ Enabled: false
59
+
60
+ Style/BlockDelimiters:
61
+ Enabled: false
62
+
63
+ Layout/IndentFirstArrayElement:
64
+ EnforcedStyle: consistent
65
+
66
+ Style/ClassAndModuleChildren:
67
+ Exclude:
68
+ - "spec/**/*_spec.rb"
69
+
70
+ Lint/HandleExceptions:
71
+ Exclude:
72
+ - "spec/spec_helper.rb"
73
+
74
+ Naming/FileName:
75
+ Exclude:
76
+ - "lib/dry-*.rb"
77
+
78
+ Style/SymbolArray:
79
+ Exclude:
80
+ - "spec/**/*_spec.rb"
81
+
82
+ Style/ConditionalAssignment:
83
+ Enabled: false
84
+
85
+ Naming/MethodName:
86
+ Enabled: false
87
+
88
+ Style/AsciiComments:
89
+ Enabled: false
data/.yardopts CHANGED
@@ -1,5 +1,9 @@
1
1
  --title 'dry-types'
2
- --markup markdown
2
+ --query '@api.text != "private"'
3
+ --embed-mixins
4
+ --output doc
3
5
  --readme README.md
4
- --private
6
+ --files CHANGELOG.md
7
+ --markup markdown
8
+ --markup-provider=redcarpet
5
9
  lib/**/*.rb
data/CHANGELOG.md CHANGED
@@ -1,6 +1,309 @@
1
+ # 1.2.1 2019-11-07
2
+
3
+ ## Fixed
4
+
5
+ - Fix keyword warnings reported by Ruby 2.7 (flash-gordon)
6
+ - Error type in failing case in `Array::Member` (esparta)
7
+
8
+ [Compare v1.2.0...v1.2.1](https://github.com/dry-rb/dry-types/compare/v1.2.0...v1.2.1)
9
+
10
+ # 1.2.0 2019-10-06
11
+
12
+ ## Changed
13
+
14
+ - `Dry::Types.[]` used to work with classes, now it's deprecated (flash-gordon)
15
+
16
+ ## Fixed
17
+
18
+ - Bug with using a `Bool`-named struct as a schema key (flash-gordon)
19
+ - A bunch of issues related to using `meta` on complex types (flash-gordon)
20
+ - `Types.Constructor(...)` returns a `Types::Array` as it should (flash-gordon)
21
+
22
+ ## Added
23
+
24
+ - `Optional::Params` types that coerce empty strings to `nil` (flash-gordon)
25
+ ```ruby
26
+ Dry::Types['optional.params.integer'].('') # => nil
27
+ Dry::Types['optional.params.integer'].('140') # => 140
28
+ Dry::Types['optional.params.integer'].('asd') # => exception!
29
+ ```
30
+ Keep in mind, `Dry::Types['optional.params.integer']` and `Dry::Types['params.integer'].optional` are not the same, the latter doesn't handle empty strings.
31
+ - Predicate inferrer was ported from dry-schema (authored by solnic)
32
+ ```ruby
33
+ require 'dry/types/predicate_inferrer'
34
+ Dry::Types::PredicateInferrer.new[Types::String]
35
+ # => [:str?]
36
+ Dry::Types::PredicateInferrer.new[Types::String | Types::Integer]
37
+ # => [[[:str?], [:int?]]]
38
+ ```
39
+ Note that the API of the predicate inferrer can change in the stable version, it's dictated by the needs of dry-schema so it should be considered as semi-stable. If you depend on it, write specs covering the desired behavior. Another option is copy-and-paste the whole thing to your project.
40
+ - Primitive inferrer was ported from dry-schema (authored by solnic)
41
+ ```ruby
42
+ require 'dry/types/primitive_inferrer'
43
+ Dry::Types::PrimitiveInferrer.new[Types::String]
44
+ # => [String]
45
+ Dry::Types::PrimitiveInferrer.new[Types::String | Types::Integer]
46
+ # => [String, Integer]
47
+ Dry::Types::PrimitiveInferrer.new[Types::String.optional]
48
+ # => [NilClass, String]
49
+ ```
50
+ The primitive inferrer should be stable by now, you can rely on it.
51
+ - The `monads` extension adds `Dry::Types::Result#to_monad`. This makes it compatible with do notation from dry-monads. Load it with `Dry::Types.load_extensions(:monads)` (skryukov)
52
+
53
+ ```ruby
54
+ Types = Dry.Types
55
+ Dry::Types.load_extensions(:monads)
56
+
57
+ class AddTen
58
+ include Dry::Monads[:result, :do]
59
+
60
+ def call(input)
61
+ integer = yield Types::Coercible::Integer.try(input)
62
+
63
+ Success(integer + 10)
64
+ end
65
+ end
66
+ ```
67
+
68
+ [Compare v1.1.1...v1.2.0](https://github.com/dry-rb/dry-types/compare/v1.1.1...v1.2.0)
69
+
70
+ # 1.1.1 2019-07-26
71
+
72
+ ## Fixed
73
+
74
+ - A bug where meta was lost for lax array types (flash-gordon)
75
+
76
+ [Compare v1.1.0...v1.1.1](https://github.com/dry-rb/dry-types/compare/v1.1.0...v1.1.1)
77
+
78
+ # 1.1.0 2019-07-02
79
+
80
+ ## Added
81
+
82
+ - New builder method `Interface` constructs a type which accepts objects that respond to the given methods (waiting-for-dev)
83
+ ```ruby
84
+ Types = Dry.Types()
85
+ Types::Callable = Types.Interface(:call)
86
+ Types::Callable.valid?(Object.new) # => false
87
+ Types::Callable.valid?(proc {}) # => true
88
+ ```
89
+ - New types: `coercible.symbol`, `params.symbol`, and `json.symbol`, all use `.to_sym` for coercion (waiting-for-dev)
90
+
91
+ ## Fixed
92
+
93
+ - Converting schema keys to maybe types (flash-gordon)
94
+ - Using `Schema#key` and `Array#member` on constuctors (flash-gordon)
95
+ - Using `meta(omittable: true)` within `transform_types` works again but produces a warning, please migrate to `.omittable` or `.required(false)` (flash-gordon)
96
+ - Bug with a constructror defined on top of enum (flash-gordon)
97
+
98
+ [Compare v1.0.1...v1.1.0](https://github.com/dry-rb/dry-types/compare/v1.0.1...v1.1.0)
99
+
100
+ # 1.0.1 2019-06-04
101
+
102
+ ## Added
103
+
104
+ - In a case of failure the constructor block can now pass a different value (flash-gordon)
105
+ ```ruby
106
+ not_empty_string = Types::String.constructor do |value, &failure|
107
+ value.strip.empty? ? failure.(nil) : value.strip
108
+ end
109
+ not_empty_string.(' ') { |v| v } # => nil
110
+ not_empty_string.lax.(' ') # => nil
111
+ not_empty_string.lax.(' foo ') # => "foo"
112
+ ```
113
+ - `Schema#strict` now accepts an boolean argument. If `fales` is passed this will turn a strict schema into a non-strict one (flash-gordon)
114
+
115
+ [Compare v1.0.0...v1.0.1](https://github.com/dry-rb/dry-types/compare/v1.0.0...v1.0.1)
116
+
117
+ # 1.0.0 2019-04-23
118
+
119
+ ## Changed
120
+
121
+ - [BREAKING] Behavior of built-in constructor types was changed to be more strict. They will always raise an error on failed coercion (flash-gordon)
122
+ Compare:
123
+
124
+ ```ruby
125
+ # 0.15.0
126
+ Types::Params::Integer.('foo')
127
+ # => "foo"
128
+
129
+ # 1.0.0
130
+ Types::Params::Integer.('foo')
131
+ # => Dry::Types::CoercionError: invalid value for Integer(): "foo"
132
+ ```
133
+
134
+ To handle coercion errors `Type#call` now yields a block:
135
+
136
+ ```ruby
137
+ Types::Params::Integer.('foo') { :invalid } # => :invalid
138
+ ```
139
+
140
+ This makes work with coercions more straightforward and way faster.
141
+
142
+ - [BREAKING] Safe types were renamed to Lax, this name better serves their purpose. The previous name is available but prints a warning (flash-gordon)
143
+ - [BREAKING] Metadata is now pushed down to the decorated type. It is not likely you will notice a difference but this a breaking change that enables some use cases in rom related to the usage of default types in relations (flash-gordon)
144
+ - Nominal types are now completely unconstrained. This fixes some inconsistencies when using them with constraints. `Nominal#try` will always return a successful result, for the previous behavior use `Nominal#try_coerce` or switch to strict types with passing a block to `#call` (flash-gordon)
145
+
146
+ ## Performance improvements
147
+
148
+ - During the work on this release, a lot of performance improvements were made. dry-types 1.0 combined with dry-logic 1.0 are multiple times faster than dry-types 0.15 and dry-logic 0.5 for common cases including constraints checking and coercion (flash-gordon)
149
+
150
+ ## Added
151
+
152
+ - API for custom constructor types was enhanced. If you pass your own callable to `.constructor` it can have a block in its signature. If a block is passed, you must call it on failed coercion, otherwise raise a type coercion error (flash-gordon)
153
+ Example:
154
+ ```ruby
155
+ proc do |input, &block|
156
+ if input.is_a? String
157
+ Integer(input, 10)
158
+ else
159
+ Integer(input)
160
+ end
161
+ rescue ArgumentError, TypeError => error
162
+ if block
163
+ block.call
164
+ else
165
+ raise Dry::Types::CoercionError.new(
166
+ error.message,
167
+ backtrace: error.backtrace
168
+ )
169
+ end
170
+ end
171
+ ```
172
+ This makes the exception handling your job so that dry-types won't have to catch and re-wrap all possible errors (this is not safe, generally speaking).
173
+ - Types now can be converted to procs thus you can pass them as blocks (flash-gordon)
174
+ ```ruby
175
+ %w(1 2 3).map(&Types::Coercible::Integer)
176
+ # => [1, 2, 3]
177
+ ```
178
+
179
+ [Compare v0.15.0...v1.0.0](https://github.com/dry-rb/dry-types/compare/v0.15.0...v1.0.0)
180
+
181
+ # 0.15.0 2019-03-22
182
+
183
+ ## Changed
184
+
185
+ - [BREAKING] Internal representation of hash schemas was changed to be a simple list of key types (flash-gordon)
186
+ `Dry::Types::Hash#with_type_transform` now yields a key type instead of type + name:
187
+ ```ruby
188
+ Dry::Types['strict.hash'].with_type_transform { |key| key.name == :age ? key.required(false) : key }
189
+ ```
190
+ - [BREAKING] Definition types were renamed to nominal (flash-gordon)
191
+ - [BREAKING] Top-level types returned by `Dry::Types.[]` are now strict (flash-gordon)
192
+ ```ruby
193
+ # before
194
+ Dry::Types['integer']
195
+ # => #<Dry::Types[Nominal<Integer>]>
196
+ # now
197
+ Dry::Types['integer']
198
+ # => <Dry::Types[Constrained<Nominal<Integer> rule=[type?(Integer)]>]>
199
+ # you can still access nominal types using namespace
200
+ Dry::Types['nominal.integer']
201
+ # => #<Dry::Types[Nominal<Integer>]>
202
+ ```
203
+ - [BREAKING] Default values are not evaluated if the decorated type returns `nil`. They are triggered on `Undefined` instead (GustavoCaso + flash-gordon)
204
+ - [BREAKING] Support for old hash schemas was fully removed. This makes dry-types not compatible with dry-validation < 1.0 (flash-gordon)
205
+ - `Dry::Types.module` is deprecated in favor of `Dry.Types` (flash-gordon)
206
+ Keep in mind `Dry.Types` uses strict types for top-level names, that is after
207
+ ```ruby
208
+ module Types
209
+ include Dry.Types
210
+ end
211
+ ```
212
+ `Types::Integer` is a strict type. If you want it to be nominal, use `include Dry.Types(default: :nominal)`. See other options below.
213
+ - `params.integer` now always converts strings to decimal numbers, this means `09` will be coerced to `9` (threw an error before) (skryukov)
214
+ - Ruby 2.3 is EOL and not officially supported. It may work but we don't test it.
215
+
216
+ ## Added
217
+
218
+ - Improved string representation of types (flash-gordon)
219
+ ```ruby
220
+ Dry::Types['nominal.integer']
221
+ # => #<Dry::Types[Nominal<Integer>]>
222
+ Dry::Types['params.integer']
223
+ # => #<Dry::Types[Constructor<Nominal<Integer> fn=Dry::Types::Coercions::Params.to_int>]>
224
+ Dry::Types['hash'].schema(age?: 'integer')
225
+ # => #<Dry::Types[Constrained<Schema<keys={age?: Constrained<Nominal<Integer> rule=[type?(Integer)]>}> rule=[type?(Hash)]>]>
226
+ Dry::Types['array<integer>']
227
+ # => #<Dry::Types[Constrained<Array<Constrained<Nominal<Integer> rule=[type?(Integer)]>> rule=[type?(Array)]>]>
228
+ ```
229
+ - Options for the list of types you want to import with `Dry.Types` (flash-gordon)
230
+ Cherry-pick only certain types:
231
+ ```ruby
232
+ module Types
233
+ include Dry.Types(:strict, :nominal, :coercible)
234
+ end
235
+ Types.constants
236
+ # => [:Strict, :Nominal, :Coercible]
237
+ ```
238
+ Change default top-level types:
239
+ ```ruby
240
+ module Types
241
+ include Dry.Types(default: :coercible)
242
+ end
243
+ # => #<Dry::Types[Constructor<Nominal<Integer> fn=Kernel.Integer>]>
244
+ ```
245
+ Rename type namespaces:
246
+ ```ruby
247
+ module Types
248
+ include Dry.Types(strict: :Strong, coercible: :Kernel)
249
+ end
250
+ ```
251
+ - Optional keys for schemas can be provided with ?-ending symbols (flash-gordon)
252
+ ```ruby
253
+ Dry::Types['hash'].schema(name: 'string', age?: 'integer')
254
+ ```
255
+ - Another way of making keys optional is setting `required: false` to meta. In fact, it is the preferable
256
+ way if you have to store this information in `meta`, otherwise use the Key's API (see below) (flash-gordon)
257
+ ```ruby
258
+ Dry::Types['hash'].schema(
259
+ name: Dry::Types['string'],
260
+ age: Dry::Types['integer'].meta(required: false)
261
+ )
262
+ ```
263
+ - Key types have API for making keys omittable and back (flash-gordon)
264
+
265
+ ```ruby
266
+ # defining a base schema with optional keys
267
+ lax_hash = Dry::Types['hash'].with_type_transform { |key| key.required(false) }
268
+ # same as
269
+ lax_hash = Dry::Types['hash'].with_type_transform(&:omittable)
270
+
271
+ # keys in user_schema are not required
272
+ user_schema = lax_hash.schema(name: 'string', age: 'integer')
273
+ ```
274
+
275
+ - `Type#optional?` now recognizes more cases where `nil` is an allowed value (flash-gordon)
276
+ - `Constructor#{prepend,append}` with `<<` and `>>` as aliases. `Constructor#append` works the same way `Constructor#constrcutor` does. `Constuctor#prepend` chains functions in the reverse order, see examples (flash-gordon)
277
+
278
+ ```ruby
279
+ to_int = Types::Coercible::Integer
280
+ inc = to_int.append { |x| x + 2 }
281
+ inc.("1") # => "1" -> 1 -> 3
282
+
283
+ inc = to_int.prepend { |x| x + "2" }
284
+ inc.("1") # => "1" -> "12" -> 12
285
+ ```
286
+
287
+ - Partial schema application for cases when you want to validate only a subset of keys (flash-gordon)
288
+ This is useful when you want to update a key or two in an already-validated hash. A perfect example is `Dry::Struct#new` where this feature is now used.
289
+ ```ruby
290
+ schema = Dry::Types['hash'].schema(name: 'string', age: 'integer')
291
+ value = schema.(name: 'John', age: 20)
292
+ update = schema.apply({ age: 21 }, skip_missing: true)
293
+ value.merge(update)
294
+ ```
295
+
296
+ ## Fixed
297
+
298
+ - `Hash::Map` now behaves as a constrained type if its values are constrained (flash-gordon)
299
+ - `coercible.integer` now doesn't blow up on invalid strings (exterm)
300
+
301
+ [Compare v0.14.0...v0.15.0](https://github.com/dry-rb/dry-types/compare/v0.14.0...v0.15.0)
302
+
1
303
  # v0.14.1 2019-03-25
2
304
 
3
305
  ## Fixed
306
+
4
307
  - `coercible.integer` now doesn't blow up on invalid strings (exterm)
5
308
 
6
309
  [Compare v0.14.0...v0.14.1](https://github.com/dry-rb/dry-types/compare/v0.14.0...v0.14.1)