Class: Protocol::Media::Set

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/protocol/media/set.rb

Overview

A set of compatible media ranges.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(media_ranges = []) ⇒ Set

Initialize a new mutable media set with the given media ranges.

Freezing the set compiles the ranges into an efficient immutable index.



103
104
105
106
107
108
109
110
# File 'lib/protocol/media/set.rb', line 103

def initialize(media_ranges = [])
	@entries = []
	@types = nil
	
	media_ranges.each do |media_range|
		add(media_range)
	end
end

Class Method Details

.for(media_ranges) ⇒ Object

Convert a sequence of ranges into a media set.

Existing sets are returned unchanged, including their frozen state.



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/protocol/media/set.rb', line 77

def self.for(media_ranges)
	# Preserve an existing media set:
	if media_ranges.instance_of?(self)
		return media_ranges
	end
	
	# Preserve the universal media set:
	if media_ranges.instance_of?(Any)
		return media_ranges
	end
	
	set = new(media_ranges)
	set.freeze
	
	if set.universal?
		return ANY
	end
	
	return set
end

Instance Method Details

#add(media_range) ⇒ Object Also known as: <<

Add a media range to the set under construction.

Raises:

  • (FrozenError)


115
116
117
118
119
120
121
122
123
124
# File 'lib/protocol/media/set.rb', line 115

def add(media_range)
	raise FrozenError, "can't modify frozen #{self.class}" if frozen?
	
	media_range = normalize(media_range)
	
	@entries << media_range
	@types = nil
	
	return self
end

#each(&block) ⇒ Object

Enumerate the canonical media ranges which define membership.



188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
# File 'lib/protocol/media/set.rb', line 188

def each(&block)
	return to_enum unless block
	
	types = self.types
	
	if types.instance_of?(Any)
		types.each(&block)
		return self
	end
	
	types.each do |type, subtypes|
		if subtypes.instance_of?(Any)
			yield Range.new(type, "*")
		else
			subtypes.each do |subtype|
				yield Range.new(type, subtype)
			end
		end
	end
	
	return self
end

#empty?Boolean

Whether the set contains no media ranges.

Returns:

  • (Boolean)


227
228
229
# File 'lib/protocol/media/set.rb', line 227

def empty?
	return types.empty?
end

#freezeObject

Freeze the media set, compiling its ranges into an efficient index.



130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/protocol/media/set.rb', line 130

def freeze
	return self if frozen?
	
	types = self.types
	@entries = nil
	
	unless types.instance_of?(Any)
		types.each_value(&:freeze)
		types.freeze
	end
	
	return super
end

#include?(media_range) ⇒ Boolean Also known as: ===, match?

Whether the set contains a compatible media type or range.

Returns:

  • (Boolean)


147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# File 'lib/protocol/media/set.rb', line 147

def include?(media_range)
	media_range = normalize(media_range)
	type = media_range.type
	subtype = media_range.subtype
	types = self.types
	
	if types.instance_of?(Any)
		return true
	end
	
	# A wildcard type matches any non-empty set:
	if type == "*"
		return !types.empty?
	end
	
	subtypes = types[type]
	
	# An unknown type cannot match:
	unless subtypes
		return false
	end
	
	# A wildcard subtype matches any known type:
	if subtype == "*"
		return true
	end
	
	# A type-wide wildcard matches every subtype:
	if subtypes.instance_of?(Any)
		return true
	end
	
	return subtypes.include?(subtype)
end

#sizeObject

The number of canonical membership ranges.



213
214
215
216
217
218
219
220
221
222
223
# File 'lib/protocol/media/set.rb', line 213

def size
	types = self.types
	
	if types.instance_of?(Any)
		return types.size
	end
	
	return types.sum do |_type, subtypes|
		subtypes.size
	end
end

#universal?Boolean

Whether this set matches every media range.

Returns:

  • (Boolean)


233
234
235
# File 'lib/protocol/media/set.rb', line 233

def universal?
	return types.instance_of?(Any)
end