Class: Remap::Compiler

Inherits:
Proxy
  • Object
show all
Defined in:
lib/remap/compiler.rb

Overview

Constructs a Rule from the block passed to Base.define

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Proxy

const_missing, #tap

Class Method Details

.call(&block) ⇒ Rule

Constructs a rule tree given block

Examples:

Compiles two rules

rule = Remap::Compiler.call do
  get :name
  get :age
end

state = Remap::State.call({
  name: "John",
  age: 50
})

error = -> failure { raise failure.exception }

rule.call(state, &error).fetch(:value) # => { name: "John", age: 50 }

Returns:



30
31
32
33
34
35
36
37
38
# File 'lib/remap/compiler.rb', line 30

def self.call(&block)
  unless block
    return Rule::Void.new
  end

  new([]).tap do |compiler|
    compiler.instance_exec(&block)
  end.rule
end

Instance Method Details

#all(&block) ⇒ Rule::Path::Segment::Quantifier::All

Selects all elements

Returns:

  • (Rule::Path::Segment::Quantifier::All)


174
175
176
177
178
179
180
# File 'lib/remap/compiler.rb', line 174

def all(&block)
  if block
    raise ArgumentError, "all selector does not take a block"
  end

  Selector::All.new(EMPTY_HASH)
end

#at(index, &block) ⇒ Path::Segment::Key

Selects index element in input

Parameters:

  • index (Integer)

Returns:

  • (Path::Segment::Key)

Raises:

  • (ArgumentError)

    if index is not an Integer



214
215
216
217
218
219
220
221
222
223
# File 'lib/remap/compiler.rb', line 214

def at(index, &block)
  if block
    raise ArgumentError, "first selector does not take a block"
  end

  Selector::Index.new(index: index)
rescue Dry::Struct::Error
  raise ArgumentError,
        "Selector at(index) requires an integer argument, got [#{index}] (#{index.class})"
end

#callRule

Returns:



10
# File 'lib/remap/compiler.rb', line 10

delegate :call, to: Compiler

#each(&block) ⇒ Rule::Each

Iterates over the input value, passes each value to its block and merges the result back together

Returns:

Raises:

  • (ArgumentError)

    if no block given



145
146
147
148
149
150
151
# File 'lib/remap/compiler.rb', line 145

def each(&block)
  unless block
    raise ArgumentError, "#each requires a block"
  end

  add Rule::Each.new(rule: call(&block))
end

#embed(mapper, &block) ⇒ Rule::Embed

Maps using mapper

Parameters:

Returns:



94
95
96
97
98
99
100
101
102
# File 'lib/remap/compiler.rb', line 94

def embed(mapper, &block)
  if block
    raise ArgumentError, "#embed does not take a block"
  end

  add Rule::Embed.new(mapper: mapper)
rescue Dry::Struct::Error
  raise ArgumentError, "Embeded mapper must be [Remap::Mapper], got [#{mapper}]"
end

#first(&block) ⇒ Path::Segment::Key Also known as: any

Selects first element in input

Returns:

  • (Path::Segment::Key)

    ]



228
229
230
231
232
233
234
# File 'lib/remap/compiler.rb', line 228

def first(&block)
  if block
    raise ArgumentError, "first selector does not take a block"
  end

  at(0)
end

#get(*path, backtrace: Kernel.caller, &block) ⇒ Rule::Map::Required

Select a path and uses the same path as output

Parameters:

  • path ([])
    Array<Segment>, Segment

Returns:



76
77
78
# File 'lib/remap/compiler.rb', line 76

def get(*path, backtrace: Kernel.caller, &block)
  map(path, to: path, backtrace: backtrace, &block)
end

#get?(*path, backtrace: Kernel.caller, &block) ⇒ Rule::Map::Optional

Optional version of #get

Returns:

See Also:



85
86
87
# File 'lib/remap/compiler.rb', line 85

def get?(*path, backtrace: Kernel.caller, &block)
  map?(path, to: path, backtrace: backtrace, &block)
end

#last(&block) ⇒ Path::Segment::Key

Selects last element in input

Returns:

  • (Path::Segment::Key)


240
241
242
243
244
245
246
# File 'lib/remap/compiler.rb', line 240

def last(&block)
  if block
    raise ArgumentError, "last selector does not take a block"
  end

  at(-1)
end

#map(*path, to: EMPTY_ARRAY, backtrace: Kernel.caller, &block) ⇒ Rule::Map::Required

Maps input path [input] to output path [to]

Parameters:

  • path ([])
    Array<Segment>, Segment
  • to ([]) (defaults to: EMPTY_ARRAY)
    Array<Symbol>, Symbol

Returns:



46
47
48
49
50
51
52
53
54
# File 'lib/remap/compiler.rb', line 46

def map(*path, to: EMPTY_ARRAY, backtrace: Kernel.caller, &block)
  add Rule::Map::Required.call(
    path: {
      output: [to].flatten,
      input: path.flatten
    },
    backtrace: backtrace,
    rule: call(&block))
end

#map?(*path, to: EMPTY_ARRAY, backtrace: Kernel.caller, &block) ⇒ Rule::Map::Optional

Optional version of #map

Returns:

See Also:



61
62
63
64
65
66
67
68
69
# File 'lib/remap/compiler.rb', line 61

def map?(*path, to: EMPTY_ARRAY, backtrace: Kernel.caller, &block)
  add Rule::Map::Optional.call(
    path: {
      output: [to].flatten,
      input: path.flatten
    },
    backtrace: backtrace,
    rule: call(&block))
end

#option(id, backtrace: Kernel.caller, &block) ⇒ Rule::Static::Option

Static option to be selected

Parameters:

  • id (Symbol)

Returns:

  • (Rule::Static::Option)


200
201
202
203
204
205
206
# File 'lib/remap/compiler.rb', line 200

def option(id, backtrace: Kernel.caller, &block)
  if block
    raise ArgumentError, "option selector does not take a block"
  end

  Static::Option.new(name: id, backtrace: backtrace)
end

#ruleRule

The final rule

Returns:



251
252
253
# File 'lib/remap/compiler.rb', line 251

def rule
  Rule::Collection.call(rules: rules)
end

#rulesArray<Rule>

Returns:



7
# File 'lib/remap/compiler.rb', line 7

param :rules, type: Types.Array(Rule)

#set(*path, to:, &block) ⇒ Rule::Set

Parameters:

  • path ([])
    Symbol, Array<Symbol>
  • to (Hash)

    a customizable set of options

Options Hash (to:):

Returns:

Raises:

  • (ArgumentError)

    if no path given if path is not a Symbol or Array<Symbol>



111
112
113
114
115
116
117
118
119
# File 'lib/remap/compiler.rb', line 111

def set(*path, to:, &block)
  if block
    raise ArgumentError, "#set does not take a block"
  end

  add Rule::Set.new(path: path.flatten, value: to)
rescue Dry::Struct::Error => e
  raise ArgumentError, e.message
end

#to(*path, map: EMPTY_ARRAY, backtrace: Kernel.caller, &block) ⇒ Rule::Map

Maps to path from map with block in between

Parameters:

  • path (Array<Symbol>, Symbol)
  • map (Array<Segment>, Segment) (defaults to: EMPTY_ARRAY)

Returns:



127
128
129
# File 'lib/remap/compiler.rb', line 127

def to(*path, map: EMPTY_ARRAY, backtrace: Kernel.caller, &block)
  map(*map, to: path, backtrace: backtrace, &block)
end

#to?(*path, map: EMPTY_ARRAY, &block) ⇒ Rule::Map::Optional

Optional version of #to

Returns:

See Also:



136
137
138
# File 'lib/remap/compiler.rb', line 136

def to?(*path, map: EMPTY_ARRAY, &block)
  map?(*map, to: path, &block)
end

#value(value, &block) ⇒ Rule::Static::Fixed

Static value to be selected

Parameters:

  • value (Any)

Returns:

  • (Rule::Static::Fixed)


187
188
189
190
191
192
193
# File 'lib/remap/compiler.rb', line 187

def value(value, &block)
  if block
    raise ArgumentError, "option selector does not take a block"
  end

  Static::Fixed.new(value: value)
end

#wrap(type, &block) ⇒ Rule::Wrap

Wraps output in type

Parameters:

  • type (:array)

Yield Returns:

Returns:

Raises:

  • (ArgumentError)

    if type is not :array



161
162
163
164
165
166
167
168
169
# File 'lib/remap/compiler.rb', line 161

def wrap(type, &block)
  unless block
    raise ArgumentError, "#wrap requires a block"
  end

  add Rule::Wrap.new(type: type, rule: call(&block))
rescue Dry::Struct::Error => e
  raise ArgumentError, e.message
end