feat(context): 🎉 begin work on the context system
This commit is contained in:
parent
fe23382dcc
commit
ac969681e6
1 changed files with 165 additions and 0 deletions
165
lib/comfpile/context.rb
Normal file
165
lib/comfpile/context.rb
Normal file
|
@ -0,0 +1,165 @@
|
|||
|
||||
|
||||
module Comfpile
|
||||
class ContextTag
|
||||
def initialize(tag)
|
||||
@@known_tags ||= {}
|
||||
|
||||
case tag
|
||||
when Symbol, String
|
||||
precompiled = @@known_tags[tag.to_sym]
|
||||
|
||||
if not precompiled.nil?
|
||||
@tag = precompiled[:tag]
|
||||
@tag_array = precompiled[:array]
|
||||
else
|
||||
@tag_array = tag.to_s.split('_').uniq.sort
|
||||
|
||||
end
|
||||
when Array
|
||||
@tag_array = tag.map(&:to_s).uniq.sort
|
||||
@tag = @tag_array
|
||||
end
|
||||
|
||||
@tag ||= @tag_array.join('_').to_sym
|
||||
|
||||
tag_data = {
|
||||
tag: @tag,
|
||||
array: @ŧag_array
|
||||
}
|
||||
|
||||
@@known_tags[@tag] ||= tag_data
|
||||
@@known_tags[tag] ||= tag_data
|
||||
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
|
Loading…
Add table
Add a link
Reference in a new issue