File: key.rb

package info (click to toggle)
ruby-dry-types 1.2.2-2
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, forky, sid, trixie
  • size: 504 kB
  • sloc: ruby: 3,059; makefile: 4
file content (147 lines) | stat: -rw-r--r-- 3,648 bytes parent folder | download
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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# frozen_string_literal: true

require 'dry/equalizer'
require 'dry/core/deprecations'

module Dry
  module Types
    # Schema is a hash with explicit member types defined
    #
    # @api public
    class Schema < Hash
      # Proxy type for schema keys. Contains only key name and
      # whether it's required or not. All other calls deletaged
      # to the wrapped type.
      #
      # @see Dry::Types::Schema
      class Key
        extend ::Dry::Core::Deprecations[:'dry-types']
        include Type
        include Dry::Equalizer(:name, :type, :options, inspect: false, immutable: true)
        include Decorator
        include Builder
        include Printable

        # @return [Symbol]
        attr_reader :name

        # @api private
        def initialize(type, name, required: Undefined, **options)
          required = Undefined.default(required) do
            type.meta.fetch(:required) { !type.meta.fetch(:omittable, false) }
          end

          unless name.is_a?(::Symbol)
            raise ArgumentError, "Schemas can only contain symbol keys, #{name.inspect} given"
          end

          super(type, name, required: required, **options)
          @name = name
        end

        # @api private
        def call_safe(input, &block)
          type.call_safe(input, &block)
        end

        # @api private
        def call_unsafe(input)
          type.call_unsafe(input)
        end

        # @see Dry::Types::Nominal#try
        #
        # @api public
        def try(input, &block)
          type.try(input, &block)
        end

        # Whether the key is required in schema input
        #
        # @return [Boolean]
        #
        # @api public
        def required?
          options.fetch(:required)
        end

        # Control whether the key is required
        #
        # @overload required
        #   @return [Boolean]
        #
        # @overload required(required)
        #   Change key's "requireness"
        #
        #   @param [Boolean] required New value
        #   @return [Dry::Types::Schema::Key]
        #
        # @api public
        def required(required = Undefined)
          if Undefined.equal?(required)
            options.fetch(:required)
          else
            with(required: required)
          end
        end

        # Make key not required
        #
        # @return [Dry::Types::Schema::Key]
        #
        # @api public
        def omittable
          required(false)
        end

        # Turn key into a lax type. Lax types are not strict hence such keys are not required
        #
        # @return [Lax]
        #
        # @api public
        def lax
          __new__(type.lax).required(false)
        end

        # Dump to internal AST representation
        #
        # @return [Array]
        #
        # @api public
        def to_ast(meta: true)
          [
            :key,
            [
              name,
              required,
              type.to_ast(meta: meta)
            ]
          ]
        end

        # @see Dry::Types::Meta#meta
        #
        # @api public
        def meta(data = nil)
          if data.nil? || !data.key?(:omittable)
            super
          else
            self.class.warn(
              'Using meta for making schema keys is deprecated, ' \
              'please use .omittable or .required(false) instead' \
              "\n" + Core::Deprecations::STACK.()
            )
            super.required(!data[:omittable])
          end
        end

        private

        # @api private
        def decorate?(response)
          response.is_a?(Type)
        end
      end
    end
  end
end