File: maybe.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 (130 lines) | stat: -rw-r--r-- 2,798 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
# frozen_string_literal: true

require 'dry/monads/maybe'
require 'dry/types/decorator'

module Dry
  module Types
    # Maybe extension provides Maybe types where values are wrapped using `Either` monad
    #
    # @api public
    class Maybe
      include Type
      include Dry::Equalizer(:type, :options, inspect: false, immutable: true)
      include Decorator
      include Builder
      include Printable
      include Dry::Monads::Maybe::Mixin

      # @param [Dry::Monads::Maybe, Object] input
      #
      # @return [Dry::Monads::Maybe]
      #
      # @api private
      def call_unsafe(input = Undefined)
        case input
        when Dry::Monads::Maybe
          input
        when Undefined
          None()
        else
          Maybe(type.call_unsafe(input))
        end
      end

      # @param [Dry::Monads::Maybe, Object] input
      #
      # @return [Dry::Monads::Maybe]
      #
      # @api private
      def call_safe(input = Undefined, &block)
        case input
        when Dry::Monads::Maybe
          input
        when Undefined
          None()
        else
          Maybe(type.call_safe(input, &block))
        end
      end

      # @param [Object] input
      #
      # @return [Result::Success]
      #
      # @api public
      def try(input = Undefined)
        res = if input.equal?(Undefined)
                None()
              else
                Maybe(type[input])
              end

        Result::Success.new(res)
      end

      # @return [true]
      #
      # @api public
      def default?
        true
      end

      # @param [Object] value
      #
      # @see Dry::Types::Builder#default
      #
      # @raise [ArgumentError] if nil provided as default value
      #
      # @api public
      def default(value)
        if value.nil?
          raise ArgumentError, 'nil cannot be used as a default of a maybe type'
        else
          super
        end
      end
    end

    module Builder
      # Turn a type into a maybe type
      #
      # @return [Maybe]
      #
      # @api public
      def maybe
        Maybe.new(Types['strict.nil'] | self)
      end
    end

    # @api private
    class Schema::Key
      # @api private
      def maybe
        __new__(type.maybe)
      end
    end

    # @api private
    class Printer
      MAPPING[Maybe] = :visit_maybe

      # @api private
      def visit_maybe(maybe)
        visit(maybe.type) do |type|
          yield "Maybe<#{type}>"
        end
      end
    end

    # Register non-coercible maybe types
    NON_NIL.each_key do |name|
      register("maybe.strict.#{name}", self["strict.#{name}"].maybe)
    end

    # Register coercible maybe types
    COERCIBLE.each_key do |name|
      register("maybe.coercible.#{name}", self["coercible.#{name}"].maybe)
    end
  end
end