-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
/
Copy pathstrict_hash_configuration.rb
108 lines (89 loc) · 2.66 KB
/
strict_hash_configuration.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# frozen_string_literal: true
module Grape
module Util
module StrictHashConfiguration
extend ActiveSupport::Concern
module DSL
extend ActiveSupport::Concern
module ClassMethods
def settings
config_context.to_hash
end
def configure(&block)
config_context.instance_exec(&block)
end
end
end
class SettingsContainer
def initialize
@settings = {}
@contexts = {}
end
def to_hash
@settings.to_hash
end
end
def self.config_class(*args)
new_config_class = Class.new(SettingsContainer)
args.each do |setting_name|
if setting_name.respond_to? :values
nested_settings_methods(setting_name, new_config_class)
else
simple_settings_methods(setting_name, new_config_class)
end
end
new_config_class
end
def self.simple_settings_methods(setting_name, new_config_class)
setting_name_sym = setting_name.to_sym
new_config_class.class_eval do
define_method setting_name do |new_value|
@settings[setting_name_sym] = new_value
end
end
end
def self.nested_settings_methods(setting_name, new_config_class)
new_config_class.class_eval do
setting_name.each_pair do |key, value|
define_method :"#{key}_context" do
@contexts[key] ||= Grape::Util::StrictHashConfiguration.config_class(*value).new
end
define_method key do |&block|
send(:"#{key}_context").instance_exec(&block)
end
end
define_method :to_hash do
@settings.to_hash.merge(
setting_name.each_key.with_object({}) do |k, merge_hash|
merge_hash[k] = send(:"#{k}_context").to_hash
end
)
end
end
end
def self.module(*args)
new_module = Module.new do
extend ActiveSupport::Concern
include DSL
end
new_module.tap do |mod|
class_mod = create_class_mod(args)
mod.const_set(:ClassMethods, class_mod)
end
end
def self.create_class_mod(args)
new_module = Module.new do
def config_context
@config_context ||= config_class.new
end
end
new_module.tap do |class_mod|
new_config_class = config_class(*args)
class_mod.send(:define_method, :config_class) do
@config_class ||= new_config_class
end
end
end
end
end
end