Module: Smplkit::Config::Discovery Private

Defined in:
lib/smplkit/config/client.rb

Overview

This module is part of a private API. You should avoid using this module if possible, as it may be removed or be changed in the future.

Module-level helpers for the config client. Extracted so they can be unit-tested without spinning up the full client.

Class Method Summary collapse

Class Method Details

.apply_change_to_target(target, dotted_key, value) ⇒ void

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Apply a server-pushed value to a bound target in place. Walks the dotted key path to the leaf’s parent and assigns the value via Hash#[]= or Struct#[]=. Bails silently if any intermediate is missing or not a supported container — the server may have items that don’t line up with what the bound target declared.

Parameters:

  • target (Hash, Struct)

    The bound target to mutate in place.

  • dotted_key (String)

    The dot-notation path to the leaf to set.

  • value (Object)

    The value to assign at the leaf.



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

def apply_change_to_target(target, dotted_key, value)
  parts = dotted_key.split(".")
  current = walk_to_leaf_parent(target, parts[0..-2])
  return if current.nil?

  last = parts.last
  if current.is_a?(Struct)
    assign_struct_member(current, last, value)
  elsif current.is_a?(Hash)
    current[last] = value
  end
end

.assign_struct_member(struct, name, value) ⇒ void

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

This method returns an undefined value.

Assign a value to a Struct member, ignoring members the Struct does not declare.

Parameters:

  • struct (Struct)

    The Struct to mutate.

  • name (String)

    The member name to assign.

  • value (Object)

    The value to assign.



175
176
177
178
179
180
# File 'lib/smplkit/config/client.rb', line 175

def assign_struct_member(struct, name, value)
  sym = name.to_sym
  return unless struct.members.include?(sym)

  struct[sym] = value
end

.iter_hash_items(hash, prefix: "") ⇒ Array<Array(String, String, Object, String, nil)>

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Walk a Hash leaf-by-leaf, flattening nested Hashes / Structs to dot-notation.

Parameters:

  • hash (Hash)

    The Hash to walk.

  • prefix (String) (defaults to: "")

    Dot-notation prefix accumulated during recursion.

Returns:

  • (Array<Array(String, String, Object, String, nil)>)

    One [key, type, value, description] tuple per leaf.



80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/smplkit/config/client.rb', line 80

def iter_hash_items(hash, prefix: "")
  out = []
  hash.each do |raw_key, value|
    flat_key = "#{prefix}#{raw_key}"
    if value.is_a?(Hash) || value.is_a?(Struct)
      out.concat(iter_items(value, prefix: "#{flat_key}."))
    else
      out << [flat_key, value_to_item_type(value), value, nil]
    end
  end
  out
end

.iter_items(target, prefix: "") ⇒ Array<Array(String, String, Object, String, nil)>

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Walk a bound target, returning [key, type, value, description] tuples flattened to dot-notation. Nested Hashes / Structs are descended into; everything else is treated as an opaque leaf.

Parameters:

  • target (Hash, Struct)

    The bound target to walk.

  • prefix (String) (defaults to: "")

    Dot-notation prefix accumulated during recursion.

Returns:

  • (Array<Array(String, String, Object, String, nil)>)

    One [key, type, value, description] tuple per leaf.



62
63
64
65
66
67
68
69
70
# File 'lib/smplkit/config/client.rb', line 62

def iter_items(target, prefix: "")
  if target.is_a?(Hash)
    iter_hash_items(target, prefix: prefix)
  elsif target.is_a?(Struct)
    iter_struct_items(target, prefix: prefix)
  else
    []
  end
end

.iter_struct_items(struct, prefix: "") ⇒ Array<Array(String, String, Object, String, nil)>

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Walk a Struct member-by-member, flattening nested Hashes / Structs to dot-notation.

Parameters:

  • struct (Struct)

    The Struct to walk.

  • prefix (String) (defaults to: "")

    Dot-notation prefix accumulated during recursion.

Returns:

  • (Array<Array(String, String, Object, String, nil)>)

    One [key, type, value, description] tuple per leaf.



101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/smplkit/config/client.rb', line 101

def iter_struct_items(struct, prefix: "")
  out = []
  struct.members.each do |member|
    value = struct[member]
    flat_key = "#{prefix}#{member}"
    if value.is_a?(Hash) || value.is_a?(Struct)
      out.concat(iter_items(value, prefix: "#{flat_key}."))
    else
      out << [flat_key, value_to_item_type(value), value, nil]
    end
  end
  out
end

.value_to_item_type(value) ⇒ String

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Map a runtime value to a Config item type. Used both when binding a Hash/Struct target and when supplying a default to get_value(id, key, default). true/false are checked first because Ruby’s Numeric/Integer tests would not accidentally claim them.

Parameters:

  • value (Object)

    The runtime value whose item type to infer.

Returns:

  • (String)

    One of “BOOLEAN”, “NUMBER”, or “STRING”.



45
46
47
48
49
50
51
# File 'lib/smplkit/config/client.rb', line 45

def value_to_item_type(value)
  case value
  when true, false then "BOOLEAN"
  when Numeric then "NUMBER"
  else "STRING"
  end
end

.walk_to_leaf_parent(target, parts) ⇒ Hash, ...

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Walk a dotted key path to the leaf’s parent container.

Parameters:

  • target (Hash, Struct)

    The root container to walk from.

  • parts (Array<String>)

    Path segments leading to (but excluding) the leaf.

Returns:

  • (Hash, Struct, nil)

    The leaf’s parent container, or nil when any intermediate is missing or not a supported container.



147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/smplkit/config/client.rb', line 147

def walk_to_leaf_parent(target, parts)
  current = target
  parts.each do |part|
    case current
    when Struct
      sym = part.to_sym
      return nil unless current.members.include?(sym)

      current = current[sym]
    when Hash
      return nil unless current.key?(part)

      current = current[part]
    else
      return nil
    end
  end
  current
end