dry-struct 1.1.1 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.codeclimate.yml +12 -0
- data/.github/ISSUE_TEMPLATE/---bug-report.md +1 -5
- data/.github/workflows/ci.yml +74 -0
- data/.github/workflows/docsite.yml +34 -0
- data/.github/workflows/sync_configs.yml +34 -0
- data/.rspec +3 -1
- data/.rubocop.yml +95 -0
- data/CHANGELOG.md +9 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/CONTRIBUTING.md +3 -3
- data/Gemfile +1 -0
- data/LICENSE +17 -17
- data/README.md +2 -2
- data/docsite/source/index.html.md +3 -1
- data/dry-struct.gemspec +1 -1
- data/lib/dry/struct.rb +7 -6
- data/lib/dry/struct/class_interface.rb +22 -16
- data/lib/dry/struct/struct_builder.rb +14 -13
- data/lib/dry/struct/value.rb +12 -1
- data/lib/dry/struct/version.rb +1 -1
- metadata +10 -5
- data/.travis.yml +0 -24
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5903d3760fd689eec22fc3e95cc6d8bed946bb9e23ca9875474dda901e5ac1a9
|
4
|
+
data.tar.gz: b0386bae928cf63becfcc7ae2e46384acfe6fc40f01b65d35dd189d300ccb27e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 55e27a71675e579b9d7a6732bf9535c8a2a044ff730ef2512b6c30f82b23893abf4f4652812a4bdcbe3b034c821f320031618f09023e7b32d9d9855963b2a7f2
|
7
|
+
data.tar.gz: 44bfe008840f54162d65399b29ea7073faced71559fa76beaed57faf40a74808e1fa148574eb08225eeb5bff46da5851ec37829a58235bc5aa8f4c3c3913eb03
|
data/.codeclimate.yml
ADDED
@@ -9,11 +9,7 @@ assignees: ''
|
|
9
9
|
|
10
10
|
**Before you submit this: WE ONLY ACCEPT BUG REPORTS AND FEATURE REQUESTS**
|
11
11
|
|
12
|
-
For more information see
|
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.
|
12
|
+
For more information see `CONTRIBUTING.md`.
|
17
13
|
|
18
14
|
**Describe the bug**
|
19
15
|
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# this file is managed by dry-rb/devtools project
|
2
|
+
|
3
|
+
name: ci
|
4
|
+
|
5
|
+
on:
|
6
|
+
push:
|
7
|
+
paths:
|
8
|
+
- .github/workflows/ci.yml
|
9
|
+
- lib/**
|
10
|
+
- spec/**
|
11
|
+
- Gemfile
|
12
|
+
- "*.gemspec"
|
13
|
+
|
14
|
+
jobs:
|
15
|
+
tests-mri:
|
16
|
+
runs-on: ubuntu-latest
|
17
|
+
strategy:
|
18
|
+
fail-fast: false
|
19
|
+
matrix:
|
20
|
+
ruby: ["2.6.x", "2.5.x", "2.4.x"]
|
21
|
+
include:
|
22
|
+
- ruby: "2.6.x"
|
23
|
+
coverage: "true"
|
24
|
+
steps:
|
25
|
+
- uses: actions/checkout@v1
|
26
|
+
- name: Set up Ruby
|
27
|
+
uses: actions/setup-ruby@v1
|
28
|
+
with:
|
29
|
+
ruby-version: ${{matrix.ruby}}
|
30
|
+
- name: Download test reporter
|
31
|
+
if: "matrix.coverage == 'true'"
|
32
|
+
run: |
|
33
|
+
mkdir -p tmp/
|
34
|
+
curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./tmp/cc-test-reporter
|
35
|
+
chmod +x ./tmp/cc-test-reporter
|
36
|
+
./tmp/cc-test-reporter before-build
|
37
|
+
- name: Run all tests
|
38
|
+
env:
|
39
|
+
COVERAGE: ${{matrix.coverage}}
|
40
|
+
run: |
|
41
|
+
gem install bundler
|
42
|
+
bundle install --jobs 4 --retry 3 --without tools docs benchmarks
|
43
|
+
bundle exec rake
|
44
|
+
- name: Send coverage results
|
45
|
+
if: "matrix.coverage == 'true'"
|
46
|
+
env:
|
47
|
+
CC_TEST_REPORTER_ID: ${{secrets.CC_TEST_REPORTER_ID}}
|
48
|
+
GIT_COMMIT_SHA: ${{github.sha}}
|
49
|
+
GIT_BRANCH: ${{github.ref}}
|
50
|
+
GIT_COMMITTED_AT: ${{github.event.head_commit.timestamp}}
|
51
|
+
run: |
|
52
|
+
GIT_BRANCH=`ruby -e "puts ENV['GITHUB_REF'].split('/', 3).last"` \
|
53
|
+
GIT_COMMITTED_AT=`ruby -r time -e "puts Time.iso8601(ENV['GIT_COMMITTED_AT']).to_i"` \
|
54
|
+
./tmp/cc-test-reporter after-build
|
55
|
+
|
56
|
+
tests-others:
|
57
|
+
runs-on: ubuntu-latest
|
58
|
+
strategy:
|
59
|
+
fail-fast: false
|
60
|
+
matrix:
|
61
|
+
image: ["jruby:9.2.8", "ruby:rc"]
|
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
|
+
run: |
|
72
|
+
gem install bundler
|
73
|
+
bundle install --jobs 4 --retry 3 --without tools docs benchmarks
|
74
|
+
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/.rspec
CHANGED
data/.rubocop.yml
ADDED
@@ -0,0 +1,95 @@
|
|
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
|
90
|
+
|
91
|
+
Style/DateTime:
|
92
|
+
Enabled: false
|
93
|
+
|
94
|
+
Style/IfUnlessModifier:
|
95
|
+
Enabled: false
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,12 @@
|
|
1
|
+
# 1.2.0 2019-12-20
|
2
|
+
|
3
|
+
## Changed
|
4
|
+
|
5
|
+
- `Dry::Struct::Value` is deprecated. `Dry::Struct` instances were never meant to be mutable, we have no support for this. The only difference between `Dry::Struct` and `Dry::Struct::Value` is that the latter is deeply frozen. Freezing objects slows the code down and gives you very little benefit in return. If you have a use case for `Value`, it won't be hard to roll your own solution using [ice_nine](https://github.com/dkubb/ice_nine) (flash-gordon)
|
6
|
+
- In the thread of the previous change, structs now use immutable equalizer. This means `Struct#hash` memoizes its value after the first invokation. Depending on the case, this may speed up your code significantly (flash-gordon)
|
7
|
+
|
8
|
+
[Compare v1.1.1...v1.2.0](https://github.com/dry-rb/dry-struct/compare/v1.1.1...v.1.2.0)
|
9
|
+
|
1
10
|
# 1.1.1 2019-10-13
|
2
11
|
|
3
12
|
## Changed
|
data/CODE_OF_CONDUCT.md
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# Contributor Code of Conduct
|
2
|
+
|
3
|
+
As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.
|
4
|
+
|
5
|
+
We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, age, or religion.
|
6
|
+
|
7
|
+
Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.
|
8
|
+
|
9
|
+
Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.
|
10
|
+
|
11
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.
|
12
|
+
|
13
|
+
This Code of Conduct is adapted from the [Contributor Covenant](http:contributor-covenant.org), version 1.4.0, available at [https://www.contributor-covenant.org/version/1/4/code-of-conduct](https://www.contributor-covenant.org/version/1/4/code-of-conduct)
|
data/CONTRIBUTING.md
CHANGED
@@ -6,11 +6,11 @@ If you found a bug, report an issue and describe what's the expected behavior ve
|
|
6
6
|
|
7
7
|
## Reporting feature requests
|
8
8
|
|
9
|
-
Report a feature request **only after
|
9
|
+
Report a feature request **only after discussing it first on [discourse.dry-rb.org](https://discourse.dry-rb.org)** where it was accepted. Please provide a concise description of the feature, don't link to a discussion thread, and instead summarize what was discussed.
|
10
10
|
|
11
11
|
## Reporting questions, support requests, ideas, concerns etc.
|
12
12
|
|
13
|
-
**PLEASE DON'T** - use [discourse.dry-rb.org](
|
13
|
+
**PLEASE DON'T** - use [discourse.dry-rb.org](http://discourse.dry-rb.org) instead.
|
14
14
|
|
15
15
|
# Pull Request Guidelines
|
16
16
|
|
@@ -26,4 +26,4 @@ Other requirements:
|
|
26
26
|
|
27
27
|
# Asking for help
|
28
28
|
|
29
|
-
If these guidelines aren't helpful, and you're stuck, please post a message on [discourse.dry-rb.org](https://discourse.dry-rb.org).
|
29
|
+
If these guidelines aren't helpful, and you're stuck, please post a message on [discourse.dry-rb.org](https://discourse.dry-rb.org) or join [our chat](https://dry-rb.zulipchat.com).
|
data/Gemfile
CHANGED
data/LICENSE
CHANGED
@@ -1,20 +1,20 @@
|
|
1
|
-
|
1
|
+
The MIT License (MIT)
|
2
2
|
|
3
|
-
|
4
|
-
a copy of this software and associated documentation files (the
|
5
|
-
"Software"), to deal in the Software without restriction, including
|
6
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
-
permit persons to whom the Software is furnished to do so, subject to
|
9
|
-
the following conditions:
|
3
|
+
Copyright (c) 2015-2019 dry-rb team
|
10
4
|
|
11
|
-
|
12
|
-
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
7
|
+
the Software without restriction, including without limitation the rights to
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
10
|
+
subject to the following conditions:
|
13
11
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
20
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
[gem]: https://rubygems.org/gems/dry-struct
|
2
|
-
[
|
2
|
+
[ci]: https://github.com/dry-rb/dry-struct/actions?query=workflow%3Aci
|
3
3
|
[codeclimate]: https://codeclimate.com/github/dry-rb/dry-struct
|
4
4
|
[inchpages]: http://inch-ci.org/github/dry-rb/dry-struct
|
5
5
|
[chat]: https://dry-rb.zulipchat.com
|
@@ -7,7 +7,7 @@
|
|
7
7
|
# dry-struct [![Join the chat at https://dry-rb.zulipchat.com](https://img.shields.io/badge/dry--rb-join%20chat-%23346b7a.svg)][chat]
|
8
8
|
|
9
9
|
[![Gem Version](https://badge.fury.io/rb/dry-struct.svg)][gem]
|
10
|
-
[![Build Status](https://
|
10
|
+
[![Build Status](https://github.com/dry-rb/dry-struct/workflows/ci/badge.svg)][ci]
|
11
11
|
[![Code Climate](https://codeclimate.com/github/dry-rb/dry-struct/badges/gpa.svg)][codeclimate]
|
12
12
|
[![Test Coverage](https://codeclimate.com/github/dry-rb/dry-struct/badges/coverage.svg)][codeclimate]
|
13
13
|
[![Inline docs](http://inch-ci.org/github/dry-rb/dry-struct.svg?branch=master)][inchpages]
|
@@ -39,6 +39,8 @@ user.age # => 21
|
|
39
39
|
|
40
40
|
### Value
|
41
41
|
|
42
|
+
:warning: `Dry::Struct::Value` is deprecated in 1.2.0. Structs are already meant to be immutable, freezing them doesn't add any value (no pun intended) beyond a bad example of defensive programming.
|
43
|
+
|
42
44
|
You can define value objects which will behave like structs but will be *deeply frozen*:
|
43
45
|
|
44
46
|
``` ruby
|
@@ -59,7 +61,7 @@ loc1 == loc2
|
|
59
61
|
|
60
62
|
### Hash Schemas
|
61
63
|
|
62
|
-
`Dry::Struct` out of the box uses [hash schemas](/gems/dry-types/hash-schemas) from `dry-types` for processing input hashes. `with_type_transform` and `with_key_transform` are exposed as `transform_types` and `transform_keys`:
|
64
|
+
`Dry::Struct` out of the box uses [hash schemas](/gems/dry-types/1.0/hash-schemas) from `dry-types` for processing input hashes. `with_type_transform` and `with_key_transform` are exposed as `transform_types` and `transform_keys`:
|
63
65
|
|
64
66
|
```ruby
|
65
67
|
class User < Dry::Struct
|
data/dry-struct.gemspec
CHANGED
@@ -29,7 +29,7 @@ Gem::Specification.new do |spec|
|
|
29
29
|
spec.require_paths = ['lib']
|
30
30
|
spec.required_ruby_version = ">= 2.4.0"
|
31
31
|
|
32
|
-
spec.add_runtime_dependency 'dry-equalizer', '~> 0.
|
32
|
+
spec.add_runtime_dependency 'dry-equalizer', '~> 0.3'
|
33
33
|
spec.add_runtime_dependency 'dry-types', '~> 1.0'
|
34
34
|
spec.add_runtime_dependency 'dry-core', '~> 0.4', '>= 0.4.3'
|
35
35
|
spec.add_runtime_dependency 'ice_nine', '~> 0.11'
|
data/lib/dry/struct.rb
CHANGED
@@ -82,11 +82,13 @@ module Dry
|
|
82
82
|
# refactoring.title #=> 'Refactoring'
|
83
83
|
# refactoring.subtitle #=> 'Improving the Design of Existing Code'
|
84
84
|
class Struct
|
85
|
-
extend
|
86
|
-
include
|
85
|
+
extend Core::Extensions
|
86
|
+
include Core::Constants
|
87
87
|
extend ClassInterface
|
88
88
|
|
89
|
-
|
89
|
+
autoload :Value, 'dry/struct/value'
|
90
|
+
|
91
|
+
include ::Dry::Equalizer(:__attributes__, inspect: false, immutable: true)
|
90
92
|
|
91
93
|
# {Dry::Types::Hash::Schema} subclass with specific behaviour defined for
|
92
94
|
# @return [Dry::Types::Hash::Schema]
|
@@ -173,7 +175,7 @@ module Dry
|
|
173
175
|
new_attributes = self.class.schema.apply(changeset, skip_missing: true, resolve_defaults: false)
|
174
176
|
self.class.load(__attributes__.merge(new_attributes))
|
175
177
|
rescue Types::SchemaError, Types::MissingKeyError, Types::UnknownKeysError => error
|
176
|
-
raise
|
178
|
+
raise Error, "[#{self}.new] #{error}"
|
177
179
|
end
|
178
180
|
alias_method :__new__, :new
|
179
181
|
|
@@ -181,7 +183,7 @@ module Dry
|
|
181
183
|
def inspect
|
182
184
|
klass = self.class
|
183
185
|
attrs = klass.attribute_names.map { |key| " #{key}=#{@attributes[key].inspect}" }.join
|
184
|
-
"#<#{
|
186
|
+
"#<#{klass.name || klass.inspect}#{attrs}>"
|
185
187
|
end
|
186
188
|
|
187
189
|
if RUBY_VERSION >= '2.7'
|
@@ -195,6 +197,5 @@ module Dry
|
|
195
197
|
end
|
196
198
|
end
|
197
199
|
|
198
|
-
require 'dry/struct/value'
|
199
200
|
require 'dry/struct/extensions'
|
200
201
|
require 'dry/struct/printer'
|
@@ -12,8 +12,8 @@ module Dry
|
|
12
12
|
module ClassInterface
|
13
13
|
include Core::ClassAttributes
|
14
14
|
|
15
|
-
include
|
16
|
-
include
|
15
|
+
include Types::Type
|
16
|
+
include Types::Builder
|
17
17
|
|
18
18
|
# @param [Class] klass
|
19
19
|
def inherited(klass)
|
@@ -24,8 +24,8 @@ module Dry
|
|
24
24
|
klass.class_eval do
|
25
25
|
@meta = base.meta
|
26
26
|
|
27
|
-
unless
|
28
|
-
extend
|
27
|
+
unless name.eql?('Dry::Struct::Value')
|
28
|
+
extend Core::DescendantsTracker
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
@@ -116,7 +116,7 @@ module Dry
|
|
116
116
|
#
|
117
117
|
def attribute?(*args, &block)
|
118
118
|
if args.size == 1 && block.nil?
|
119
|
-
|
119
|
+
Core::Deprecations.warn(
|
120
120
|
'Dry::Struct.attribute? is deprecated for checking attribute presence, '\
|
121
121
|
'use has_attribute? instead',
|
122
122
|
tag: :'dry-struct'
|
@@ -231,7 +231,7 @@ module Dry
|
|
231
231
|
load(schema.call_unsafe(attributes))
|
232
232
|
end
|
233
233
|
rescue Types::CoercionError => error
|
234
|
-
raise
|
234
|
+
raise Error, "[#{self}.new] #{error}"
|
235
235
|
end
|
236
236
|
|
237
237
|
# @api private
|
@@ -264,7 +264,7 @@ module Dry
|
|
264
264
|
# @param [#call,nil] block
|
265
265
|
# @return [Dry::Struct::Constructor]
|
266
266
|
def constructor(constructor = nil, **_options, &block)
|
267
|
-
|
267
|
+
Constructor.new(self, fn: constructor || block)
|
268
268
|
end
|
269
269
|
|
270
270
|
# @param [Hash{Symbol => Object},Dry::Struct] input
|
@@ -273,7 +273,7 @@ module Dry
|
|
273
273
|
# @return [Dry::Types::Result]
|
274
274
|
def try(input)
|
275
275
|
success(self[input])
|
276
|
-
rescue
|
276
|
+
rescue Error => e
|
277
277
|
failure_result = failure(input, e.message)
|
278
278
|
block_given? ? yield(failure_result) : failure_result
|
279
279
|
end
|
@@ -298,7 +298,7 @@ module Dry
|
|
298
298
|
# @param [({Symbol => Object})] args
|
299
299
|
# @return [Dry::Types::Result::Failure]
|
300
300
|
def failure(*args)
|
301
|
-
result(
|
301
|
+
result(Types::Result::Failure, *args)
|
302
302
|
end
|
303
303
|
|
304
304
|
# @param [Class] klass
|
@@ -359,7 +359,7 @@ module Dry
|
|
359
359
|
if meta.equal?(Undefined)
|
360
360
|
@meta
|
361
361
|
else
|
362
|
-
Class.new(self) do
|
362
|
+
::Class.new(self) do
|
363
363
|
@meta = @meta.merge(meta) unless meta.empty?
|
364
364
|
end
|
365
365
|
end
|
@@ -369,8 +369,8 @@ module Dry
|
|
369
369
|
# @param [Dry::Types::Type] type
|
370
370
|
# @return [Dry::Types::Sum]
|
371
371
|
def |(type)
|
372
|
-
if type.is_a?(Class) && type <= Struct
|
373
|
-
|
372
|
+
if type.is_a?(::Class) && type <= Struct
|
373
|
+
Sum.new(self, type)
|
374
374
|
else
|
375
375
|
super
|
376
376
|
end
|
@@ -399,7 +399,7 @@ module Dry
|
|
399
399
|
# @param [Dry::Types::Type] type
|
400
400
|
# @return [Boolean]
|
401
401
|
def struct?(type)
|
402
|
-
type.is_a?(Class) && type <= Struct
|
402
|
+
type.is_a?(::Class) && type <= Struct
|
403
403
|
end
|
404
404
|
private :struct?
|
405
405
|
|
@@ -408,11 +408,11 @@ module Dry
|
|
408
408
|
# @return [Dry::Types::Type, Dry::Struct]
|
409
409
|
def build_type(name, type, &block)
|
410
410
|
type_object =
|
411
|
-
if type.is_a?(String)
|
412
|
-
|
411
|
+
if type.is_a?(::String)
|
412
|
+
Types[type]
|
413
413
|
elsif block.nil? && type.nil?
|
414
414
|
raise(
|
415
|
-
ArgumentError,
|
415
|
+
::ArgumentError,
|
416
416
|
'you must supply a type or a block to `Dry::Struct.attribute`'
|
417
417
|
)
|
418
418
|
else
|
@@ -426,6 +426,12 @@ module Dry
|
|
426
426
|
end
|
427
427
|
end
|
428
428
|
private :build_type
|
429
|
+
|
430
|
+
# @api private
|
431
|
+
# @return [Boolean]
|
432
|
+
def value?
|
433
|
+
false
|
434
|
+
end
|
429
435
|
end
|
430
436
|
end
|
431
437
|
end
|
@@ -3,11 +3,11 @@ require 'dry/types/compiler'
|
|
3
3
|
module Dry
|
4
4
|
class Struct
|
5
5
|
# @private
|
6
|
-
class StructBuilder <
|
6
|
+
class StructBuilder < Types::Compiler
|
7
7
|
attr_reader :struct
|
8
8
|
|
9
9
|
def initialize(struct)
|
10
|
-
super(
|
10
|
+
super(Types)
|
11
11
|
@struct = struct
|
12
12
|
end
|
13
13
|
|
@@ -18,7 +18,7 @@ module Dry
|
|
18
18
|
const_name = const_name(type, attr_name)
|
19
19
|
check_name(const_name)
|
20
20
|
|
21
|
-
new_type = Class.new(parent(type), &block)
|
21
|
+
new_type = ::Class.new(parent(type), &block)
|
22
22
|
struct.const_set(const_name, new_type)
|
23
23
|
|
24
24
|
if array?(type)
|
@@ -31,7 +31,7 @@ module Dry
|
|
31
31
|
private
|
32
32
|
|
33
33
|
def array?(type)
|
34
|
-
type.is_a?(Types::Type) && type.primitive.equal?(Array)
|
34
|
+
type.is_a?(Types::Type) && type.primitive.equal?(::Array)
|
35
35
|
end
|
36
36
|
|
37
37
|
def parent(type)
|
@@ -43,22 +43,23 @@ module Dry
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def default_superclass
|
46
|
-
struct
|
46
|
+
struct.value? ? Value : Struct
|
47
47
|
end
|
48
48
|
|
49
49
|
def const_name(type, attr_name)
|
50
|
-
snake_name =
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
50
|
+
snake_name =
|
51
|
+
if array?(type)
|
52
|
+
Core::Inflector.singularize(attr_name)
|
53
|
+
else
|
54
|
+
attr_name
|
55
|
+
end
|
56
|
+
|
57
|
+
Core::Inflector.camelize(snake_name)
|
57
58
|
end
|
58
59
|
|
59
60
|
def check_name(name)
|
60
61
|
raise(
|
61
|
-
|
62
|
+
Error,
|
62
63
|
"Can't create nested attribute - `#{struct}::#{name}` already defined"
|
63
64
|
) if struct.const_defined?(name, false)
|
64
65
|
end
|
data/lib/dry/struct/value.rb
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
require 'ice_nine'
|
2
|
+
require 'dry/core/deprecations'
|
2
3
|
|
3
4
|
module Dry
|
4
5
|
class Struct
|
6
|
+
extend Core::Deprecations[:'dry-struct']
|
7
|
+
|
5
8
|
# {Value} objects behave like {Struct}s but *deeply frozen*
|
6
9
|
# using [`ice_nine`](https://github.com/dkubb/ice_nine)
|
7
10
|
#
|
@@ -24,8 +27,16 @@ module Dry
|
|
24
27
|
# @return [Value]
|
25
28
|
# @see https://github.com/dkubb/ice_nine
|
26
29
|
def self.new(*)
|
27
|
-
IceNine.deep_freeze(super)
|
30
|
+
::IceNine.deep_freeze(super)
|
31
|
+
end
|
32
|
+
|
33
|
+
# @api private
|
34
|
+
# @return [Boolean]
|
35
|
+
def self.value?
|
36
|
+
true
|
28
37
|
end
|
29
38
|
end
|
39
|
+
|
40
|
+
deprecate_constant :Value
|
30
41
|
end
|
31
42
|
end
|
data/lib/dry/struct/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dry-struct
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Piotr Solnica
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-12-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dry-equalizer
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '0.
|
19
|
+
version: '0.3'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '0.
|
26
|
+
version: '0.3'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: dry-types
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -135,14 +135,19 @@ executables: []
|
|
135
135
|
extensions: []
|
136
136
|
extra_rdoc_files: []
|
137
137
|
files:
|
138
|
+
- ".codeclimate.yml"
|
138
139
|
- ".github/ISSUE_TEMPLATE/----please-don-t-ask-for-support-via-issues.md"
|
139
140
|
- ".github/ISSUE_TEMPLATE/---bug-report.md"
|
140
141
|
- ".github/ISSUE_TEMPLATE/---feature-request.md"
|
142
|
+
- ".github/workflows/ci.yml"
|
143
|
+
- ".github/workflows/docsite.yml"
|
144
|
+
- ".github/workflows/sync_configs.yml"
|
141
145
|
- ".gitignore"
|
142
146
|
- ".rspec"
|
143
|
-
- ".
|
147
|
+
- ".rubocop.yml"
|
144
148
|
- ".yardopts"
|
145
149
|
- CHANGELOG.md
|
150
|
+
- CODE_OF_CONDUCT.md
|
146
151
|
- CONTRIBUTING.md
|
147
152
|
- Gemfile
|
148
153
|
- LICENSE
|
data/.travis.yml
DELETED
@@ -1,24 +0,0 @@
|
|
1
|
-
language: ruby
|
2
|
-
dist: trusty
|
3
|
-
sudo: required
|
4
|
-
bundler_args: --without benchmarks tools
|
5
|
-
script:
|
6
|
-
- bundle exec rspec spec
|
7
|
-
after_success:
|
8
|
-
- "[ -d coverage ] && bundle exec codeclimate-test-reporter"
|
9
|
-
rvm:
|
10
|
-
- 2.4.9
|
11
|
-
- 2.5.7
|
12
|
-
- 2.6.5
|
13
|
-
- 2.7
|
14
|
-
- jruby-9.2.8.0
|
15
|
-
- truffleruby
|
16
|
-
env:
|
17
|
-
global:
|
18
|
-
- COVERAGE=true
|
19
|
-
- JRUBY_OPTS='--dev -J-Xmx1024M'
|
20
|
-
matrix:
|
21
|
-
allow_failures:
|
22
|
-
- rvm: truffleruby
|
23
|
-
notifications:
|
24
|
-
email: false
|