diff options
Diffstat (limited to 'app/models/user_settings')
-rw-r--r-- | app/models/user_settings/dsl.rb | 37 | ||||
-rw-r--r-- | app/models/user_settings/glue.rb | 23 | ||||
-rw-r--r-- | app/models/user_settings/namespace.rb | 21 | ||||
-rw-r--r-- | app/models/user_settings/setting.rb | 49 |
4 files changed, 130 insertions, 0 deletions
diff --git a/app/models/user_settings/dsl.rb b/app/models/user_settings/dsl.rb new file mode 100644 index 000000000..26238bbbe --- /dev/null +++ b/app/models/user_settings/dsl.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +module UserSettings::DSL + module ClassMethods + def setting(key, options = {}) + @definitions ||= {} + + UserSettings::Setting.new(key, options).tap do |s| + @definitions[s.key] = s + end + end + + def namespace(key, &block) + @definitions ||= {} + + UserSettings::Namespace.new(key).configure(&block).tap do |n| + @definitions.merge!(n.definitions) + end + end + + def keys + @definitions.keys + end + + def definition_for(key) + @definitions[key.to_sym] + end + + def definition_for?(key) + @definitions.key?(key.to_sym) + end + end + + def self.included(base) + base.extend ClassMethods + end +end diff --git a/app/models/user_settings/glue.rb b/app/models/user_settings/glue.rb new file mode 100644 index 000000000..02066a411 --- /dev/null +++ b/app/models/user_settings/glue.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +module UserSettings::Glue + def to_model + self + end + + def to_key + '' + end + + def persisted? + false + end + + def type_for_attribute(key) + self.class.definition_for(key)&.type + end + + def has_attribute?(key) # rubocop:disable Naming/PredicateName + self.class.definition_for?(key) + end +end diff --git a/app/models/user_settings/namespace.rb b/app/models/user_settings/namespace.rb new file mode 100644 index 000000000..b8f7e092e --- /dev/null +++ b/app/models/user_settings/namespace.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +class UserSettings::Namespace + attr_reader :name, :definitions + + def initialize(name) + @name = name.to_sym + @definitions = {} + end + + def configure(&block) + instance_eval(&block) + self + end + + def setting(key, options = {}) + UserSettings::Setting.new(key, options.merge(namespace: name)).tap do |s| + @definitions[s.key] = s + end + end +end diff --git a/app/models/user_settings/setting.rb b/app/models/user_settings/setting.rb new file mode 100644 index 000000000..5f5504254 --- /dev/null +++ b/app/models/user_settings/setting.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true + +class UserSettings::Setting + attr_reader :name, :namespace, :in + + def initialize(name, options = {}) + @name = name.to_sym + @default_value = options[:default] + @namespace = options[:namespace] + @in = options[:in] + end + + def default_value + if @default_value.respond_to?(:call) + @default_value.call + else + @default_value + end + end + + def type + case default_value + when TrueClass, FalseClass + ActiveModel::Type::Boolean.new + else + ActiveModel::Type::String.new + end + end + + def type_cast(value) + if type.respond_to?(:cast) + type.cast(value) + else + value + end + end + + def to_a + [key, default_value] + end + + def key + if namespace + "#{namespace}.#{name}".to_sym + else + name + end + end +end |