Sha256: 9b8fa642d0b0abf945a9d7492cdde9c8b8adea91760a435b10c8b68872750a84

Contents?: true

Size: 1.54 KB

Versions: 3

Compression:

Stored size: 1.54 KB

Contents

# frozen_string_literal: true

# Parses environment variables and provides
# method-like access
class Runger::Env
  using Runger::Ext::DeepDup
  using Runger::Ext::Hash

  class << self
    def from_hash(hash, prefix: nil, memo: {})
      hash.each do |key, value|
        prefix_with_key = (prefix && !prefix.empty?) ? "#{prefix}_#{key.to_s.upcase}" : key.to_s.upcase

        if value.is_a?(Hash)
          from_hash(value, prefix: "#{prefix_with_key}_", memo:)
        else
          memo[prefix_with_key] = value.to_s
        end
      end

      memo
    end
  end

  include ::Runger::Tracing

  attr_reader :data, :traces, :type_cast, :env_container

  def initialize(type_cast: ::Runger::AutoCast, env_container: ENV)
    @type_cast = type_cast
    @data = {}
    @traces = {}
    @env_container = env_container
  end

  def clear
    data.clear
    traces.clear
  end

  def fetch(prefix)
    return data[prefix].deep_dup if data.key?(prefix)

    ::Runger::Tracing.capture do
      data[prefix] = parse_env(prefix)
    end.then do |trace|
      traces[prefix] = trace
    end

    data[prefix].deep_dup
  end

  def fetch_with_trace(prefix)
    [fetch(prefix), traces[prefix]]
  end

  private

  def parse_env(prefix)
    match_prefix = prefix.empty? ? prefix : "#{prefix}_"
    env_container.each_pair.with_object({}) do |(key, val), data|
      next unless key.start_with?(match_prefix)

      path = key.sub(/^#{match_prefix}/, '').downcase

      paths = path.split('__')
      trace!(:env, *paths, key:) { data.bury(type_cast.call(val), *paths) }
    end
  end
end

Version data entries

3 entries across 3 versions & 1 rubygems

Version Path
runger_config-5.2.0 lib/runger/env.rb
runger_config-5.1.0 lib/runger/env.rb
runger_config-5.0.0 lib/runger/env.rb