lib/rack/queries/cache.rb in rack-queries-0.2.1 vs lib/rack/queries/cache.rb in rack-queries-0.3.0

- old
+ new

@@ -1,62 +1,97 @@ # frozen_string_literal: true module Rack module Queries class Cache + class Option < Struct.new(:name, :type) + def as_json + { name: name, type: type } + end + end + + class SelectOption < Struct.new(:name) + def as_json + { name: name, type: 'select' } + end + end + class CreateQuery - def self.name(name = :get) - if name == :get - @name - else - @name = name + class << self + def name(name = :get) + if name == :get + @name + else + @name = name + end end - end - def self.desc(desc = :get) - if desc == :get - @desc - else - @desc = desc + def desc(desc = :get) + if desc == :get + @desc + else + @desc = desc + end end - end - def self.opt(name, &block) - define_method(name, &block) - end + def opts + @opts ||= {} + end - def self.run(&block) - define_method(:run, &block) + def opt(name, type: :select, &block) + if type != :select && block + raise ArgumentError, 'Can only specify a block if it is a select' + end + + if type == :select + define_method(name, &block) + opts[name.to_s] = SelectOption.new(name) + else + opts[name.to_s] = Option.new(name, type) + end + end + + def run(&block) + define_method(:run, &block) + end end end attr_reader :cache def initialize @cache = [] end def add(*queries) + queries.each do |query| + opts = {} + + (query.public_instance_methods(false) - %i[run]).each do |name| + opts[name] = SelectOption.new(name) + end + + query.define_singleton_method(:opts) { opts } + end + @cache = (cache + queries).sort_by(&:name) end def create(&block) query = Class.new(CreateQuery, &block) @cache = (cache << query).sort_by(&:name) end def opts_for(name, opt) query = query_for(name) - return unless query - - instance = query.new - instance.public_send(opt) if instance.respond_to?(opt) + query.new.public_send(opt) if query end def queries cache.map do |query| desc = query.respond_to?(:desc) ? query.desc : '' - opts = query.public_instance_methods(false) - %i[run] + opts = + query.respond_to?(:opts) ? query.opts.values.map(&:as_json) : [] { name: query.name, desc: desc, opts: opts } end end