Skip to content

Instantly share code, notes, and snippets.

@enten
Created August 10, 2017 06:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save enten/401690e9a64d0b26c3877b9260b34940 to your computer and use it in GitHub Desktop.
Save enten/401690e9a64d0b26c3877b9260b34940 to your computer and use it in GitHub Desktop.
EnumFlag
const {inspect} = require('util')
const DEFAULT = {
defaultValue: undefined,
dictionary: undefined,
value: undefined
}
function EnumFlag (enumFlag) {
const index = getDictionaryIndex(enumFlag.dictionary)
const getMap = getEnumFlagMap.bind(null, enumFlag)
const getValue = getEnumFlagValue.bind(null, enumFlag)
const setValue = setByKey.bind(null, 'value', enumFlag)
const api = (...args) => !args.length ? getValue() : setValue(args[0]) && api
Object.defineProperties(api, {
'name': {
configurable: true,
enumerable: false,
get: getValue
},
'opts': {
configurable: true,
enumerable: true,
value: enumFlag,
writable: true
},
'toJSON': {
configurable: true,
enumerable: false,
value: getMap,
writable: true
},
'toString': {
configurable: true,
enumerable: false,
value: getValue
},
[inspect.custom]: {
configurable: true,
enumerable: false,
value: getMap,
writable: true
}
})
index.forEach((flag) => {
Object.defineProperty(api, flag, {
enumerable: true,
get: () => isInDictionarySection(enumFlag.dictionary, flag, getValue())
})
})
return api
}
function createEnumFlag (opts) {
opts = parseEnumFlagOptions(opts)
// if (!opts.value && opts.defaultValue) {
// opts.value = opts.defaultValue
// }
return EnumFlag(opts)
}
function getEnumFlagKeys (enumFlag) {
const {dictionary} = enumFlag
const value = getEnumFlagValue(enumFlag)
return dictionarySectionsOf(dictionary, value)
}
function getEnumFlagMap (enumFlag) {
const {dictionary} = enumFlag
const value = getEnumFlagValue(enumFlag)
return dictionarySectionsMapOf(dictionary, value)
}
function getEnumFlagValue (enumFlag) {
const {
defaultValue,
dictionary,
value
} = enumFlag
let sections = dictionarySectionsOf(dictionary, value)
return sections.length ? value : defaultValue
}
function parseEnumFlagOptions (opts) {
opts = Object.assign({}, DEFAULT, opts)
return opts
}
module.exports = Object.assign(EnumFlag.bind(), {
EnumFlag,
createEnumFlag,
getEnumFlagKeys,
getEnumFlagMap,
getEnumFlagValue,
parseEnumFlagOptions
})
function castArray (value) {
return Array.isArray(value) ? value : [].concat(value || [])
}
function dictionarySectionsMapOf (dictionary, value) {
const flags = dictionarySectionsOf(dictionary, value)
const index = getDictionaryIndex(dictionary)
return index.reduce((acc, flag) => {
acc[flag] = flags.indexOf(flag) > -1
return acc
}, {})
}
function dictionarySectionsOf (dictionary, value) {
if (Array.isArray(dictionary)) {
return castArray(dictionary[dictionary.indexOf(value)])
}
return Object.keys(dictionary).reduce((acc, key) => {
return ~castArray(dictionary[key]).indexOf(value) ? acc.concat(key) : acc
}, [])
}
function getDictionaryIndex (dictionary) {
return Array.isArray(dictionary) ? dictionary : Object.keys(dictionary)
}
function isInDictionarySection (dictionary, section, value) {
if (Array.isArray(dictionary)) {
return dictionary[dictionary.indexOf(value)] === section
}
return castArray(dictionary[section]).indexOf(value) > -1
}
function setByKey (key, obj, value) {
obj[key] = value
return obj
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment