-
Notifications
You must be signed in to change notification settings - Fork 17
Expand file tree
/
Copy pathswitchCase.js
More file actions
125 lines (123 loc) · 3.99 KB
/
Copy pathswitchCase.js
File metadata and controls
125 lines (123 loc) · 3.99 KB
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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
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]
* type Predicate = (...arguments)=>Promise|boolean|any
* type Function = (...arguments)=>Promise|any
*
* conditionalValues Array<Promise|boolean|any>
* conditionalFunctionsOrValues Array<Predicate|Function|Promise|boolean|any>
*
* switchCase(conditionalValues) -> result Promise|any
* switchCase(...arguments, conditionalFunctionsOrValues) -> result Promise|any
* switchCase(conditionalFunctionsOrValues)(...arguments) -> result Promise|any
* ```
*
* @description
* Conditional function operator. Accepts an array of conditional functions or values that specifies cases as function or value pairs with the exception of the last, default function or value. All functions are provided with the same arguments and executed in series. The result of a conditional execution with `switchCase` is the result of the execution of the first truthy function or value pair, the result of the execution of the last, default function, or the provided last, default value.
*
* ```javascript [playground]
* function isOdd(n) {
* return n % 2 == 1
* }
*
* switchCase(1, [
* isOdd,
* n => console.log(`${n} is odd`),
* n => console.log(`${n} is even`),
* ])
* ```
*
* `switchCase` supports a lazy interface for composability.
*
* ```javascript [playground]
* const fruitsGuesser = switchCase([
* fruit => fruit.color == 'yellow',
* fruit => fruit.name + ' is possibly a banana',
* fruit => fruit.name + ' is possibly not a banana',
* ])
*
* const guess1 = fruitsGuesser({ name: 'plantain', color: 'yellow' })
* const guess2 = fruitsGuesser({ name: 'apple', color: 'red' })
*
* console.log(guess1)
* console.log(guess2)
* ```
*
* Any item of the conditional array passed to switchCase can be a nonfunction (object or primitive) value.
*
* ```javascript [playground]
* function identity (value) {
* return value
* }
*
* const value = switchCase(false, [
* identity,
* 'non-function',
* 'default-value',
* ])
*
* console.log(value)
* ```
*
* If every item in the conditional array is a nonfunction value, `switchCase` executes eagerly.
*
* ```javascript [playground]
* const age = 26
*
* const myDrink = switchCase([age >= 21, 'Water', 'Juice'])
*
* console.log(myDrink)
* ```
*
* Any promises in `arguments` are resolved for their values before further execution for the eager interface only. Any promises in the conditional array are resolved before further execution for both the lazy and eager interface.
*
* ```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`),
* ])
*
* const result = await switchCase(true, [
* bool => bool,
* Promise.resolve(1),
* Promise.resolve(2),
* ])
*
* console.log(result)
* ```
*
* See also:
* * [pipe](/docs/pipe)
* * [tap.if](/docs/tap.if)
* * [tryCatch](/docs/tryCatch)
* * [all](/docs/all)
*
* @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