Class: Yerba::Map

Inherits:
Object
  • Object
show all
Includes:
Enumerable, Node
Defined in:
lib/yerba/map.rb

Instance Attribute Summary

Attributes included from Node

#key, #location, #selector

Instance Method Summary collapse

Methods included from Node

#connected?, #document, #file_path, included, #line

Constructor Details

#initialize(hash = nil, **data) ⇒ Map

Returns a new instance of Map.



8
9
10
11
12
13
14
15
16
# File 'lib/yerba/map.rb', line 8

def initialize(hash = nil, **data)
  init_node(nil, nil, nil, nil, nil, nil)

  @data = if hash.is_a?(Hash)
            hash
          else
            (data.empty? ? {} : data)
          end
end

Instance Method Details

#[](key) ⇒ Object



18
19
20
21
22
23
24
25
# File 'lib/yerba/map.rb', line 18

def [](key)
  if connected?
    new_path = @selector.empty? ? key.to_s : "#{@selector}.#{key}"
    document[new_path]
  else
    @data[key]
  end
end

#[]=(key, value) ⇒ Object



27
28
29
# File 'lib/yerba/map.rb', line 27

def []=(key, value)
  set(key, value)
end

#collection_styleObject



188
189
190
# File 'lib/yerba/map.rb', line 188

def collection_style
  @collection_style || document&.get_collection_style(@selector)
end

#collection_style=(style) ⇒ Object



192
193
194
195
196
# File 'lib/yerba/map.rb', line 192

def collection_style=(style)
  document&.set_collection_style(@selector, style)

  @collection_style = style
end

#delete(key = nil) ⇒ Object



126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/yerba/map.rb', line 126

def delete(key = nil)
  if key && connected?
    new_path = @selector.empty? ? key.to_s : "#{@selector}.#{key}"
    document.delete(new_path)
  elsif connected?
    document.delete(@selector)
  else
    @data.delete(key)
  end

  self
end

#dig(*keys) ⇒ Object



109
110
111
112
113
114
115
# File 'lib/yerba/map.rb', line 109

def dig(*keys)
  if connected?
    keys.reduce(self) { |node, key| node.nil? ? nil : node[key] }
  else
    @data.dig(*keys)
  end
end

#eachObject



90
91
92
93
94
95
96
97
98
# File 'lib/yerba/map.rb', line 90

def each(&)
  return enum_for(:each) unless block_given?

  if connected?
    keys.each { |key| yield key, self[key] }
  else
    @data.each(&)
  end
end

#fetch(key) ⇒ Object



100
101
102
103
104
105
106
107
# File 'lib/yerba/map.rb', line 100

def fetch(key)
  if connected?
    new_path = @selector.empty? ? key.to_s : "#{@selector}.#{key}"
    document.fetch(new_path)
  else
    @data.fetch(key)
  end
end

#insert(key, value, before: nil, after: nil, style: nil) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
# File 'lib/yerba/map.rb', line 61

def insert(key, value, before: nil, after: nil, style: nil)
  if connected?
    new_path = @selector.empty? ? key.to_s : "#{@selector}.#{key}"

    document.insert(new_path, coerce_value(value, style: style), before: before, after: after)
  else
    @data[key] = value
  end

  self
end

#inspectObject



171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/yerba/map.rb', line 171

def inspect
  if connected?
    results = document.find(@selector)

    if results.is_a?(Array) && !results.empty? && results.first.is_a?(Hash)
      map_keys = results.first.keys.first(5)
      preview = map_keys.map { |key| "#{key}: #{results.first[key].inspect}" }.join(", ")

      "#<Yerba::Map selector=#{@selector.inspect} {#{preview}}>"
    else
      "#<Yerba::Map selector=#{@selector.inspect}>"
    end
  else
    "#<Yerba::Map {#{@data.map { |key, value| "#{key}: #{value.inspect}" }.join(", ")}}>"
  end
end

#key?(key) ⇒ Boolean Also known as: has_key?, include?

Returns:

  • (Boolean)


139
140
141
142
143
144
145
146
# File 'lib/yerba/map.rb', line 139

def key?(key)
  if connected?
    new_path = @selector.empty? ? key.to_s : "#{@selector}.#{key}"
    document.exists?(new_path)
  else
    @data.key?(key)
  end
end

#keysObject



79
80
81
82
83
84
85
86
87
88
# File 'lib/yerba/map.rb', line 79

def keys
  if connected?
    results = document.find(@selector)
    return [] unless results.is_a?(Array) && results.first.is_a?(Hash)

    results.first.keys
  else
    @data.keys
  end
end

#set(key, value, style: nil) ⇒ Object



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
# File 'lib/yerba/map.rb', line 31

def set(key, value, style: nil)
  if connected?
    new_path = @selector.empty? ? key.to_s : "#{@selector}.#{key}"
    coerced = coerce_value(value, style: style)
    is_block_value = coerced.is_a?(String) && (coerced.include?("\n") || coerced.start_with?("- "))

    if document.exists?(new_path) && is_block_value
      # Block-style collections can't replace a scalar via set().
      # Delete the key and re-insert at the same position.
      all_keys = keys
      key_index = all_keys.index(key.to_s)
      after_key = key_index&.positive? ? all_keys[key_index - 1] : nil

      document.delete(new_path)

      if after_key
        document.insert(new_path, coerced, after: after_key)
      else
        document.insert(new_path, coerced)
      end
    elsif document.exists?(new_path)
      document.set(new_path, coerced)
    else
      document.insert(new_path, coerced)
    end
  else
    @data[key] = value
  end
end

#sort_keys(order) ⇒ Object



73
74
75
76
77
# File 'lib/yerba/map.rb', line 73

def sort_keys(order)
  document&.sort_keys(@selector, order)

  self
end

#to_hObject Also known as: to_hash



154
155
156
157
158
159
160
161
# File 'lib/yerba/map.rb', line 154

def to_h
  if connected?
    results = document.find(@selector)
    results&.first || {}
  else
    @data
  end
end

#to_yamlObject



164
165
166
167
168
169
# File 'lib/yerba/map.rb', line 164

def to_yaml
  to_hash.map do |key, val|
    formatted = format_value(val)
    "#{key}: #{formatted}"
  end.join("\n")
end

#valueObject



150
151
152
# File 'lib/yerba/map.rb', line 150

def value
  @data || nil
end

#value_at(key) ⇒ Object



117
118
119
120
121
122
123
124
# File 'lib/yerba/map.rb', line 117

def value_at(key)
  if connected?
    new_path = @selector.empty? ? key.to_s : "#{@selector}.#{key}"
    document.value_at(new_path)
  else
    @data[key]
  end
end