rack-mount 0.0.1 → 0.8.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. data/README.rdoc +12 -4
  2. data/lib/rack/mount/analysis/histogram.rb +55 -6
  3. data/lib/rack/mount/analysis/splitting.rb +103 -89
  4. data/lib/rack/mount/code_generation.rb +120 -0
  5. data/lib/rack/mount/generatable_regexp.rb +95 -48
  6. data/lib/rack/mount/multimap.rb +84 -41
  7. data/lib/rack/mount/prefix.rb +13 -8
  8. data/lib/rack/mount/regexp_with_named_groups.rb +27 -7
  9. data/lib/rack/mount/route.rb +75 -18
  10. data/lib/rack/mount/route_set.rb +308 -22
  11. data/lib/rack/mount/strexp/parser.rb +160 -0
  12. data/lib/rack/mount/strexp/tokenizer.rb +83 -0
  13. data/lib/rack/mount/strexp.rb +54 -79
  14. data/lib/rack/mount/utils.rb +65 -174
  15. data/lib/rack/mount/vendor/regin/regin/alternation.rb +40 -0
  16. data/lib/rack/mount/vendor/regin/regin/anchor.rb +4 -0
  17. data/lib/rack/mount/vendor/regin/regin/atom.rb +54 -0
  18. data/lib/rack/mount/vendor/regin/regin/character.rb +51 -0
  19. data/lib/rack/mount/vendor/regin/regin/character_class.rb +50 -0
  20. data/lib/rack/mount/vendor/regin/regin/collection.rb +77 -0
  21. data/lib/rack/mount/vendor/regin/regin/expression.rb +126 -0
  22. data/lib/rack/mount/vendor/regin/regin/group.rb +90 -0
  23. data/lib/rack/mount/vendor/regin/regin/options.rb +55 -0
  24. data/lib/rack/mount/vendor/regin/regin/parser.rb +546 -0
  25. data/lib/rack/mount/vendor/regin/regin/tokenizer.rb +255 -0
  26. data/lib/rack/mount/vendor/regin/regin/version.rb +3 -0
  27. data/lib/rack/mount/vendor/regin/regin.rb +75 -0
  28. data/lib/rack/mount/version.rb +3 -0
  29. data/lib/rack/mount.rb +13 -17
  30. metadata +88 -35
  31. data/lib/rack/mount/analysis/frequency.rb +0 -51
  32. data/lib/rack/mount/const.rb +0 -45
  33. data/lib/rack/mount/exceptions.rb +0 -3
  34. data/lib/rack/mount/generation/route.rb +0 -57
  35. data/lib/rack/mount/generation/route_set.rb +0 -163
  36. data/lib/rack/mount/meta_method.rb +0 -104
  37. data/lib/rack/mount/mixover.rb +0 -47
  38. data/lib/rack/mount/recognition/code_generation.rb +0 -99
  39. data/lib/rack/mount/recognition/route.rb +0 -59
  40. data/lib/rack/mount/recognition/route_set.rb +0 -88
  41. data/lib/rack/mount/vendor/multimap/multimap.rb +0 -466
  42. data/lib/rack/mount/vendor/multimap/multiset.rb +0 -153
  43. data/lib/rack/mount/vendor/multimap/nested_multimap.rb +0 -156
@@ -0,0 +1,77 @@
1
+ module Regin
2
+ class Collection
3
+ include Enumerable
4
+
5
+ def initialize(*args)
6
+ @array = Array.new(*args)
7
+ end
8
+
9
+ def each
10
+ @array.each{ |item| yield item }
11
+ end
12
+
13
+ def [](i)
14
+ @array[i]
15
+ end
16
+
17
+ def length
18
+ @array.length
19
+ end
20
+ alias_method :size, :length
21
+
22
+ def first
23
+ @array.first
24
+ end
25
+
26
+ def last
27
+ @array.last
28
+ end
29
+
30
+ def +(other)
31
+ ary = other.is_a?(self.class) ? other.internal_array : other
32
+ self.class.new(@array + ary)
33
+ end
34
+
35
+ def to_regexp(anchored = false)
36
+ re = to_s(true)
37
+ re = "\\A#{re}\\Z" if anchored
38
+ Regexp.compile(re, flags)
39
+ end
40
+
41
+ def match(char)
42
+ to_regexp.match(char)
43
+ end
44
+
45
+ def include?(char)
46
+ any? { |e| e.include?(char) }
47
+ end
48
+
49
+ def ==(other) #:nodoc:
50
+ case other
51
+ when String
52
+ other == to_s
53
+ when Array
54
+ other == @array
55
+ else
56
+ eql?(other)
57
+ end
58
+ end
59
+
60
+ def eql?(other) #:nodoc:
61
+ other.instance_of?(self.class) && @array.eql?(other.internal_array)
62
+ end
63
+
64
+ protected
65
+ def internal_array #:nodoc:
66
+ @array
67
+ end
68
+
69
+ def extract_options(args)
70
+ if args.last.is_a?(Hash)
71
+ return args[0..-2], args.last
72
+ else
73
+ return args, {}
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,126 @@
1
+ module Regin
2
+ class Expression < Collection
3
+ attr_reader :ignorecase, :multiline, :extended
4
+
5
+ def initialize(*args)
6
+ args, options = extract_options(args)
7
+
8
+ @multiline = @ignorecase = @extended = nil
9
+
10
+ if args.length == 1 && args.first.instance_of?(Array)
11
+ super(args.first)
12
+ else
13
+ args = args.map { |e| e.instance_of?(String) ? Character.new(e) : e }
14
+ super(args)
15
+ end
16
+
17
+ self.multiline = options[:multiline] if options.key?(:multiline)
18
+ self.ignorecase = options[:ignorecase] if options.key?(:ignorecase)
19
+ self.extended = options[:extended] if options.key?(:extended)
20
+ end
21
+
22
+ # Returns true if expression could be treated as a literal string.
23
+ #
24
+ # A Expression is literal if all its elements are literal.
25
+ def literal?
26
+ !ignorecase && all? { |e| e.literal? }
27
+ end
28
+
29
+ def anchored?
30
+ anchored_to_start? && anchored_to_end?
31
+ end
32
+
33
+ def anchored_to_start?
34
+ first.is_a?(Anchor) && first == '\A'
35
+ end
36
+
37
+ def anchored_to_end?
38
+ last.is_a?(Anchor) && last == '\Z'
39
+ end
40
+
41
+ def anchored_to_line?
42
+ anchored_to_start_of_line? && anchored_to_end_of_line?
43
+ end
44
+
45
+ def anchored_to_start_of_line?
46
+ anchored_to_start? || (first.is_a?(Anchor) && first == '^')
47
+ end
48
+
49
+ def anchored_to_end_of_line?
50
+ anchored_to_end? || (last.is_a?(Anchor) && last == '$')
51
+ end
52
+
53
+ def options?
54
+ options.any?(true)
55
+ end
56
+
57
+ def flags
58
+ options.to_i
59
+ end
60
+
61
+ def +(other)
62
+ ary = other.is_a?(self.class) ? other.internal_array : other
63
+ ary = @array + ary + [options.to_h(true)]
64
+ self.class.new(*ary)
65
+ end
66
+
67
+ def dup(options = {})
68
+ expression = super()
69
+ expression.multiline = options[:multiline] if options.key?(:multiline)
70
+ expression.ignorecase = options[:ignorecase] if options.key?(:ignorecase)
71
+ expression.extended = options[:extended] if options.key?(:extended)
72
+ expression
73
+ end
74
+
75
+ def to_s(parent = false)
76
+ if parent || !options?
77
+ map { |e| e.to_s(parent) }.join
78
+ else
79
+ with, without = [], []
80
+ multiline ? (with << 'm') : (without << 'm')
81
+ ignorecase ? (with << 'i') : (without << 'i')
82
+ extended ? (with << 'x') : (without << 'x')
83
+
84
+ with = with.join
85
+ without = without.any? ? "-#{without.join}" : ''
86
+
87
+ "(?#{with}#{without}:#{map { |e| e.to_s(true) }.join})"
88
+ end
89
+ end
90
+
91
+ def inspect #:nodoc:
92
+ "#<Expression #{to_s.inspect}>"
93
+ end
94
+
95
+ def casefold?
96
+ ignorecase
97
+ end
98
+
99
+ def eql?(other) #:nodoc:
100
+ super &&
101
+ !!self.multiline == !!other.multiline &&
102
+ !!self.ignorecase == !!other.ignorecase &&
103
+ !!self.extended == !!other.extended
104
+ end
105
+
106
+ protected
107
+ def options
108
+ Options.new(multiline, ignorecase, extended)
109
+ end
110
+
111
+ def multiline=(multiline)
112
+ @multiline = multiline
113
+ end
114
+
115
+ def ignorecase=(ignorecase)
116
+ if @ignorecase.nil?
117
+ @array.map! { |e| e.dup(:ignorecase => ignorecase) }
118
+ @ignorecase = ignorecase
119
+ end
120
+ end
121
+
122
+ def extended=(extended)
123
+ @extended = extended
124
+ end
125
+ end
126
+ end
@@ -0,0 +1,90 @@
1
+ module Regin
2
+ class Group
3
+ attr_reader :expression, :quantifier, :lookahead, :capture, :index, :name
4
+
5
+ def initialize(expression, options = {})
6
+ @quantifier = @index = @name = nil
7
+ @capture = true
8
+ @expression = expression.dup(options)
9
+
10
+ @quantifier = options[:quantifier] if options.key?(:quantifier)
11
+ @lookahead = options[:lookahead] if options.key?(:lookahead)
12
+ @capture = options[:capture] if options.key?(:capture)
13
+ @index = options[:index] if options.key?(:index)
14
+ @name = options[:name] if options.key?(:name)
15
+ end
16
+
17
+ def option_names
18
+ %w( quantifier capture index name )
19
+ end
20
+
21
+ # Returns true if expression could be treated as a literal string.
22
+ #
23
+ # A Group is literal if its expression is literal and it has no quantifier.
24
+ def literal?
25
+ quantifier.nil? && lookahead.nil? && expression.literal?
26
+ end
27
+
28
+ def to_s(parent = false)
29
+ if lookahead == :postive
30
+ "(?=#{expression.to_s(parent)})#{quantifier}"
31
+ elsif lookahead == :negative
32
+ "(?!#{expression.to_s(parent)})#{quantifier}"
33
+ elsif !expression.options?
34
+ "(#{capture ? '' : '?:'}#{expression.to_s(parent)})#{quantifier}"
35
+ elsif capture == false
36
+ "#{expression.to_s}#{quantifier}"
37
+ else
38
+ "(#{expression.to_s})#{quantifier}"
39
+ end
40
+ end
41
+
42
+ def to_regexp(anchored = false)
43
+ re = to_s
44
+ re = "\\A#{re}\\Z" if anchored
45
+ Regexp.compile(re)
46
+ end
47
+
48
+ def dup(options = {})
49
+ original_options = option_names.inject({}) do |h, m|
50
+ h[m.to_sym] = send(m)
51
+ h
52
+ end
53
+ self.class.new(expression, original_options.merge(options))
54
+ end
55
+
56
+ def inspect #:nodoc:
57
+ to_s.inspect
58
+ end
59
+
60
+ def match(char)
61
+ to_regexp.match(char)
62
+ end
63
+
64
+ def include?(char)
65
+ expression.include?(char)
66
+ end
67
+
68
+ def capture?
69
+ capture
70
+ end
71
+
72
+ def ==(other) #:nodoc:
73
+ case other
74
+ when String
75
+ other == to_s
76
+ else
77
+ eql?(other)
78
+ end
79
+ end
80
+
81
+ def eql?(other) #:nodoc:
82
+ other.is_a?(self.class) &&
83
+ self.expression == other.expression &&
84
+ self.quantifier == other.quantifier &&
85
+ self.capture == other.capture &&
86
+ self.index == other.index &&
87
+ self.name == other.name
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,55 @@
1
+ module Regin
2
+ class Options
3
+ def self.from_int(flags)
4
+ multiline = flags & Regexp::MULTILINE != 0
5
+ ignorecase = flags & Regexp::IGNORECASE != 0
6
+ extended = flags & Regexp::EXTENDED != 0
7
+
8
+ new(multiline, ignorecase, extended)
9
+ end
10
+
11
+ attr_reader :multiline, :ignorecase, :extended
12
+
13
+ def initialize(*args)
14
+ if args.first.is_a?(Hash)
15
+ @multiline = args[0][:multiline]
16
+ @ignorecase = args[0][:ignorecase]
17
+ @extended = args[0][:extended]
18
+ else
19
+ @multiline = args[0]
20
+ @ignorecase = args[1]
21
+ @extended = args[2]
22
+ end
23
+ end
24
+
25
+ def any?(explicit = false)
26
+ if explicit
27
+ !multiline.nil? || !ignorecase.nil? || !extended.nil?
28
+ else
29
+ multiline || ignorecase || extended
30
+ end
31
+ end
32
+
33
+ def to_h(explicit = false)
34
+ if explicit
35
+ options = {}
36
+ options[:multiline] = multiline unless multiline.nil?
37
+ options[:ignorecase] = ignorecase unless ignorecase.nil?
38
+ options[:extended] = extended unless extended.nil?
39
+ options
40
+ else
41
+ { :multiline => multiline,
42
+ :ignorecase => ignorecase,
43
+ :extended => extended }
44
+ end
45
+ end
46
+
47
+ def to_i
48
+ flag = 0
49
+ flag |= Regexp::MULTILINE if multiline
50
+ flag |= Regexp::IGNORECASE if ignorecase
51
+ flag |= Regexp::EXTENDED if extended
52
+ flag
53
+ end
54
+ end
55
+ end