rich-enum

A implementation of enum like feature, but more powerful and extensible.

Downloads in past

Stats

StarsIssuesVersionUpdatedCreatedSize
rich-enum
101.0.16 years ago6 years agoMinified + gzip package size for rich-enum in KB

Readme

rich-enum

A implementation of enum like feature, but more powerful and extensible.




!Build Statusbuild-badgebuild !Code Coveragecoverage-badgecoverage !versionversion-badgepackage !downloadsdownloads-badgenpmtrends !MIT Licenselicense-badgelicense
All Contributors !PRs Welcomeprs-badgeprs !Code of Conductcoc-badgecoc
!Watch on GitHubgithub-watch-badgegithub-watch !Star on GitHubgithub-star-badgegithub-star !Tweettwitter-badgetwitter

The problem

We could use a plain object to simulate an enumeration type. It's fine that if we just need to use this to store the value of a key and access the predefined value by a key. What if we need to store and read more informations by a key or read some information by value ?
Take the api documentation described by protocol buffers as an example:
message SearchRequest {
  enum Corpus {
    UNIVERSAL = 0;
    WEB = 1;
    IMAGES = 2;
    LOCAL = 3;
    NEWS = 4;
    PRODUCTS = 5;
    VIDEO = 6;
  }

  Corpus corpus = 4;
}

In the above example, it define an value corpus of enum type Corpus. When we communicate with the back end api, wo need to passed something like this:
const Corpus = {
  UNIVERSAL: 0,
  WEB: 1,
  IMAGES: 2,
  LOCAL: 3,
  NEWS: 4,
  PRODUCTS: 5,
  VIDEO: 6,
}

const request = {
  corpus: Corpus.UNIVERSAL,
}

In the context of communicating with the back end API, we can create an object to map the key like UNIVERSAL to the value 0 and other enumeration values the same way. But if we want to add more information to the enumeration value? Such as detailed description and any other extra pieces of information. For example, we have a value 0 and we want to know which enumeration item has the value 0, we also want to display the corresponding description for this value.
const CorpusText = {
  [Corpus.UNIVERSAL]: 'Universal',
  //...
  [Corpus.VIDEO]: 'Video',
}

CorpusText[corpusValue]

The solution the above provided can meet our needs, but it's too troublesome. So we take rich-enum as the more great solution.

This solution

This solution is apparent when we define the enum value, we attach more information with it, then through the key and extensible API to use the enumeration value in the form we need.

Table of Contents



Basic extend()

Installation

This module is distributed via npmnpm which is bundled with nodenode and should be installed as one of your project's dependencies:
npm install --save rich-enum

Usage

Basic

Define a powerful enumeration:
import RichEnum from 'rich-enum'

const CorpusEnum = new RichEnum({
  UNIVERSAL: {
    value: 0,
    text: 'Universal',
  },
  WEB: {
    value: 1,
    text: 'Web',
  },
  IMAGES: {
    value: 2,
    text: 'Images',
  },
  LOCAL: {
    value: 3,
    text: 'Local',
  },
  NEWS: {
    value: 4,
    text: 'News',
  },
  PRODUCTS: {
    value: 5,
    text: 'Products',
  },
  VIDEO: {
    value: 6,
    text: 'Video',
  },
})

Then use this:
const {value: Corpus} = CorpusEnum
/* read the value by key */
Corpus.UNIVERSAL // 0
Corpus.VIDEO // 6

/* read the text by value */
CorpusEnum.text[Corpus.UNIVERSAL] // 'Universal'
CorpusEnum.text[Corpus.VIDEO] // 'Video'

/* read the all details of one element */
CorpusEnum.UNIVERSAL // { key: 'UNIVERSAL', value: 0, text: 'UNIVERSAL' }
CorpusEnum.VIDEO // { key: 'VIDEO', value: 6, text: 'Video' }

/* loop the all enumerations with detailed information */
CorpusEnum.collection.forEach(({key, value, text}) => {
  console.log({key, value, text})
  // { key: 'UNIVERSAL', value: 0, text: 'Universal' }
  // ...
  // { key: 'VIDEO', value: 6, text: 'Video' }
})

The RichEnum instance has properties whose key is the value of an enumeration item, and the value is the property value of the enumeration item for every property defined for enumeration items except property value.
The property value is the object whose key is the key of an item, and value is the value of property value in the properties.
For Example:
const enumeration = new RichEnumeration({
  TYPE_A: {
    value: 0,
    text: 'Type A',
    extra: 'Extra info',
    xxx: 'xxx',
  },
})

enumeration.value.TYPE_A // 0
enumeration.text[0] // 'Type A'
enumeration.extra[0] // 'Extra info'
enumeration.xxx[0] // 'xxx'

extend()

if you defined a rich enumeration object, it's fine for your most scenes to be used. What if you have some extra information need to be bound with the same key only for a specified scene ?
You're allowed to extend it to generate a new RichEnum instance object, for example:
const SpecifiedCorpusEnum = CorpusEnum.extend({
  UNIVERSAL: {
    extra: 'Extra information of the universal',
  },
})

CorpusEnum.UNIVERSAL // { key: 'UNIVERSAL', value: 0, text: 'Universal', extra: 'Extra information of the universal' }
CorpusEnum.UNIVERSAL.extra // 'Extra information of the universal'

The instance method new RichEnum().extend() will merge the new detail object with the older one shallowly per key. And return a new instance, so it will not pollute the original instance.

Other Solutions

I'm not aware of any, if you are please make a pull requestprs and add it here!

Contributors

Thanks goes to these people (emoji keyemojis):

|
Jianhua Cheng

💻 📖 🚇") ⚠️ | | :---: |

This project follows the all-contributorsall-contributors specification. Contributions of any kind welcome!

LICENSE

MIT