comfpile-old/lib/comfpile/context.rb

196 lines
No EOL
5 KiB
Ruby

module Comfpile
class ContextTag
attr_reader :tag, :taglist
def self.form_context(tag)
@known_tags ||= {}
case tag
when Symbol
tag_instance = @known_tags[tag]
return tag_instance unless tag_instance.nil?
tag_instance = ContextTag.new(tag)
tag_instance = (@known_tags[tag_instance] ||= tag_instance)
@known_tags[tag] ||= tag_instance
@known_tags[tag_instance.tag] ||= tag_instance
end
end
def initialize(tag)
process_tag(tag)
end
private def process_tag(tag)
case tag
when Symbol, String
@taglist = tag.to_s.split('_').uniq.sort
when Array
@taglist = tag.map(&:to_s).uniq.sort
end
@tag = @taglist.join('_').to_sym
@taghash = {}
@taglist.each do |tag|
@taghash[tag] = true
end
end
def include?(*tags)
tags = tags - @tag_array
tags.empy?
end
alias include_all? include?
def include_any?(*tags)
tags = tags & @tag_array
tags.empty?
end
def hash
@tag.hash
end
def eql?(other)
if(other.is_a? Symbol)
@tag.eql? other
elsif(other.is_a? ContextTag)
@tag.eql? other.tag
end
end
end
#
# This class represents the configuration of a specific context.
# It has two main jobs:
# To provide functions to set up and merge configuration options
# from the various tags given to it, and
# to give reader options for the various config options.
#
# Most importantly, it contains mechanisms for safely setting up
# configurations and flagging issues.
#
class ContextConfig
attr_reader :context_tag
attr_reader :config_options
def initialize(context_tag, parent)
@context_tag = context_tag
@seeder_blocks = []
@config_options = nil
end
def add_seeder_block(priority, &block)
@seeder_blocks << {
priority: priority,
block: block
}
end
def resolve_key(key)
if key.is_a? Array
return key.map {|k| k.to_sym }
elsif key.is_a? String
return key.split('.').map {|k| k.to_sym }
elsif key.is_a? Symbol
return resolve_key(key.to_s)
end
end
def [](key)
@config_options&.dig(*resolve_key(key))
end
def []=(key, value)
key = resolve_key(key)
current_hash = (@config_options ||= {})
key[0..-2].each do |key|
current_hash = (current_hash[key] ||= {})
next if current_hash.is_a? Hash
raise ArgumentError, "Attempted to set child-parameter of another parameter!"
end
current_hash[key[-1]] = value
value
end
alias set []=
def set_flag(key, value)
set resolve_key(key).append(value), true
end
def get_flags(key)
(@config_options&.dig(*resolve_key(key)) || {}).keys
end
def dig(arg0, *args)
@config_options&.dig(arg0, *args)
end
def append(key, value)
key = resolve_key key
array = @config_options&.dig(*key)
if array.nil?
array = set key, []
end
raise ArgumentError, "Attempted to append to a non-list parameter!" unless array.is_a? Array
array << value
end
alias append_to append
def assert(orig_key, value)
key = resolve_key orig_key
current_value = @config_options&.dig(*key)
if current_value.nil?
set key, value
elsif current_value != value
raise ArgumentError, "Config key assertion failed! #{orig_key} should be #{value}, is #{current_value}!"
end
end
def build_config
@config_options = nil
@seeder_blocks.sort { |block| block[:priority] }.each do |block|
self.instance_exec(block, &block[:block])
end
self.freeze
end
end
class ContextConfigContainer
def initialize
@context_configs_seeds = []
end
def find_seeds_for(context_tag)
out = []
@context_configs_seeds.each do |seed|
seed_tags = seed[:context_tags]
seed_tags.each do |tag|
end
end
end
def add_to_config(context_config)
raise ArgumentError, "No context supplied!" unless context_config.is_a? ContextConfig
end
end
end