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
    If namePattern is a string, * can be used as a wildcard. For example 'audio/*' for any type in the audio category.
    If namePattern 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 of number times
  • {name: [pattern, flags]}: match if new RegExp(pattern, flags) matches the type name
  • {parameter: [paramName, pattern, flags]}: match if new RegExp(pattern, flags) matches the specified parameter

You can decode a filter from this representation using TypeDescriptor.fromJSON(json).