Module: Smplkit::Config::Discovery
- Defined in:
- lib/smplkit/config/client.rb
Overview
Module-level helpers for the runtime config client. Extracted so they can be unit-tested without spinning up the full client.
Class Method Summary collapse
-
.apply_change_to_target(target, dotted_key, value) ⇒ Object
Apply a server-pushed value to a bound target in place.
- .assign_struct_member(struct, name, value) ⇒ Object
- .iter_hash_items(hash, prefix: "") ⇒ Object
-
.iter_items(target, prefix: "") ⇒ Object
Walk a bound target, returning [key, type, value, description] tuples flattened to dot-notation.
- .iter_struct_items(struct, prefix: "") ⇒ Object
-
.value_to_item_type(value) ⇒ Object
Map a runtime value to a Config item type.
- .walk_to_leaf_parent(target, parts) ⇒ Object
Class Method Details
.apply_change_to_target(target, dotted_key, value) ⇒ Object
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.
67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/smplkit/config/client.rb', line 67 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) ⇒ Object
100 101 102 103 104 105 |
# File 'lib/smplkit/config/client.rb', line 100 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: "") ⇒ Object
35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/smplkit/config/client.rb', line 35 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: "") ⇒ Object
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.
25 26 27 28 29 30 31 32 33 |
# File 'lib/smplkit/config/client.rb', line 25 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: "") ⇒ Object
48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'lib/smplkit/config/client.rb', line 48 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) ⇒ Object
Map a runtime value to a Config item type. Used both when binding a Hash/Struct target and when supplying a default to get(id, key, default). true/false are checked first because Ruby’s Numeric/Integer tests would not accidentally claim them.
14 15 16 17 18 19 20 |
# File 'lib/smplkit/config/client.rb', line 14 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) ⇒ Object
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'lib/smplkit/config/client.rb', line 80 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 |