Class: Rage::Router::Constrainer

Inherits:
Object
  • Object
show all
Defined in:
lib/rage/router/constrainer.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(custom_strategies) ⇒ Constrainer

Returns a new instance of Constrainer.



8
9
10
11
12
13
14
# File 'lib/rage/router/constrainer.rb', line 8

def initialize(custom_strategies)
  @strategies = {
    host: Rage::Router::Strategies::Host.new
  }

  @strategies_in_use = Set.new
end

Instance Attribute Details

#strategiesObject (readonly)

Returns the value of attribute strategies.



6
7
8
# File 'lib/rage/router/constrainer.rb', line 6

def strategies
  @strategies
end

Instance Method Details

#__build_derive_constraintsObject

Optimization: build a fast function for deriving the constraints for all the strategies at once. We inline the definitions of the version constraint and the host constraint for performance. If no constraining strategies are in use (no routes constrain on host, or version, or any custom strategies) then we don't need to derive constraints for each route match, so don't do anything special, and just return undefined This allows us to not allocate an object to hold constraint values if no constraints are defined.



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/rage/router/constrainer.rb', line 64

def __build_derive_constraints
  return if @strategies_in_use.empty?

  lines = ["{"]

  @strategies_in_use.each do |key|
    strategy = @strategies[key]
    # Optimization: inline the derivation for the common built in constraints
    if !strategy.custom?
      if key == :host
        lines << "   host: env['HTTP_HOST'.freeze],"
      else
        raise ArgumentError, "unknown non-custom strategy for compiling constraint derivation function"
      end
    else
      lines << "  #{strategy.name}: @strategies[#{key}].derive_constraint(env),"
    end
  end

  lines << "}"

  instance_eval <<-RUBY
    def derive_constraints(env)
      #{lines.join("\n")}
    end
  RUBY
end

#derive_constraints(env) ⇒ Object



29
30
# File 'lib/rage/router/constrainer.rb', line 29

def derive_constraints(env)
end

#has_constraint_strategy(strategy_name) ⇒ Object



20
21
22
23
24
25
26
27
# File 'lib/rage/router/constrainer.rb', line 20

def has_constraint_strategy(strategy_name)
  custom_constraint_strategy = @strategies[strategy_name]
  if custom_constraint_strategy
    return custom_constraint_strategy.custom? || strategy_used?(strategy_name)
  end

  false
end

#new_store_for_constraint(constraint) ⇒ Object

Raises:

  • (ArgumentError)


47
48
49
50
# File 'lib/rage/router/constrainer.rb', line 47

def new_store_for_constraint(constraint)
  raise ArgumentError, "No strategy registered for constraint key '#{constraint}'" unless @strategies[constraint]
  @strategies[constraint].storage
end

#note_usage(constraints) ⇒ Object

When new constraints start getting used, we need to rebuild the deriver to derive them. Do so if we see novel constraints used.



33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/rage/router/constrainer.rb', line 33

def note_usage(constraints)
  if constraints
    before_size = @strategies_in_use.size

    constraints.each_key do |key|
      @strategies_in_use.add(key)
    end

    if before_size != @strategies_in_use.size
      __build_derive_constraints
    end
  end
end

#strategy_used?(strategy_name) ⇒ Boolean

Returns:

  • (Boolean)


16
17
18
# File 'lib/rage/router/constrainer.rb', line 16

def strategy_used?(strategy_name)
  @strategies_in_use.include?(strategy_name)
end

#validate_constraints(constraints) ⇒ Object



52
53
54
55
56
57
58
59
# File 'lib/rage/router/constrainer.rb', line 52

def validate_constraints(constraints)
  constraints.each do |key, value|
    strategy = @strategies[key]
    raise ArgumentError, "No strategy registered for constraint key '#{key}'" unless strategy

    strategy.validate(value)
  end
end