Sha256: a0793a0e6f9150a9a2b559f8d08f0bf623a15630a326645d54568e9402255eb4

Contents?: true

Size: 1.85 KB

Versions: 42

Compression:

Stored size: 1.85 KB

Contents

module Acfs

  # @api private
  #
  # Describes a URL with placeholders.
  #
  class Location
    attr_reader :arguments, :raw, :struct, :args

    REGEXP= /^:([A-z][A-z0-9_]*)$/

    def initialize(uri, args = {})
      @raw       = URI.parse uri
      @args      = args
      @struct    = raw.path.split('/').reject(&:empty?).map{|s| s =~ REGEXP ? $1.to_sym : s }
      @arguments = struct.select{|s| Symbol === s }
    end

    def build(args = {})
      unless Hash === args
        raise ArgumentError.new "URI path arguments must be a hash, `#{args.inspect}' given."
      end

      self.class.new raw.to_s, args.merge(self.args)
    end

    def extract_from(*args)
      args = Hash.new.tap do |collect|
        arguments.each{|key| collect[key] = extract_arg key, args }
      end

      build args
    end

    def str
      uri = raw.dup
      uri.path = URI.escape '/' + struct.map{|s| lookup_arg(s, args) }.join('/')
      uri.to_s
    end

    def raw_uri
      raw.to_s
    end
    alias_method :to_s, :raw_uri

    private
    def extract_arg(key, hashes)
      hashes.each_with_index do |hash, index|
        return (index == 0 ? hash.delete(key) : hash.fetch(key)) if hash.has_key?(key)
      end

      nil
    end

    def lookup_arg(arg, args)
      Symbol === arg ? lookup_replacement(arg, args) : arg
    end

    def lookup_replacement(sym, args)
      value = get_replacement(sym, args).to_s
      return value unless value.empty?

      raise ArgumentError.new "Cannot replace path argument `#{sym}' with empty string."
    end

    def get_replacement(sym, args)
      args.fetch(sym.to_s) do
        args.fetch(sym) do
          if args[:raise].nil? || args[:raise]
            raise ArgumentError.new "URI path argument `#{sym}' missing on `#{to_s}'. Given: `#{args}.inspect'"
          else
            ":#{sym}"
          end
        end
      end
    end
  end
end

Version data entries

42 entries across 42 versions & 1 rubygems

Version Path
acfs-0.42.0 lib/acfs/location.rb
acfs-0.41.1 lib/acfs/location.rb
acfs-0.41.1.beta1 lib/acfs/location.rb
acfs-0.41.0 lib/acfs/location.rb
acfs-0.40.1.rc1 lib/acfs/location.rb
acfs-0.40.0 lib/acfs/location.rb
acfs-0.39.1 lib/acfs/location.rb
acfs-0.39.0 lib/acfs/location.rb
acfs-1.0.0.dev.1.b305 lib/acfs/location.rb
acfs-0.38.0 lib/acfs/location.rb
acfs-1.0.0.dev.1.b298 lib/acfs/location.rb
acfs-1.0.0.dev.1.b297 lib/acfs/location.rb
acfs-0.37.0.1.b295 lib/acfs/location.rb
acfs-0.37.0 lib/acfs/location.rb
acfs-0.36.0.1.b293 lib/acfs/location.rb
acfs-0.36.0 lib/acfs/location.rb
acfs-0.35.0.1.b291 lib/acfs/location.rb
acfs-0.35.0 lib/acfs/location.rb
acfs-0.34.1.1.b289 lib/acfs/location.rb
acfs-0.34.1 lib/acfs/location.rb