dry-data 0.1.0 → 0.2.0

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
  SHA1:
3
- metadata.gz: 63d84521c44133ae20569f13cfe37198d145b84b
4
- data.tar.gz: 34a54445feeb95d3caffec626f3cca303eaa3455
3
+ metadata.gz: 66f872c57c14fed55be62785dabd619e72cf79ff
4
+ data.tar.gz: 663d9e422d10619df80ff448ecc268c66651586a
5
5
  SHA512:
6
- metadata.gz: c4ed0e1ca95bdb0e7d07dd744480da21d0316d96a43dc9e52e35963edbbc45f4eca370b4116a5ef4db51f6c0dda8e68b8f0b836ab1235fd7b2850ecfaa4f4558
7
- data.tar.gz: 87f09d1e60fbfef3a96750561ef81e354ced647d6e4371d02e49fd204e6229684b50e194f7ed3c6cf8c8d312e1d329b60de0f876f5a5cfca1fed9ffafb92cfe7
6
+ metadata.gz: e675b8735a351ec4f5d086cbc51eeb64a1f1d06ad28d3b96e09024ee076eef687cac70cc209afc63b6bc463f73ebe2f8c6dbdb86159befed7fb61e40d7610282
7
+ data.tar.gz: a44e721d53be8ff1e25c34e95acd174bf15982199e5bcd9626f4aaa608c022658454a3e03f3d5260f6011e839cd7c37d84b0996224cb1bd54835e616c88d8ec2
data/CHANGELOG.md CHANGED
@@ -1,3 +1,17 @@
1
+ # v0.2.0 2015-11-29
2
+
3
+ ## Added
4
+
5
+ * `form.nil` which coerces empty strings to `nil` (solnic)
6
+ * `bool` sum-type (true | false) (solnic)
7
+ * Type compiler supports sum-types now (solnic)
8
+
9
+ ## Changed
10
+
11
+ * Constructing optional types uses the new `Dry::Data["optional"]` built-in type (solnic)
12
+
13
+ [Compare v0.1.0...v0.2.0](https://github.com/dryrb/dry-data/compare/v0.1.0...v0.2.0)
14
+
1
15
  # v0.1.0 2015-11-27
2
16
 
3
17
  ## Added
data/README.md CHANGED
@@ -117,7 +117,7 @@ maybe_int['12.3'] # Some(12.3)
117
117
  You can define your own optional types too:
118
118
 
119
119
  ``` ruby
120
- maybe_string = Dry::Data["nil"] | Dry::Data["string"]
120
+ maybe_string = Dry::Data["optional"] | Dry::Data["string"]
121
121
 
122
122
  maybe_string[nil]
123
123
  # => None
@@ -10,6 +10,14 @@ module Dry
10
10
  FALSE_VALUES = %w[0 off f false n no].freeze
11
11
  BOOLEAN_MAP = Hash[TRUE_VALUES.product([true]) + FALSE_VALUES.product([false])].freeze
12
12
 
13
+ def self.to_nil(input)
14
+ if input.is_a?(String) && input == ''
15
+ nil
16
+ else
17
+ input
18
+ end
19
+ end
20
+
13
21
  def self.to_date(input)
14
22
  Date.parse(input)
15
23
  rescue ArgumentError
@@ -1,10 +1,10 @@
1
1
  module Dry
2
2
  module Data
3
3
  class Compiler
4
- attr_reader :types
4
+ attr_reader :registry
5
5
 
6
- def initialize(types)
7
- @types = types
6
+ def initialize(registry)
7
+ @registry = registry
8
8
  end
9
9
 
10
10
  def call(ast)
@@ -21,18 +21,18 @@ module Dry
21
21
  if args
22
22
  send(:"visit_#{type}", args)
23
23
  else
24
- types[type]
24
+ registry[type]
25
25
  end
26
26
  end
27
27
 
28
28
  def visit_hash(node)
29
29
  constructor, schema = node
30
- types['hash'].public_send(constructor, schema.map { |key| visit(key) }.reduce(:merge))
30
+ registry['hash'].public_send(constructor, schema.map { |key| visit(key) }.reduce(:merge))
31
31
  end
32
32
 
33
33
  def visit_key(node)
34
- name, type = node
35
- { name => type }
34
+ name, types = node
35
+ { name => types.map { |id| registry[id] }.reduce(:|) }
36
36
  end
37
37
  end
38
38
  end
@@ -4,7 +4,7 @@ module Dry
4
4
  module Data
5
5
  def self.SumType(left, right)
6
6
  klass =
7
- if left.primitive == NilClass
7
+ if left.is_a?(Type::Optional)
8
8
  SumType::Optional
9
9
  else
10
10
  SumType
@@ -33,15 +33,17 @@ module Dry
33
33
  end
34
34
 
35
35
  def call(input)
36
- result = left[input]
37
-
38
- if left.valid?(result)
39
- result
40
- else
36
+ begin
37
+ value = left[input]
38
+
39
+ if left.valid?(value)
40
+ value
41
+ else
42
+ right[value]
43
+ end
44
+ rescue TypeError
41
45
  right[input]
42
46
  end
43
- rescue TypeError
44
- right[input]
45
47
  end
46
48
  alias_method :[], :call
47
49
 
data/lib/dry/data/type.rb CHANGED
@@ -1,3 +1,4 @@
1
+ require 'dry/data/type/optional'
1
2
  require 'dry/data/type/hash'
2
3
  require 'dry/data/type/array'
3
4
 
@@ -47,7 +48,7 @@ module Dry
47
48
  alias_method :[], :call
48
49
 
49
50
  def valid?(input)
50
- input.instance_of?(primitive)
51
+ input.is_a?(primitive)
51
52
  end
52
53
 
53
54
  def |(other)
@@ -48,8 +48,8 @@ module Dry
48
48
  end
49
49
 
50
50
  def schema(type_map, meth = :safe_constructor)
51
- value_constructors = type_map.each_with_object({}) { |(name, type_id), result|
52
- result[name] = Data[type_id]
51
+ value_constructors = type_map.each_with_object({}) { |(name, type), result|
52
+ result[name] = type.is_a?(String) ? Data[type] : type
53
53
  }
54
54
 
55
55
  self.class.new(
@@ -0,0 +1,19 @@
1
+ module Dry
2
+ module Data
3
+ class Type
4
+ class Optional < Type
5
+ def |(other)
6
+ Data.SumType(self.class.new(constructor, other.primitive), other)
7
+ end
8
+
9
+ def call(input)
10
+ Maybe(input)
11
+ end
12
+
13
+ def valid?(input)
14
+ input.nil? || super
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -20,6 +20,12 @@ module Dry
20
20
 
21
21
  ALL_PRIMITIVES = COERCIBLE.merge(NON_COERCIBLE).freeze
22
22
 
23
+ # Register optional type
24
+ register(
25
+ 'optional',
26
+ Type::Optional.new(Type.method(:passthrough_constructor), NilClass)
27
+ )
28
+
23
29
  # Register built-in primitive types with kernel coercion methods
24
30
  COERCIBLE.each do |name, primitive|
25
31
  register(
@@ -47,15 +53,16 @@ module Dry
47
53
  # Register non-coercible maybe types
48
54
  ALL_PRIMITIVES.each do |name, primitive|
49
55
  next if name == :nil
50
- register("maybe.strict.#{name}", self["strict.nil"] | self["strict.#{name}"])
56
+ register("maybe.strict.#{name}", self["optional"] | self["strict.#{name}"])
51
57
  end
52
58
 
53
59
  # Register coercible maybe types
54
60
  COERCIBLE.each do |name, primitive|
55
- register("maybe.coercible.#{name}", self["strict.nil"] | self["coercible.#{name}"])
61
+ register("maybe.coercible.#{name}", self["optional"] | self["coercible.#{name}"])
56
62
  end
57
63
 
58
64
  # Register :bool since it's common and not a built-in Ruby type :(
65
+ register("bool", self["true"] | self["false"])
59
66
  register("strict.bool", self["strict.true"] | self["strict.false"])
60
67
  end
61
68
  end
@@ -2,6 +2,10 @@ require 'dry/data/coercions/form'
2
2
 
3
3
  module Dry
4
4
  module Data
5
+ register('form.nil') do
6
+ Type.new(Coercions::Form.method(:to_nil), NilClass)
7
+ end
8
+
5
9
  register('form.date') do
6
10
  Type.new(Coercions::Form.method(:to_date), Date)
7
11
  end
@@ -1,5 +1,5 @@
1
1
  module Dry
2
2
  module Data
3
- VERSION = '0.1.0'.freeze
3
+ VERSION = '0.2.0'.freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dry-data
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.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: 2015-11-27 00:00:00.000000000 Z
11
+ date: 2015-11-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dry-container
@@ -130,6 +130,7 @@ files:
130
130
  - lib/dry/data/type.rb
131
131
  - lib/dry/data/type/array.rb
132
132
  - lib/dry/data/type/hash.rb
133
+ - lib/dry/data/type/optional.rb
133
134
  - lib/dry/data/types.rb
134
135
  - lib/dry/data/types/form.rb
135
136
  - lib/dry/data/version.rb