Created
August 10, 2017 06:14
-
-
Save enten/401690e9a64d0b26c3877b9260b34940 to your computer and use it in GitHub Desktop.
EnumFlag
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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