Class: StrongCSV::Let

Inherits:
Object
  • Object
show all
Defined in:
lib/strong_csv/let.rb,
sig/strong_csv.rbs

Overview

Let is a class that is used to define types for columns.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeLet



15
16
17
18
19
20
# File 'lib/strong_csv/let.rb', line 15

def initialize
  @types = []
  @headers = false
  @pickers = {}
  @picked = {}
end

Instance Attribute Details

#headersBoolean (readonly)



10
11
12
# File 'lib/strong_csv/let.rb', line 10

def headers
  @headers
end

#pickersHash (readonly)



13
14
15
# File 'lib/strong_csv/let.rb', line 13

def pickers
  @pickers
end

#typesHash{Symbol => [Types::Base, Proc]} (readonly)



7
8
9
# File 'lib/strong_csv/let.rb', line 7

def types
  @types
end

Instance Method Details

#booleanTypes::Boolean



69
70
71
# File 'lib/strong_csv/let.rb', line 69

def boolean
  Types::Boolean.new
end

#boolean?Boolean



73
74
75
# File 'lib/strong_csv/let.rb', line 73

def boolean?
  optional(boolean)
end

#float(**options) ⇒ Types::Float



78
79
80
# File 'lib/strong_csv/let.rb', line 78

def float(**options)
  Types::Float.new(**options)
end

#float?(**options) ⇒ Boolean



83
84
85
# File 'lib/strong_csv/let.rb', line 83

def float?(**options)
  optional(float(**options))
end

#integer(**options) ⇒ Types::Integer



60
61
62
# File 'lib/strong_csv/let.rb', line 60

def integer(**options)
  Types::Integer.new(**options)
end

#integer?(**options) ⇒ Boolean



65
66
67
# File 'lib/strong_csv/let.rb', line 65

def integer?(**options)
  optional(integer(**options))
end

#let(name, type, *types, error_message: nil, &block) ⇒ void



25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/strong_csv/let.rb', line 25

def let(name, type, *types, error_message: nil, &block)
  type = Types::Union.new(type, *types) unless types.empty?
  case name
  when ::Integer
    @types << TypeWrapper.new(name: name, type: type, block: block, error_message: error_message)
  when ::String, ::Symbol
    @types << TypeWrapper.new(name: name.to_sym, type: type, block: block, error_message: error_message)
  else
    raise TypeError, "Invalid type specified for `name`. `name` must be String, Symbol, or Integer: #{name.inspect}"
  end
  validate_columns
end

#optional(*args) ⇒ Types::Optional



108
109
110
# File 'lib/strong_csv/let.rb', line 108

def optional(*args)
  Types::Optional.new(*args)
end

#pick(column, as:) {|values, arg0| ... } ⇒ void

This method returns an undefined value.

#pick is intended for defining a singleton method with :as. This might be useful for the case where you want to receive IDs that are stored in a database, and you want to make sure the IDs actually exist.

Examples:

pick :user_id, as: :user_ids do |user_ids|
  User.where(id: user_ids).ids
end

Yields:

Yield Parameters:

  • values (Array<String>)

    The values for the column. NOTE: This is an array of String, not casted values.

  • arg0 (Array[::String])

Yield Returns:

  • (Object)


50
51
52
53
54
55
56
57
# File 'lib/strong_csv/let.rb', line 50

def pick(column, as:, &block)
  define_singleton_method(as) do
    @picked[as]
  end
  @pickers[as] = lambda do |csv|
    @picked[as] = block.call(csv.map { |row| row[column] })
  end
end

#string(**options) ⇒ Types::String



88
89
90
# File 'lib/strong_csv/let.rb', line 88

def string(**options)
  Types::String.new(**options)
end

#string?(**options) ⇒ Boolean



93
94
95
# File 'lib/strong_csv/let.rb', line 93

def string?(**options)
  optional(string(**options))
end

#time(**options) ⇒ Types::Time



98
99
100
# File 'lib/strong_csv/let.rb', line 98

def time(**options)
  Types::Time.new(**options)
end

#time?(**options) ⇒ Boolean



103
104
105
# File 'lib/strong_csv/let.rb', line 103

def time?(**options)
  optional(time(**options))
end

#validate_columnsBoolean



114
115
116
117
118
119
120
121
122
# File 'lib/strong_csv/let.rb', line 114

def validate_columns
  if @types.all? { |t| t.name.is_a?(Integer) }
    @headers = false
  elsif @types.all? { |k| k.name.is_a?(Symbol) }
    @headers = true
  else
    raise ArgumentError, "`types` cannot be mixed with Integer and Symbol keys: #{@types.map(&:name).inspect}"
  end
end