-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathswitchCase.js
110 lines (108 loc) · 3.8 KB
/
switchCase.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
const promiseAll = require('./_internal/promiseAll')
const areAnyValuesPromises = require('./_internal/areAnyValuesPromises')
const arrayConditional = require('./_internal/arrayConditional')
const areAllValuesNonfunctions = require('./_internal/areAllValuesNonfunctions')
const nonfunctionsConditional = require('./_internal/nonfunctionsConditional')
const __ = require('./_internal/placeholder')
const curry3 = require('./_internal/curry3')
const curryArgs3 = require('./_internal/curryArgs3')
/**
* @name switchCase
*
* @synopsis
* ```coffeescript [specscript]
* switchCase(conditionalValues Array<boolean|any>) -> Promise|any
*
* switchCase(
* ...args,
* conditionalFuncsOrValues Array<function|boolean|any>
* ) -> Promise|any
*
* switchCase(
* conditionalFuncsOrValues Array<function|boolean|any>
* )(...args) -> Promise|any
* ```
*
* @description
* Functional equivalent to the [Conditional (ternary) operator](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator). Accepts an array of conditional functions that specifies cases as pairings of `predicate` and `resolver` functions with the exception of the last, default resolver. All functions are provided with the same arguments and executed in series. The result of a `switchCase` operation is either the result of the execution the last default resolver, or the result of the execution of the first resolver where the associated predicate tested true.
*
* ```javascript [playground]
* const fruitIsYellow = fruit => fruit.color == 'yellow'
*
* console.log(
* switchCase({ name: 'plantain', color: 'yellow' }, [
* fruitIsYellow,
* fruit => fruit.name + ' is possibly a banana',
* fruit => fruit.name + ' is probably not a banana',
* ])
* ) // plantain is possibly a banana
* ```
*
* For composability `switchCase` supports a lazy API.
*
* ```javascript [playground]
* const fruitIsYellow = fruit => fruit.color == 'yellow'
*
* const fruitsGuesser = switchCase([
* fruitIsYellow,
* fruit => fruit.name + ' is possibly a banana',
* fruit => fruit.name + ' is probably not a banana',
* ])
*
* console.log(fruitsGuesser({ name: 'plantain', color: 'yellow' }))
* // plantain is possibly a banana
*
* console.log(fruitsGuesser({ name: 'apple', color: 'red' }))
* // apple is probably not a banana
* ```
*
* Any function can be replaced with a nonfunction (object or primitive) value to be used directly in the operation.
*
* ```javascript [playground]
* switchCase([
* async function asyncIdentity(value) {
* return value
* },
* 'something',
* 'default',
* ])(false).then(console.log) // default
* ```
*
* If every item in the conditional array is a nonfunction value, `switchCase` executes eagerly.
*
* ```javascript [playground]
* const age = 26
*
* const myDrink = switchCase([age >= 21, 'Beer', 'Juice'])
*
* console.log(myDrink) // Beer
* ```
*
* Any promises passed in argument position are resolved for their values before further execution. This only applies to the eager version of the API.
*
* ```javascript [playground]
* switchCase(Promise.resolve(1), 2, Promise.resolve(3), [
* function doValuesAddUpTo6(a, b, c) {
* return a + b + c == 6
* },
* (a, b, c) => console.log(`${a} + ${b} + ${c} == 6`),
* (a, b, c) => console.log(`${a} + ${b} + ${c} != 6`),
* ]) // 1 + 2 + 3 == 6
* ```
*
* @execution series
*/
const switchCase = (...args) => {
const values = args.pop()
if (areAllValuesNonfunctions(values)) {
return nonfunctionsConditional(values, -2)
}
if (args.length == 0) {
return curryArgs3(arrayConditional, values, __, -2)
}
if (areAnyValuesPromises(args)) {
return promiseAll(args).then(curry3(arrayConditional, values, __, -2))
}
return arrayConditional(values, args, -2)
}
module.exports = switchCase