/
types.rb
100 lines (92 loc) · 2.51 KB
/
types.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
require 'rom/types'
module Hanami
module Model
# Types definitions
#
# @since 0.7.0
module Types
include ROM::Types
# @since 0.7.0
# @api private
def self.included(mod)
mod.extend(ClassMethods)
end
# Class level interface
#
# @since 0.7.0
module ClassMethods
# Define an array of given type
#
# @since 0.7.0
def Collection(type) # rubocop:disable Style/MethodName
type = Schema::CoercibleType.new(type) unless type.is_a?(Dry::Types::Definition)
Types::Array.member(type)
end
end
# Types for schema definitions
#
# @since 0.7.0
module Schema
# Coercer for objects within custom schema definition
#
# @since 0.7.0
# @api private
class CoercibleType < Dry::Types::Definition
# Coerce given value into the wrapped object type
#
# @param value [Object] the value
#
# @return [Object] the coerced value of `object` type
#
# @raise [TypeError] if value can't be coerced
#
# @since 0.7.0
# @api private
def call(value)
return if value.nil?
if valid?(value)
coerce(value)
else
raise TypeError.new("#{value.inspect} must be coercible into #{object}")
end
end
# Check if value can be coerced
#
# It is true if value is an instance of `object` type or if value
# respond to `#to_hash`.
#
# @param value [Object] the value
#
# @return [TrueClass,FalseClass] the result of the check
#
# @since 0.7.0
# @api private
def valid?(value)
value.is_a?(object) ||
value.respond_to?(:to_hash)
end
# Coerce given value into an instance of `object` type
#
# @param value [Object] the value
#
# @return [Object] the coerced value of `object` type
def coerce(value)
case value
when object
value
else
object.new(value.to_hash)
end
end
# @since 0.7.0
# @api private
def object
result = primitive
return result unless result.respond_to?(:primitive)
result.primitive
end
end
end
end
end
end