# Sc4ry module # @note namespace module Sc4ry # Sc4ry::Config module # @note namespace module Config # Configuration validator for Sc4ry default and circuits configuration # @private class Validator # accessor on Circuit definition given for validation attr_reader :input # accessor on circuit initial definition from default config or given in construction by from keyword # @note altered by reference to final result mapping with {#validate!} attr_reader :config def result @config end include Sc4ry::Constants include Sc4ry::Exceptions # Validator constructor # @param [Hash] definition the config hash to merge and validate # @param [Hash] from config hash merged on origin (default : the Sc4ry base config from Constants ) # @return [Validator] a new instance of Validator def initialize(definition: , from: DEFAULT_CONFIG) @config = from @input = definition end # Validation method, alter by reference the config attribut # @raise ConfigError if un unknown key is given in definition to merge. def validate! unknown_keys = @input.keys.difference @config.keys raise ConfigError::new("Unknown keys in config set : #{unknown_keys.to_s}") unless unknown_keys.empty? validate_formats @config.merge! @input format_exceptions end private # Validation private sub method # @raise ConfigError if proposed values haven't the good format and deeply in array def validate_formats @input.each do |spec,value| raise ConfigError::new("#{spec} value #{DEFAULT_CONFIG_FORMATS[spec][:desc]}") unless DEFAULT_CONFIG_FORMATS[spec][:proc].call(value) if DEFAULT_CONFIG_FORMATS[spec].include? :list then value.each do |item| raise ConfigError::new("#{spec} value must be in #{DEFAULT_CONFIG_FORMATS[spec][:list]}") unless DEFAULT_CONFIG_FORMATS[spec][:list].include? item end end end end # adapter for exception key in config String to Constant Class Name if need # @note by reference def format_exceptions @config[:exceptions].map! {|item| item = (item.class == String)? Object.const_get(item) : item } end end # Config Data mapper for block yielding methods for configuration # @note work for/with {Sc4ry::Circuits.configure} and {Sc4ry::Circuits.register} when block given class ConfigMapper include Sc4ry::Constants # config from given definition passed in constructor attr_reader :config # the mapping constructor from a given definition or the default From Sc4ry config (Constant) # @param [Hash] definition a config hash # @note creating dynamically accessors on config record given in definition def initialize(definition: DEFAULT_CONFIG) @config = definition @config.each do |key,value| self.define_singleton_method "#{key.to_s}=".to_sym do |val| key = __method__.to_s.chop.to_sym @config[key]=val end self.define_singleton_method key do return @config[__method__] end end end end end end