module PushRoutes class PushRouteUrl attr_accessor :source # # if this push_route_url is a new route that needs to be registered # can be determined by if the input passed in was a string or not # attr_accessor :isNew def initialize(input) if (input.is_a?(ActionDispatch::Journey::Route)) #Remove traiing format string @source = input.path.spec.to_s.gsub(/\(\.\:format\)\Z/, "") @isNew = false elsif input.is_a? String @source = input @isNew = true else raise ArgumentError.new("Unexpected input: #{input}") end #Parses out the required parameters for the route as a list of symbols @url_args = @source.scan(/\/\:([^\/]+)/).flatten.map { |e| e.to_sym } end # # Returns a true url from the original route with parameters filled in # If the route has no parameters this function simply returns the route, ignoring input # If the parameters are insufficient an ArgumentError is raised # # @param params [Hash] params # # @return [String] completed url def notification_string(params) if @url_args.count == 0 @source else unless (params.is_a?(Hash)) raise ArgumentError.new("Params for #{@source} must be a hash with: #{@url_args}") end built_string = @source @url_args.each do |e| if (params.include?(e)) built_string = built_string.gsub(Regexp.new("\\:#{e}"), params[e].to_s) else raise ArgumentError.new("Missing param #{e}") end end built_string end end def to_s @source end # # returns true of url is a valid expression of the route represented # @param url [string] url to check # # @return [bool] true if url matches this route # TODO: testing on this function def matches(url) str = @source.gsub(/(?!\/)\:.*?(?=\/|$)/, "([^\/]+?)") str = "^" + str + "$" Regexp.new(str).match(url) end # Gets the parameter associations from a url if they are well formed, meaning, each # parameter is preceded by another token # @return [Hash] parameter_symbol => preceding symbol def param_associations @source.scan(/\/([^\/]*?)\/\:([^\/]+)/).map {|k,v| [v.to_sym,k]}.to_h end end end