TypeDescriptor - radishengine/drowsy GitHub Wiki
Require Path: 'TypeDescriptor'
Creating a Descriptor
new TypeDescriptor( descriptorString [, parametersObject] )
descriptorString
must at least include the 'category/subtype'
part.
If it also has any name=value
parameters after that, these will be extracted, percent-decoded
and added to the TypeDescriptor's .parameters
object.
All properties set on parametersObject
will also be extracted, and have their values converted to strings.
Do not percent-encode values set on parametersObject
as they will not be decoded at this point,
and so will end up double-encoded when the full descriptor string is reconstructed later.
If the same parameter happens to be set in both descriptorString
and parametersObject
,
the value in parametersObject
will take priority.
If the same parameter appears more than once in descriptorString
, only the final value will be used.
Properties
For a descriptor representing type 'category/subtype; param1=value1; param2=value2'
:
.name
:'category/subtype'
.category
:'category'
.subtype
:'subtype'
.parameters
:{param1:"value1", param2:"value2"}
(For compatibility with filter objects (see below), type descriptors also have a .willNeverMatch
property, that is always false
.)
Methods
.toString()
Returns the full type descriptor string, with parameters percent-encoded as necessary.
.test( other )
Returns true
if the other type descriptor:
- has the same name (category and subtype) as this one, and
- for every parameter that this one has, has a parameter with the same name and value
...or if not, false
.
If the other descriptor includes parameters that this one does not have, they are ignored.
So, if we have two descriptors a
and b
, this:
if (a.test(b) === true && b.test(a) === false) ...
...is not a contradiction -- b
might have parameters that a
does not.
Instead of passing another TypeDescriptor object, you can also pass the same arguments as in new TypeDescriptor(...)
to describe the other
type to test.
Descriptor-as-Filter Methods
There are some additional TypeDescriptor methods that mirror the ones on a filter object (see below). A filter can be created from a descriptor, so what these methods essentially do is to convert the descriptor to a filter, then call the equivalent method on that filter, and return the result.
.or( filterOrDescriptor )
.filter( filterOrDescriptor )
.except( filterOrDescriptor )
.count( number )
.reset()
filterOrDescriptor
may be a descriptor object, a filter object,
the arguments for creating a descriptor,
or the arguments for creating a filter.
Filters
Type filters are a similar concept to type descriptors, but the key difference is that a filter can indicate a whole range of types, while a type descriptor represents a single, specific one.
Creating a Filter
Unlike type descriptors, you do not call a new
constructor directly in order to get a filter object.
TypeDescriptor.filter( descriptor [, descriptor, ...] )
Creates a filter which will match if any of the given descriptors match.
TypeDescriptor.filter(d1, d2, d3...)
is equivalent to d1.or(d2).or(d3).or(...)
TypeDescriptor.filter( [namePattern] [, parameterPatterns] )
namePattern
: a regular expression or string to match against the'category/subtype'
part
IfnamePattern
is a string,*
can be used as a wildcard. For example'audio/*'
for any type in theaudio
category.
IfnamePattern
is not specified, it is taken to be'*/*'
.parameterPatterns:
an object where each key is a parameter name and each value can be:true
: the parameter must be present (but can have any value)false
: the parameter must not be present at all- a regular expression: test that this matches successfully against the parameter value
- a string: the parameter value must be exactly equal to this
- any other value: the parameter value must be exactly equal this value, converted to a string
TypeDescriptor.except(...)
Takes the same parameters as TypeDescriptor.filter(...)
but returns a filter
that matches every type except the ones that .filter()
would match on.
In other words, an inverted or opposite version of .filter()
.
Filter Methods
.test(descriptor)
Returns true
or false
indicating whether this filter accepts the specified type.
You can pass the arguments for creating a descriptor, instead of an existing descriptor object.
.filter(other)
Creates a new filter which matches successfully if both this filter and the other
filter match a type.
You can pass the arguments for creating a filter, instead of an existing filter object.
.except(other)
Creates a new filter which matches successfully if this filter matches, but the other
filter does not.
You can pass the arguments for creating a filter, instead of an existing filter object.
.or(other)
Creates a new filter which matches successfully if either this filter or the other
filter matches.
You can pass the arguments for creating a filter, instead of an existing filter object.
.count(number)
Creates a filter similar to this one except that it will only match successfully the given number
of times, and then after that, always fails. In order to reset the counter, use .reset()
.
.reset()
Returns a filter where the counter initially specified by .count()
is reset to its initial number, or if no counter exists, returns the filter this method was called on.
.toString()
Returns this filter as a JSON-encoded string.
Properties
.willNeverMatch
true
if this is a filter that will never accept any types, for example a filter with a .count()
counter that has now reached zero.
Special Filters
TypeDescriptor.any
: Matches any type.TypeDescriptor.none
: Never matches any type.
Filter Examples
For any known audio format except WAV:
TypeDescriptor.filter('audio/*').except('audio/wav')
If you are only care about the first chunk, whatever it is:
TypeDescriptor.where('chunk/*).count(1);
Object Type Check
TypeDescriptor.isDescriptorOrFilter(object)
will return 'descriptor'
, 'filter'
or false
.
JSON Encoding
Type descriptors are encoded as strings, the same as their .toString()
value.
Type filters are encoded the following way (where DorF
is an encoded descriptor or filter):
{any: true}
: match any type{any: false}
: match no types{any: [DorF, DorF, ...]}
: match at least one filter of this list{all: [DorF, DorF, ...]}
: match every filter in this list{not: DorF}
match any type except this one{count: [number, DorF]}
: match on this, a maximum ofnumber
times{name: [pattern, flags]}
: match ifnew RegExp(pattern, flags)
matches the type name{parameter: [paramName, pattern, flags]}
: match ifnew RegExp(pattern, flags)
matches the specified parameter
You can decode a filter from this representation using TypeDescriptor.fromJSON(json)
.