# enumerated_types

> Full featured, extensible enumerations for javascript.

Latest version **1.1.0** (published 2021-04-13) · BSD-3-Clause license · 0 weekly downloads

## Install

```sh
npm install enumerated_types
pnpm add enumerated_types
yarn add enumerated_types
bun add enumerated_types
```

## Health

**Score 15/100 (F)** — status: abandoned.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 1.1.0 |
| Published | 2021-04-13 |
| First published | 2021-03-17 |
| Weekly downloads | 0 |
| License | BSD-3-Clause |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 0 |
| Unpacked size | 68.9 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| Author | Jason DeLaat |
| Maintainers | jasondelaat |
| Keywords | enum, enumerate, enumeration, constants, flags, utility, enumerated_types, node, nodejs, browser |

## Links

- npm: https://www.npmjs.com/package/enumerated_types
- Repository: https://github.com/jasondelaat/enumerated_types
- Homepage: https://github.com/jasondelaat/enumerated_types#readme
- Issues: https://github.com/jasondelaat/enumerated_types/issues
- npm.io page: https://npm.io/package/enumerated_types

## Alternatives

- [@opentelemetry/exporter-zipkin](https://npm.io/package/@opentelemetry/exporter-zipkin.md) — 14.8M weekly downloads
- [pusher-js](https://npm.io/package/pusher-js.md) — 2.0M weekly downloads
- [browserify](https://npm.io/package/browserify.md) — 1.7M weekly downloads
- [sqs-consumer](https://npm.io/package/sqs-consumer.md) — 1.7M weekly downloads
- [@sanity/eventsource](https://npm.io/package/@sanity/eventsource.md) — 930.8K weekly downloads

## Recent versions

- 1.1.0 (latest) — 2021-04-13
- 1.0.1 — 2021-03-17
- 1.0.0 — 2021-03-17

## README

# Table of Contents

1.  [Enumerated Types for Javascript](#org4c4fe2f)
    1.  [Getting Started](#org89fa3c2)
        1.  [Installing](#org65a40a3)
    2.  [Usage](#org8ab3a30)
        1.  [Enumerated constants with `Enum`](#org2e9ec5c)
        2.  [Enumerated constants with `EnumObjects`](#orgd1deb4d)
        3.  [Binary options with `Flags`](#org78854e1)
        4.  [Constrained values with `EnumeratedRange`](#orge23f6d4)


<a id="org4c4fe2f"></a>

# Enumerated Types for Javascript

Full featured, extensible enumerations for javascript.  


<a id="org89fa3c2"></a>

## Getting Started


<a id="org65a40a3"></a>

### Installing

1.  Node

        npm install enumerated_types

2.  Browser

    Download the package from [here](https://github.com/jasondelaat/enumeration/releases). 
    
    The `js` folder contains two files: `enumerated_types.js` and
    `enumerated_module.js`.
    
    To use `enumerated_types.js` load it from an HTML script tag:
    
        <script type='text/javascript' src='/js/enumerated_types.js'></script>
    
    To use `enumerated_module.js` import the required
    objects/functions:
    
        import * as enumeration from '/js/enumerated_module.js'
        import {Enum} from '/js/enumerated_module.js'


<a id="org8ab3a30"></a>

## Usage

The `enumeration` package provides a base object,
`EnumerationBase`, on which to base enumerated types.

The following methods are available on all enumerated types:

<table border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">


<colgroup>
<col  class="org-left" />

<col  class="org-left" />

<col  class="org-left" />
</colgroup>
<thead>
<tr>
<th scope="col" class="org-left">Method</th>
<th scope="col" class="org-left">Description</th>
<th scope="col" class="org-left">Default Implementation</th>
</tr>
</thead>

<tbody>
<tr>
<td class="org-left">first()</td>
<td class="org-left">Returns the first value in the enumeration</td>
<td class="org-left">no</td>
</tr>


<tr>
<td class="org-left">fromInt(i)</td>
<td class="org-left">Returns an enumeration given an integer</td>
<td class="org-left">no</td>
</tr>


<tr>
<td class="org-left">isEqualTo(other)</td>
<td class="org-left">Tests two enumerations for equality</td>
<td class="org-left">yes</td>
</tr>


<tr>
<td class="org-left">isGreater(other)</td>
<td class="org-left">Test if one enumeration is greater than another</td>
<td class="org-left">yes</td>
</tr>


<tr>
<td class="org-left">isGreaterOrEqualTo(other)</td>
<td class="org-left">Test if one enumeration is greater than or equal to another</td>
<td class="org-left">yes</td>
</tr>


<tr>
<td class="org-left">isLess(other)</td>
<td class="org-left">Test if one enumeration is less than another</td>
<td class="org-left">yes</td>
</tr>


<tr>
<td class="org-left">isLessOrEqualTo(other)</td>
<td class="org-left">Test if one enumeration is less than or equal to another</td>
<td class="org-left">yes</td>
</tr>


<tr>
<td class="org-left">iterator(from, to)</td>
<td class="org-left">Gives an iterator between the (optional) given enumeration values</td>
<td class="org-left">yes</td>
</tr>


<tr>
<td class="org-left">last()</td>
<td class="org-left">Returns the last value of the enumeration</td>
<td class="org-left">no</td>
</tr>


<tr>
<td class="org-left">methods(methods<sub>object</sub>)</td>
<td class="org-left">Adds additional methods to the enumerated type</td>
<td class="org-left">yes</td>
</tr>


<tr>
<td class="org-left">next()</td>
<td class="org-left">Returns the next enumeration value in the sequence</td>
<td class="org-left">yes</td>
</tr>


<tr>
<td class="org-left">previous()</td>
<td class="org-left">Returns the previous enumeration value in the sequence</td>
<td class="org-left">yes</td>
</tr>


<tr>
<td class="org-left">toInt()</td>
<td class="org-left">Converts an enumeration value to its integer representation</td>
<td class="org-left">no</td>
</tr>


<tr>
<td class="org-left">toString()</td>
<td class="org-left">Converts an enumeration value to a string representation</td>
<td class="org-left">no</td>
</tr>
</tbody>
</table>

When creating your own enumerated types, the methods marks "no"
under 'Default Implementation' *must* be implemented. All other
methods *may* be overridden if required.


<a id="org2e9ec5c"></a>

### Enumerated constants with `Enum`

Use the `Enum` function to create a set of constants:

    Color = Enum(
        'RED',
        'ORANGE',
        'YELLOW',
        'GREEN',
        'BLUE',
        'INDIGO',
        'VIOLET'
    )

Constants can be converted to and from their interger equivalents:

    Color.fromInt(3)    // Color.GREEN
    Color.GREEN.toInt() // 3

And you can also get the string representation:

    Color.RED.toString()    // 'RED'
    Color.VIOLET.toString() // 'VIOLET'

This allows you to use the constants as if they were object
keys.

    someObj = {
        Color.RED : 'Something having to do with red.',
        Color.BLUE : 'Something to do with blue.',
    }

In the above example the actual keys are the strings `RED` and
`BLUE` because javascript calls `toString()` automatically when
an object is used as a key.

You can navigate forwards and backwards through the sequence using
`next()` and `previous()`. Going past the end of the sequence
throws and error:

    Color.RED.next()        // Color.ORANGE
    Color.INDIGO.previous() // Color.BLUE
    Color.RED.previous()    // Error!
    Color.VIOLET.next()     // Error!

To get around that you can get an `iterator()` and loop through
the values with a `for` loop or with `forEach`.

    // Prints all the colors to the console.
    for (let color of Color.iterator()) {
        ; console.log(color.toString()) 
    }
    
    // Also prints all the colors to the console.
    Color.iterator().forEach(color => console.log(color.toString()))

The `iterator()` method takes two parameters `from` and `to`, both
optional, so you can iterate though a subset of the values.

    Color.iterator(Color.GREEN, Color.INDIGO)
        .forEach(color => console.log(color.toString()))

And can even be used to iterate though the values in reverse order
if desired.

    Color.iterator(Color.last(), Color.first())
        .forEach(color => console.log(color.toString()))

The constants can be compared in a number of ways.

    Color.RED.isLess(Color.BLUE)                // true
    Color.VIOLET.isLess(Color.BLUE)             // false
    Color.VIOLET.isGreater(Color.BLUE)          // true
    Color.VIOLET.isGreater(Color.VIOLET)        // false
    Color.VIOLET.isGreaterOrEqual(Color.VIOLET) // true
    Color.RED.isEqual(Color.GREEN)              // false
    Color.RED.isEqual(Color.RED)                // true
    Color.RED === Color.GREEN                   // false
    Color.RED === Color.RED                     // true

Finally, the type can be extended with addtional methods:

    Answers = Enum('YES', 'NO', 'MAYBE').methods({
        toLowerCase() {
    	return this.toString().toLowerCase();
        },
        capitalize() {
    	const as_string = this.toString();
    	const first = as_string[0];
    	const rest = as_string.substring(1).toLowerCase();
    	return `${first}${rest}`;
        }
    })
    
    console.log(Answers.YES.toLowerCase());  // yes
    console.log(Answers.Maybe.capitalize()); // Maybe

You can call `methods` *at most* once. After that the prototype
object is frozen and can't be modified further.


<a id="orgd1deb4d"></a>

### Enumerated constants with `EnumObjects`

The `EnumObjects` function works in much the same way as `Enum`
but instead of a list of strings it takes an object as input. Each
key becomes a constant and, unlike `Enum` each contant can have
its own additional properties and methods. 

    Animal = E.EnumObjects({
        DOG : {
    	speak() {
    	    console.log('woof!');
    	}
        },
        CAT : {
    	speak() {
    	    console.log('meow!');
    	}
        },
        GIRAFFE : {}
    }).methods({
        speak() {
    	console.log('...');
        }
    })
    
    Animal.DOG.speak()     // woof!
    Animal.CAT.speak()     // meow!
    Animal.GIRAFFE.speak() // ...
    Animal.iterator().forEach(a => a.speak())

In particular, notice that we can use `methods` to define default
methods which will apply to all constants that don't specifically
override it: `DOG` and `CAT` use their own behaviour while
`GIRAFFE` uses the default.


<a id="org78854e1"></a>

### Binary options with `Flags`

Flags are like enumerated constants except, instead of being
sequential, each flag's value is a power of 2. 

    Options = Flags('A', 'B', 'C', 'D')
    Options.A.toInt() // 1
    Options.B.toInt() // 2
    Options.C.toInt() // 4
    Options.D.toInt() // 8

This means you can combine multiple flags into a single integer
value using the bitwise OR (`|`) operator:

    Options.A | Options.B | Options.D;  // 11

Flag types have an additional method, `listFromInt()`, which
returns a list of all options represented by a given integer.

    Options.listFromInt(Options.A | Options.B | Options.D);  // [Options.A, Options.B, Options.D]
    Options.listFromInt(12)                                  // [Options.C, Options.D]
    Options.listFromInt(0)                                   // []
    Options.listFromInt(16)                                  // Error! Out of range.


<a id="orge23f6d4"></a>

### Constrained values with `EnumeratedRange`

Another type of enumeration are values constrained to a particular
range: values between 1 and 10, for instance. In this case it's
actually the number we're interested in not a symbolic name and
there are, generally, too many possible values to create them as
contants. Instead we can create an `EnumeratedRange`.

    SmallNum = EnumeratedRange(1, 10, 'SmallNum')

The resulting value, `SmallNum` in this example, can then be used
to construct values in this range.  The third parameter is
optional and is only relevant when calling `toString()`. Trying to
create a value outside of the allowed range throws an error.

    x = SmallNum(1)
    y = SmallNum(5)
    z = SmallNum(10)
    error1 = SmallNum(0)  // Error!
    error2 = SmallNum(11) // Error!

Even though the values don't exist as constants you can still get
an iterator over all the possible values:

    // Prints all SmallNum values from 1 to 10
    SmallNum.iterator().forEach(n => console.log(n))

---
_Source: https://npm.io/package/enumerated_types · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
