ipaddr_range_set 0.9.1 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -12,6 +12,8 @@ but many of us have to do it anyway.
12
12
 
13
13
  ## Usage
14
14
 
15
+ ### Creating
16
+
15
17
  require 'ipaddr_range_set'
16
18
 
17
19
  # Zero or more segment arguments, which can be input in a variety of
@@ -23,25 +25,37 @@ but many of us have to do it anyway.
23
25
  '8.*.*.*', # informal splat notation, only for IPv4
24
26
  '8.8.0.0'..'8.8.2.255', # arbitrary range, works for IPv6 too.
25
27
  IPAddr.new(whatever), # arbitrary existing IPAddr object
26
- (ip_addr..ip_addr) # range of arbitrary IPAddr objects.
28
+ (ip_addr..ip_addr), # range of arbitrary IPAddr objects.
29
+ IPAddrRangeSet::LocalAddresses # An existing IPAddrRangeSet
27
30
  )
28
-
31
+
32
+ Ranges and splats are handled by this gem (in terms of underlying IPAddr), other strings
33
+ passed directly to IPAddr constructor.
34
+
29
35
  When ruby Range's are used, IPAddrRangeSet makes sure to use `Range#cover?`
30
36
  internally, not `Range#include?` (the latter being disastrous for anything that
31
37
  doesn't have `#to_int`). Triple dot `...` exclusive endpoint ranges are
32
38
  supported, which can be convenient if you don't like writing lots of `255`s
33
39
  in your range end points.
34
40
 
41
+ ### Checking
42
+
43
+ And then, once you have an IPAddrRangeSet, you can check if a particular
44
+ ip is in the range set, using string (IPv4 or v6) or IPAddr instance:
45
+
35
46
  range.include? '220.1.10.5'
36
47
  range.include? IPAddr.new('220.1.10.5')
37
48
 
38
49
  `#include?` is aliased as `#===` so you can easily use it in `case/when`.
50
+
51
+
52
+ ### Immutable, but create new with union of existing
39
53
 
40
54
  IPAddrRangeSets are immutable, but you can create new ones combining existing
41
55
  ranges:
42
56
 
43
57
  new_range = IPAddrRangeSet('8.10.5.1') + IPAddrRangeSet('8.11.6.1')
44
- new_range = IPAddrRangeSet('8.10.5.1').add('8.0.0.0/24', 10.0.0.1..10.1.4.255 )
58
+ new_range = IPAddrRangeSet('8.10.5.1').add('8.0.0.0/24', '10.0.0.1'..'10.1.4.255' )
45
59
 
46
60
  The internal implementation just steps through all range segments and checks
47
61
  the argument for inclusion, there's no special optimization to detect overlapping
@@ -52,6 +66,8 @@ involving a search tree of some kind anyway.
52
66
  As above range 'union' is supported, but range intersection is not. It's
53
67
  a bit tricky to implement well, and I don't have a use case for it.
54
68
 
69
+ ## Built-in ranges for checking local addresses
70
+
55
71
  Built-in constants are available for local (private, not publically routable)
56
72
  and loopback ranges in both IPv4 and IPv6. `IPAddrRangeSet::IPv4Local`, `IPv4Loopback`, `IPv6Local`,
57
73
  `IPv6Loopback`. The constant `LocalAddresses` is the union of all v4 and v6 local
@@ -4,10 +4,28 @@ require 'ipaddr'
4
4
 
5
5
  class IPAddrRangeSet
6
6
 
7
+ # Zero or more segment arguments, which can be input in a variety of
8
+ # of formats.
9
+ # range = IPAddrRangeSet.new(
10
+ # '220.1.10.3', # a single IPv4 as a string
11
+ # '2001:db8::10', # a single IPv6 as a string
12
+ # '8.0.0.0/24', # IPv4 as CIDR, works for IPv6 CIDR too
13
+ # '8.*.*.*', # informal splat notation, only for IPv4
14
+ # '8.8.0.0'..'8.8.2.255', # arbitrary range, works for IPv6 too.
15
+ # IPAddr.new(whatever), # arbitrary existing IPAddr object
16
+ # (ip_addr..ip_addr), # range of arbitrary IPAddr objects.
17
+ # IPAddrRangeSet::LocalAddresses # An existing IPAddrRangeSet
18
+ # )
7
19
  def initialize(*segments_list)
8
20
 
9
21
  segments_list.each do |segment|
10
22
 
23
+ if IPAddrRangeSet === segment
24
+ # just absorb em
25
+ segments.concat segment.segments
26
+ next
27
+ end
28
+
11
29
  if IPAddr === segment
12
30
  segment.freeze
13
31
  segments << segment
@@ -84,8 +102,7 @@ class IPAddrRangeSet
84
102
  #
85
103
  # IPAddrRangeSets are immutable.
86
104
  def union(other_set)
87
- all_segments = self.segments + other_set.segments
88
- self.class.new *all_segments
105
+ self.class.new(self, other_set)
89
106
  end
90
107
  alias_method :'+', :union
91
108
 
@@ -96,6 +113,7 @@ class IPAddrRangeSet
96
113
  return self + IPAddrRangeSet.new(*new_segments)
97
114
  end
98
115
 
116
+
99
117
  protected
100
118
 
101
119
  # Not public API, but used for creating unions of range sets,
@@ -1,3 +1,3 @@
1
1
  module IpaddrRangeSet
2
- VERSION = "0.9.1"
2
+ VERSION = "0.10.0"
3
3
  end
@@ -37,6 +37,7 @@ class TestIpAddrRange < Test::Unit::TestCase
37
37
 
38
38
  test_inclusion("ipv4_range_str_exclusive_endpoint", ("128.220.10.1"..."128.220.11.255"), "128.220.10.1", "128.220.9.255", "128.220.11.255")
39
39
 
40
+ test_inclusion("existing IPAddrRangeSEt obj", IPAddrRangeSet.new("128.220.10.1"), "128.220.10.1", "128.220.10.2")
40
41
 
41
42
  def test_incompatible_range
42
43
  # one ipv4 one ipv6.
@@ -121,6 +122,7 @@ class TestIpAddrRange < Test::Unit::TestCase
121
122
  end
122
123
 
123
124
  def test_local_constants
125
+
124
126
  %w{10.3.3.1 172.16.4.1 192.168.2.1 fc00::1 127.0.0.1 ::1}.each do |ip|
125
127
  assert IPAddrRangeSet::LocalAddresses.include?(ip), "IPAddrRangeSet::LocalAddresses should include #{ip}"
126
128
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ipaddr_range_set
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.1
4
+ version: 0.10.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-11-08 00:00:00.000000000 Z
12
+ date: 2012-11-12 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description:
15
15
  email: