ipaddr_range_set 0.9.1 → 0.10.0

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.
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: