Class: Aspera::Cli::ExtendedValue

Inherits:
Object
  • Object
show all
Includes:
Singleton
Defined in:
lib/aspera/cli/extended_value.rb

Overview

Command line extended values

Constant Summary collapse

DEFAULT_DECODERS =

First is default

i[none json ruby yaml]

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#default_decoderObject

Returns the value of attribute default_decoder.



120
121
122
# File 'lib/aspera/cli/extended_value.rb', line 120

def default_decoder
  @default_decoder
end

Class Method Details

.assert_no_value(value, ext_type) ⇒ Object

The value must be empty

Parameters:

  • value (String)

    The value as parameter

  • ext_type (Symbol)

    The method of extended value



65
66
67
# File 'lib/aspera/cli/extended_value.rb', line 65

def assert_no_value(value, ext_type)
  Aspera.assert(value.empty?, type: BadArgument){"no value allowed for extended value type: #{ext_type}"}
end

.decode_csvt(value) ⇒ Object

Decode comma separated table text



26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/aspera/cli/extended_value.rb', line 26

def decode_csvt(value)
  col_titles = nil
  hash_array = []
  CSV.parse(value).each do |values|
    next if values.empty?
    if col_titles.nil?
      col_titles = values
    else
      hash_array.push(col_titles.zip(values).to_h)
    end
  end
  Log.log.warn('Titled CSV file without any row') if hash_array.empty?
  return hash_array
end

.JSON_parse(value) ⇒ Object

JSON Parser, with more information on error location extract a context: 10 chars before and after the error on the given line and display a pointer “^” :reek:UncommunicativeMethodName



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/aspera/cli/extended_value.rb', line 44

def JSON_parse(value) # rubocop:disable Naming/MethodName
  JSON.parse(value)
rescue JSON::ParserError => e
  m = /at line (\d+) column (\d+)/.match(e.message)
  raise if m.nil?
  line = m[1].to_i - 1
  column = m[2].to_i - 1
  lines = value.lines
  raise if line >= lines.size
  error_line = lines[line].chomp
  context_col_beg = [column - 10, 0].max
  context_col_end = [column + 10, error_line.length].min
  context = error_line[context_col_beg...context_col_end]
  cursor_pos = column - context_col_beg
  pointer = ' ' * cursor_pos + '^'.blink
  raise BadArgument, "#{e.message}\n#{context}\n#{pointer}"
end

.read_stdin(mode) ⇒ Object



69
70
71
72
73
74
75
76
# File 'lib/aspera/cli/extended_value.rb', line 69

def read_stdin(mode)
  case mode
  when '' then $stdin.read
  when 'bin' then $stdin.binmode.read
  when 'chomp' then $stdin.chomp
  else raise BadArgument, "`stdin` supports only: '', 'bin' or 'chomp'"
  end
end

Instance Method Details

#evaluate(value, context:, allowed: nil) ⇒ Object

Parses a String value to extended value. If it is a String using supported extended value modifiers, then evaluate them. Other value types are returned as is.

Parameters:

  • value (String)

    the value to parse

  • context (String)

    Context in which evaluation is done

  • allowed (Array<Class>, NilClass) (defaults to: nil)

    Expected types

Returns:

  • (Object)

    Evaluated value



148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/aspera/cli/extended_value.rb', line 148

def evaluate(value, context:, allowed: nil)
  return value unless value.is_a?(String)
  Aspera.assert_array_all(allowed, Class) unless allowed.nil?
  # use default decoder if not an extended value and expect complex types
  using_default_decoder = allowed&.all?{ |t| DEFAULT_PARSER_TYPES.include?(t)} && !@regex_single.match?(value) && !@default_decoder.nil?
  value = [MARKER_START, @default_decoder, MARKER_END, value].join if using_default_decoder
  # First determine decoders, in reversed order
  handlers_reversed = []
  while (m = value.match(@regex_single))
    handler = m[1].to_sym
    handlers_reversed.unshift(handler)
    value = m[2]
    break if SPECIAL_HANDLERS.include?(handler)
  end
  Log.log.trace1{"evaluating: #{handlers_reversed}, value: #{value}"}
  handlers_reversed.each do |handler|
    value = @handlers[handler].call(value)
  rescue => e
    raise BadArgument, "Evaluation of #{handler} for #{context}: #{e.message}"
  end
  return value
end

#evaluate_extend(value) ⇒ Object

Find inner extended values Only used in above lambda



173
174
175
176
177
178
179
180
# File 'lib/aspera/cli/extended_value.rb', line 173

def evaluate_extend(value)
  while (m = value.match(@regex_extend))
    sub_value = "@#{m[2]}:#{m[3]}"
    Log.log.debug{"evaluating #{sub_value}"}
    value = "#{m[1]}#{evaluate(sub_value, context: 'composite extended value')}#{m[4]}"
  end
  return value
end

#modifiersObject

List of Extended Value methods



130
# File 'lib/aspera/cli/extended_value.rb', line 130

def modifiers; @handlers.keys; end

#on(name, &block) ⇒ Object

Add a new handler



133
134
135
136
137
138
139
# File 'lib/aspera/cli/extended_value.rb', line 133

def on(name, &block)
  Aspera.assert_type(name, Symbol){'name'}
  Aspera.assert(block)
  Log.log.debug{"Setting handler for #{name}"}
  @handlers[name] = block
  update_regex
end