class Shaf::MethodBuilder

Constants

NO_GIVEN_VALUE

Attributes

alt_uri[R]
name[R]
uri[R]

Public Class Methods

new(name, uri, alt_uri: nil) click to toggle source
# File lib/shaf/extensions/resource_uris.rb, line 214
def initialize(name, uri, alt_uri: nil)
  @name = name
  @uri = uri.dup.freeze
  @alt_uri = alt_uri.dup.freeze
end
query_string(query) click to toggle source
# File lib/shaf/extensions/resource_uris.rb, line 202
def self.query_string(query)
  return '' unless query&.any?

  fragment_id = query.delete(:fragment_id)
  fragment_str = "##{fragment_id}" if fragment_id

  query_str = query.map { |a| a.join('=') }.join('&')
  query_str = "?#{query_str}" unless query_str.empty?

  [query_str, fragment_str].join
end

Public Instance Methods

call() click to toggle source
# File lib/shaf/extensions/resource_uris.rb, line 220
def call
  if UriHelper.respond_to? uri_method_name
    exception = ResourceUris::UriHelperMethodAlreadyExistError
    raise exception.new(name, uri_method_name)
  end

  if alt_uri.nil?
    build_methods
  else
    build_methods_with_optional_arg
  end
end

Private Instance Methods

build_methods() click to toggle source
# File lib/shaf/extensions/resource_uris.rb, line 237
def build_methods
  UriHelperMethods.eval_method uri_method_string
  UriHelperMethods.eval_method path_method_string
  UriHelperMethods.register(template_method_name, &template_proc)
  UriHelperMethods.register(legacy_template_method_name, &template_proc)
  UriHelperMethods.register(path_matcher_name, &path_matcher_proc)
  path_method_name.to_sym
end
build_methods_with_optional_arg() click to toggle source
# File lib/shaf/extensions/resource_uris.rb, line 246
def build_methods_with_optional_arg
  UriHelperMethods.eval_method uri_method_with_optional_arg_string
  UriHelperMethods.eval_method path_method_with_optional_arg_string
  UriHelperMethods.register(template_method_name, &template_proc)
  UriHelperMethods.register(legacy_template_method_name, &template_proc)
  UriHelperMethods.register(path_matcher_name, &path_matcher_proc)
  path_method_name.to_sym
end
extract_symbols(uri = @uri) click to toggle source
# File lib/shaf/extensions/resource_uris.rb, line 359
def extract_symbols(uri = @uri)
  uri.split('/').grep(/\A:.+/).map { |t| t[1..-1].to_sym }
end
interpolated_uri_string(uri) click to toggle source
# File lib/shaf/extensions/resource_uris.rb, line 372
def interpolated_uri_string(uri)
  return uri if uri == '/'

  transform_symbols(uri) do |segment, i|
    # if the uri is templated (starting with a '{'), then we need to
    # exclude it from the interpolated string but add it back to the end of
    # the segment.
    last = (segment.index('{') || 0) - 1
    sym = segment[1..last]
    template = segment[(last + 1)..-1] unless last == -1
    "\#{arg#{i}.respond_to?(:#{sym}) ? arg#{i}.#{sym} : arg#{i}}#{template}"
  end
end
legacy_template_method_name() click to toggle source
# File lib/shaf/extensions/resource_uris.rb, line 271
def legacy_template_method_name
  "#{uri_method_name}_template".freeze
end
path_matcher_name() click to toggle source
# File lib/shaf/extensions/resource_uris.rb, line 263
def path_matcher_name
  :"#{path_method_name}?"
end
path_matcher_proc() click to toggle source
# File lib/shaf/extensions/resource_uris.rb, line 420
    def path_matcher_proc
      patterns = path_mather_patterns

      deprecated_method = path_matcher_name
      replacing_method = "#{name}_collection_path?"

      lambda do |path = nil, collection: NO_GIVEN_VALUE|
        if collection != NO_GIVEN_VALUE
          warn <<~DEPRECATION

            Deprecated use of uri predicate helper with `collection` argument:
            Use #{replacing_method} instead of #{deprecated_method}(collection: true)
              #{caller.find { |s| !s.match? %r{lib/shaf/extensions} }}

          DEPRECATION
        else
          collection = false
        end

        unless path
          r = request if respond_to? :request
          path = r.path_info if r&.respond_to? :path_info

          unless path
            raise(
              ArgumentError,
              "Uri must be given (or #{self} should respond to :request)"
            )
          end
        end
        pattern = collection ? patterns.last : patterns.first
        !!(pattern =~ path)
      end
    end
path_mather_patterns() click to toggle source
# File lib/shaf/extensions/resource_uris.rb, line 413
def path_mather_patterns
  [
    uri.gsub(%r{:[^/]*}, '\w+'),
    alt_uri&.gsub(%r{:[^/]*}, '\w+')
  ].compact.map { |str| Regexp.new("\\A#{str}\\Z") }
end
path_method_name() click to toggle source
# File lib/shaf/extensions/resource_uris.rb, line 259
def path_method_name
  "#{name}_path".freeze
end
path_method_string() click to toggle source
# File lib/shaf/extensions/resource_uris.rb, line 303
    def path_method_string
      <<~RUBY
        def #{path_signature}
          query_str = Shaf::MethodBuilder.query_string(query)
          \"#{interpolated_uri_string(uri)}\#{query_str}\".freeze
        end
      RUBY
    end
path_method_with_optional_arg_string() click to toggle source
# File lib/shaf/extensions/resource_uris.rb, line 336
    def path_method_with_optional_arg_string
      arg_no = extract_symbols(alt_uri).size
      <<~RUBY
        def #{path_signature(uri: alt_uri, optional_args: 1)}
          query_str = Shaf::MethodBuilder.query_string(query)
          if arg#{arg_no}.nil?
            warn <<~DEPRECATION

              Deprecated use of collection path helper:
              To get the collection path use ##{name}_collection_path instead of ##{path_method_name}.
              Or pass an argument to ##{path_method_name} to get the path to a resource.
                \#{caller.find { |s| !s.match? %r{lib/shaf/extensions} }}

            DEPRECATION

            \"#{interpolated_uri_string(alt_uri)}\#{query_str}\".freeze
          else
            \"#{interpolated_uri_string(uri)}\#{query_str}\".freeze
          end
        end
      RUBY
    end
path_signature(uri: @uri, optional_args: 0) click to toggle source
# File lib/shaf/extensions/resource_uris.rb, line 279
def path_signature(uri: @uri, optional_args: 0)
  signature(path_method_name, uri, optional_args: optional_args)
end
signature(method_name, uri, optional_args: 0) click to toggle source
# File lib/shaf/extensions/resource_uris.rb, line 283
def signature(method_name, uri, optional_args: 0)
  args = extract_symbols(uri).size.times.map { |i| "arg#{i}" }
  sym_count = args.size

  optional_args.times { |i| args << "arg#{sym_count + i} = nil" }
  args << '**query'

  "#{method_name}(#{args.join(', ')})"
end
template_method_name() click to toggle source
# File lib/shaf/extensions/resource_uris.rb, line 267
def template_method_name
  "#{path_method_name}_template".freeze
end
template_proc() click to toggle source
# File lib/shaf/extensions/resource_uris.rb, line 386
    def template_proc
      uri, alt_uri = @uri, @alt_uri

      if alt_uri.nil?
        -> { uri }
      else
        deprecated_method = template_method_name
        replacing_method = "#{name}_collection_path_template"

        lambda do |collection = NO_GIVEN_VALUE|
          if collection != NO_GIVEN_VALUE
            warn <<~DEPRECATION

              Deprecated use of uri template helper with `collection` argument:
              Use #{replacing_method} instead of #{deprecated_method}"
                #{caller.find { |s| !s.match? %r{lib/shaf/extensions} }}

            DEPRECATION
          else
            collection = false
          end

          collection ? alt_uri : uri
        end
      end
    end
transform_symbols(uri) { |segment, i| ... } click to toggle source
# File lib/shaf/extensions/resource_uris.rb, line 363
def transform_symbols(uri)
  i = -1
  uri.split('/').map do |segment|
    next segment unless segment.start_with? ':'
    i += 1
    yield segment, i
  end.join('/')
end
uri_method_name() click to toggle source
# File lib/shaf/extensions/resource_uris.rb, line 255
def uri_method_name
  "#{name}_uri".freeze
end
uri_method_string() click to toggle source
# File lib/shaf/extensions/resource_uris.rb, line 293
    def uri_method_string
      base_uri = UriHelper.base_uri
      <<~RUBY
        def #{uri_signature}
          query_str = Shaf::MethodBuilder.query_string(query)
          \"#{base_uri}#{interpolated_uri_string(uri)}\#{query_str}\".freeze
        end
      RUBY
    end
uri_method_with_optional_arg_string() click to toggle source
# File lib/shaf/extensions/resource_uris.rb, line 312
    def uri_method_with_optional_arg_string
      base_uri = UriHelper.base_uri
      arg_no = extract_symbols(alt_uri).size
      <<~RUBY
        def #{uri_signature(uri: alt_uri, optional_args: 1)}
          query_str = Shaf::MethodBuilder.query_string(query)
          if arg#{arg_no}.nil?
            warn <<~DEPRECATION

              Deprecated use of collection uri helper:
              To get the collection uri use ##{name}_collection_uri instead of ##{uri_method_name}.
              Or pass an argument to ##{uri_method_name} to get the uri to a resource.
                \#{caller.find { |s| !s.match? %r{lib/shaf/extensions/resource_uris.rb} }}

            DEPRECATION

            \"#{base_uri}#{interpolated_uri_string(alt_uri)}\#{query_str}\".freeze
          else
            \"#{base_uri}#{interpolated_uri_string(uri)}\#{query_str}\".freeze
          end
        end
      RUBY
    end
uri_signature(uri: @uri, optional_args: 0) click to toggle source
# File lib/shaf/extensions/resource_uris.rb, line 275
def uri_signature(uri: @uri, optional_args: 0)
  signature(uri_method_name, uri, optional_args: optional_args)
end