Class: Igniter::Extensions::Contracts::BranchPack::Definition

Inherits:
Object
  • Object
show all
Defined in:
lib/igniter/extensions/contracts/branch_pack.rb

Instance Method Summary collapse

Constructor Details

#initialize(name:, selector_name:) ⇒ Definition

Returns a new instance of Definition.



55
56
57
58
59
60
# File 'lib/igniter/extensions/contracts/branch_pack.rb', line 55

def initialize(name:, selector_name:)
  @name = name.to_sym
  @selector_name = selector_name.to_sym
  @cases = []
  @default_case = nil
end

Instance Method Details

#default(id: :default, value: UNSET, &block) ⇒ Object

Raises:

  • (ArgumentError)


74
75
76
77
78
79
80
81
82
83
# File 'lib/igniter/extensions/contracts/branch_pack.rb', line 74

def default(id: :default, value: UNSET, &block)
  raise ArgumentError, "branch :#{@name} can define only one default" if @default_case

  @default_case = {
    id: id.to_sym,
    matcher: :default,
    match: :default,
    value: normalize_value(value, block)
  }
end

#on(match = UNSET, id: nil, value: UNSET, **options, &block) ⇒ Object



62
63
64
65
66
67
68
69
70
71
72
# File 'lib/igniter/extensions/contracts/branch_pack.rb', line 62

def on(match = UNSET, id: nil, value: UNSET, **options, &block)
  matcher_kind, matcher_value = normalize_match(match, options)
  resolved_value = normalize_value(value, block)

  @cases << {
    id: (id || :"case_#{@cases.length + 1}").to_sym,
    matcher: matcher_kind,
    match: matcher_value,
    value: resolved_value
  }
end

#resolve(kwargs) ⇒ Object



105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/igniter/extensions/contracts/branch_pack.rb', line 105

def resolve(kwargs)
  selector_value = kwargs.fetch(@selector_name)
  selected = @cases.find { |entry| match?(entry, selector_value) } || @default_case

  {
    case: selected.fetch(:id),
    value: BranchPack.invoke_value(selected.fetch(:value), kwargs),
    matcher: selected.fetch(:matcher),
    matched_on: selected.fetch(:match),
    selector: @selector_name,
    selector_value: selector_value
  }
end

#validate!Object

Raises:

  • (ArgumentError)


85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/igniter/extensions/contracts/branch_pack.rb', line 85

def validate!
  raise ArgumentError, "branch :#{@name} requires at least one on clause" if @cases.empty?
  raise ArgumentError, "branch :#{@name} requires a default clause" unless @default_case

  duplicate_ids = (@cases.map { |entry| entry.fetch(:id) } + [@default_case.fetch(:id)])
                  .group_by { |id| id }
                  .select { |_id, group| group.length > 1 }
                  .keys
  unless duplicate_ids.empty?
    raise ArgumentError,
          "branch :#{@name} has duplicate case ids: #{duplicate_ids.join(", ")}"
  end

  overlapping = overlapping_literals
  return if overlapping.empty?

  raise ArgumentError,
        "branch :#{@name} has overlapping literal matches: #{overlapping.map(&:inspect).join(", ")}"
end