decoders 2.0.0 → 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +11 -0
- package/Decoder.js +41 -148
- package/Decoder.js.flow +1 -1
- package/Decoder.mjs +38 -145
- package/README.md +1 -1
- package/_utils.js +50 -61
- package/_utils.js.flow +18 -4
- package/_utils.mjs +41 -52
- package/annotate.js +79 -72
- package/annotate.mjs +62 -58
- package/format.js +64 -74
- package/format.js.flow +11 -11
- package/format.mjs +58 -68
- package/index.js +66 -66
- package/index.mjs +11 -11
- package/lib/arrays.js +47 -89
- package/lib/arrays.mjs +38 -78
- package/lib/basics.js +59 -109
- package/lib/basics.mjs +49 -94
- package/lib/booleans.js +14 -24
- package/lib/booleans.mjs +9 -19
- package/lib/dates.js +18 -34
- package/lib/dates.mjs +12 -27
- package/lib/json.d.ts +3 -3
- package/lib/json.js +20 -42
- package/lib/json.js.flow +2 -2
- package/lib/json.mjs +13 -35
- package/lib/numbers.js +19 -39
- package/lib/numbers.mjs +11 -31
- package/lib/objects.d.ts +11 -10
- package/lib/objects.js +84 -163
- package/lib/objects.js.flow +4 -12
- package/lib/objects.mjs +74 -150
- package/lib/strings.js +41 -84
- package/lib/strings.mjs +25 -67
- package/lib/unions.d.ts +1 -1
- package/lib/unions.js +52 -116
- package/lib/unions.js.flow +1 -1
- package/lib/unions.mjs +46 -109
- package/lib/utilities.d.ts +7 -1
- package/lib/utilities.js +23 -50
- package/lib/utilities.mjs +15 -38
- package/package.json +1 -1
- package/result.js +9 -22
- package/result.mjs +5 -17
package/lib/unions.js
CHANGED
|
@@ -1,160 +1,96 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict'
|
|
2
2
|
|
|
3
|
-
exports.__esModule = true
|
|
4
|
-
exports.either = void 0
|
|
5
|
-
exports.oneOf = oneOf
|
|
6
|
-
exports.taggedUnion = taggedUnion
|
|
3
|
+
exports.__esModule = true
|
|
4
|
+
exports.either = void 0
|
|
5
|
+
exports.oneOf = oneOf
|
|
6
|
+
exports.taggedUnion = taggedUnion
|
|
7
7
|
|
|
8
|
-
var _Decoder = require(
|
|
8
|
+
var _Decoder = require('../Decoder')
|
|
9
9
|
|
|
10
|
-
var _utils = require(
|
|
10
|
+
var _utils = require('../_utils')
|
|
11
11
|
|
|
12
|
-
var _objects = require(
|
|
12
|
+
var _objects = require('./objects')
|
|
13
13
|
|
|
14
|
-
var _utilities = require(
|
|
14
|
+
var _utilities = require('./utilities')
|
|
15
15
|
|
|
16
|
-
var EITHER_PREFIX = 'Either:\n'
|
|
17
|
-
/**
|
|
18
|
-
* Indents and adds a dash in front of this (potentially multiline) string.
|
|
19
|
-
*/
|
|
16
|
+
var EITHER_PREFIX = 'Either:\n'
|
|
20
17
|
|
|
21
18
|
function itemize(s) {
|
|
22
|
-
return '-' + (0, _utils.indent)(s).substring(1)
|
|
19
|
+
return '-' + (0, _utils.indent)(s).substring(1)
|
|
23
20
|
}
|
|
24
|
-
/**
|
|
25
|
-
* Nests another error as an item under a new-to-be-created "Either error". If
|
|
26
|
-
* the given subitem already is an "Either error" of itself, don't indent, but
|
|
27
|
-
* just "inject" its items at the same error level, for nicely flattened either
|
|
28
|
-
* expressions.
|
|
29
|
-
*
|
|
30
|
-
* Avoids:
|
|
31
|
-
*
|
|
32
|
-
* Either:
|
|
33
|
-
* - Either:
|
|
34
|
-
* - Must be P
|
|
35
|
-
* - Either:
|
|
36
|
-
* - Must be Q
|
|
37
|
-
* - Must be R
|
|
38
|
-
* - Must be S
|
|
39
|
-
*
|
|
40
|
-
* And "flattens" these to:
|
|
41
|
-
*
|
|
42
|
-
* Either:
|
|
43
|
-
* - Must be P
|
|
44
|
-
* - Must be Q
|
|
45
|
-
* - Must be R
|
|
46
|
-
* - Must be S
|
|
47
|
-
*
|
|
48
|
-
*/
|
|
49
|
-
|
|
50
21
|
|
|
51
22
|
function nest(errText) {
|
|
52
|
-
return errText.startsWith(EITHER_PREFIX) ? errText.substr(EITHER_PREFIX.length) : itemize(errText)
|
|
53
|
-
}
|
|
54
|
-
|
|
23
|
+
return errText.startsWith(EITHER_PREFIX) ? errText.substr(EITHER_PREFIX.length) : itemize(errText)
|
|
24
|
+
}
|
|
55
25
|
|
|
56
26
|
function _either() {
|
|
57
27
|
for (var _len = arguments.length, decoders = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
58
|
-
decoders[_key] = arguments[_key]
|
|
28
|
+
decoders[_key] = arguments[_key]
|
|
59
29
|
}
|
|
60
30
|
|
|
61
31
|
if (decoders.length === 0) {
|
|
62
|
-
throw new Error('Pass at least one decoder to either()')
|
|
32
|
+
throw new Error('Pass at least one decoder to either()')
|
|
63
33
|
}
|
|
64
34
|
|
|
65
35
|
return (0, _Decoder.define)(function (blob, _, err) {
|
|
66
|
-
|
|
67
|
-
var errors = [];
|
|
36
|
+
var errors = []
|
|
68
37
|
|
|
69
38
|
for (var _i = 0; _i < decoders.length; _i++) {
|
|
70
|
-
var result = decoders[_i].decode(blob)
|
|
39
|
+
var result = decoders[_i].decode(blob)
|
|
71
40
|
|
|
72
41
|
if (result.ok) {
|
|
73
|
-
return result
|
|
42
|
+
return result
|
|
74
43
|
} else {
|
|
75
|
-
errors.push(result.error)
|
|
44
|
+
errors.push(result.error)
|
|
76
45
|
}
|
|
77
|
-
}
|
|
78
|
-
|
|
46
|
+
}
|
|
79
47
|
|
|
80
|
-
var text =
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
48
|
+
var text =
|
|
49
|
+
EITHER_PREFIX +
|
|
50
|
+
errors
|
|
51
|
+
.map(function (err) {
|
|
52
|
+
return nest((0, _utils.summarize)(err).join('\n'))
|
|
53
|
+
})
|
|
54
|
+
.join('\n')
|
|
55
|
+
return err(text)
|
|
56
|
+
})
|
|
85
57
|
}
|
|
86
|
-
/**
|
|
87
|
-
* Accepts values accepted by any of the given decoders.
|
|
88
|
-
*
|
|
89
|
-
* The decoders are tried on the input one by one, in the given order. The
|
|
90
|
-
* first one that accepts the input "wins". If all decoders reject the input,
|
|
91
|
-
* the input gets rejected.
|
|
92
|
-
*/
|
|
93
|
-
|
|
94
58
|
|
|
95
|
-
var either = _either
|
|
96
|
-
/**
|
|
97
|
-
* Accepts any value that is strictly-equal (using `===`) to one of the
|
|
98
|
-
* specified values.
|
|
99
|
-
*/
|
|
59
|
+
var either = _either
|
|
100
60
|
|
|
101
|
-
exports.either = either
|
|
61
|
+
exports.either = either
|
|
102
62
|
|
|
103
63
|
function oneOf(constants) {
|
|
104
64
|
return (0, _Decoder.define)(function (blob, ok, err) {
|
|
105
65
|
var winner = constants.find(function (c) {
|
|
106
|
-
return c === blob
|
|
107
|
-
})
|
|
66
|
+
return c === blob
|
|
67
|
+
})
|
|
108
68
|
|
|
109
69
|
if (winner !== undefined) {
|
|
110
|
-
return ok(winner)
|
|
70
|
+
return ok(winner)
|
|
111
71
|
}
|
|
112
72
|
|
|
113
|
-
return err(
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
73
|
+
return err(
|
|
74
|
+
'Must be one of ' +
|
|
75
|
+
constants
|
|
76
|
+
.map(function (value) {
|
|
77
|
+
return JSON.stringify(value)
|
|
78
|
+
})
|
|
79
|
+
.join(', ')
|
|
80
|
+
)
|
|
81
|
+
})
|
|
117
82
|
}
|
|
118
|
-
/**
|
|
119
|
-
* If you are decoding tagged unions you may want to use the `taggedUnion()`
|
|
120
|
-
* decoder instead of the general purpose `either()` decoder to get better
|
|
121
|
-
* error messages and better performance.
|
|
122
|
-
*
|
|
123
|
-
* This decoder is optimized for [tagged
|
|
124
|
-
* unions](https://en.wikipedia.org/wiki/Tagged_union), i.e. a union of
|
|
125
|
-
* objects where one field is used as the discriminator.
|
|
126
|
-
*
|
|
127
|
-
* ```ts
|
|
128
|
-
* const A = object({ tag: constant('A'), foo: string });
|
|
129
|
-
* const B = object({ tag: constant('B'), bar: number });
|
|
130
|
-
*
|
|
131
|
-
* const AorB = taggedUnion('tag', { A, B });
|
|
132
|
-
* // ^^^
|
|
133
|
-
* ```
|
|
134
|
-
*
|
|
135
|
-
* Decoding now works in two steps:
|
|
136
|
-
*
|
|
137
|
-
* 1. Look at the `'tag'` field in the incoming object (this is the field
|
|
138
|
-
* that decides which decoder will be used)
|
|
139
|
-
* 2. If the value is `'A'`, then decoder `A` will be used. If it's `'B'`, then
|
|
140
|
-
* decoder `B` will be used. Otherwise, this will fail.
|
|
141
|
-
*
|
|
142
|
-
* This is effectively equivalent to `either(A, B)`, but will provide better
|
|
143
|
-
* error messages and is more performant at runtime because it doesn't have to
|
|
144
|
-
* try all decoders one by one.
|
|
145
|
-
*/
|
|
146
|
-
|
|
147
83
|
|
|
148
84
|
function taggedUnion(field, mapping) {
|
|
149
|
-
var _object
|
|
85
|
+
var _object
|
|
150
86
|
|
|
151
|
-
var base = (0, _objects.object)((_object = {}, _object[field] = (0, _utilities.prep)(String, oneOf(Object.keys(mapping))), _object)).transform(function (o) {
|
|
152
|
-
return o[field]
|
|
153
|
-
})
|
|
87
|
+
var base = (0, _objects.object)(((_object = {}), (_object[field] = (0, _utilities.prep)(String, oneOf(Object.keys(mapping)))), _object)).transform(function (o) {
|
|
88
|
+
return o[field]
|
|
89
|
+
})
|
|
154
90
|
return base.peek_UNSTABLE(function (_ref) {
|
|
155
91
|
var blob = _ref[0],
|
|
156
|
-
|
|
157
|
-
var decoder = mapping[key]
|
|
158
|
-
return decoder.decode(blob)
|
|
159
|
-
})
|
|
160
|
-
}
|
|
92
|
+
key = _ref[1]
|
|
93
|
+
var decoder = mapping[key]
|
|
94
|
+
return decoder.decode(blob)
|
|
95
|
+
})
|
|
96
|
+
}
|
package/lib/unions.js.flow
CHANGED
package/lib/unions.mjs
CHANGED
|
@@ -1,146 +1,83 @@
|
|
|
1
|
-
import { define } from '../Decoder.mjs'
|
|
2
|
-
import { indent, summarize } from '../_utils.mjs'
|
|
3
|
-
import { object } from './objects.mjs'
|
|
4
|
-
import { prep } from './utilities.mjs'
|
|
5
|
-
var EITHER_PREFIX = 'Either:\n'
|
|
6
|
-
/**
|
|
7
|
-
* Indents and adds a dash in front of this (potentially multiline) string.
|
|
8
|
-
*/
|
|
1
|
+
import { define } from '../Decoder.mjs'
|
|
2
|
+
import { indent, summarize } from '../_utils.mjs'
|
|
3
|
+
import { object } from './objects.mjs'
|
|
4
|
+
import { prep } from './utilities.mjs'
|
|
5
|
+
var EITHER_PREFIX = 'Either:\n'
|
|
9
6
|
|
|
10
7
|
function itemize(s) {
|
|
11
|
-
return '-' + indent(s).substring(1)
|
|
8
|
+
return '-' + indent(s).substring(1)
|
|
12
9
|
}
|
|
13
|
-
/**
|
|
14
|
-
* Nests another error as an item under a new-to-be-created "Either error". If
|
|
15
|
-
* the given subitem already is an "Either error" of itself, don't indent, but
|
|
16
|
-
* just "inject" its items at the same error level, for nicely flattened either
|
|
17
|
-
* expressions.
|
|
18
|
-
*
|
|
19
|
-
* Avoids:
|
|
20
|
-
*
|
|
21
|
-
* Either:
|
|
22
|
-
* - Either:
|
|
23
|
-
* - Must be P
|
|
24
|
-
* - Either:
|
|
25
|
-
* - Must be Q
|
|
26
|
-
* - Must be R
|
|
27
|
-
* - Must be S
|
|
28
|
-
*
|
|
29
|
-
* And "flattens" these to:
|
|
30
|
-
*
|
|
31
|
-
* Either:
|
|
32
|
-
* - Must be P
|
|
33
|
-
* - Must be Q
|
|
34
|
-
* - Must be R
|
|
35
|
-
* - Must be S
|
|
36
|
-
*
|
|
37
|
-
*/
|
|
38
|
-
|
|
39
10
|
|
|
40
11
|
function nest(errText) {
|
|
41
|
-
return errText.startsWith(EITHER_PREFIX) ? errText.substr(EITHER_PREFIX.length) : itemize(errText)
|
|
42
|
-
}
|
|
43
|
-
|
|
12
|
+
return errText.startsWith(EITHER_PREFIX) ? errText.substr(EITHER_PREFIX.length) : itemize(errText)
|
|
13
|
+
}
|
|
44
14
|
|
|
45
15
|
function _either() {
|
|
46
16
|
for (var _len = arguments.length, decoders = new Array(_len), _key = 0; _key < _len; _key++) {
|
|
47
|
-
decoders[_key] = arguments[_key]
|
|
17
|
+
decoders[_key] = arguments[_key]
|
|
48
18
|
}
|
|
49
19
|
|
|
50
20
|
if (decoders.length === 0) {
|
|
51
|
-
throw new Error('Pass at least one decoder to either()')
|
|
21
|
+
throw new Error('Pass at least one decoder to either()')
|
|
52
22
|
}
|
|
53
23
|
|
|
54
24
|
return define(function (blob, _, err) {
|
|
55
|
-
|
|
56
|
-
var errors = [];
|
|
25
|
+
var errors = []
|
|
57
26
|
|
|
58
27
|
for (var _i = 0; _i < decoders.length; _i++) {
|
|
59
|
-
var result = decoders[_i].decode(blob)
|
|
28
|
+
var result = decoders[_i].decode(blob)
|
|
60
29
|
|
|
61
30
|
if (result.ok) {
|
|
62
|
-
return result
|
|
31
|
+
return result
|
|
63
32
|
} else {
|
|
64
|
-
errors.push(result.error)
|
|
33
|
+
errors.push(result.error)
|
|
65
34
|
}
|
|
66
|
-
}
|
|
67
|
-
|
|
35
|
+
}
|
|
68
36
|
|
|
69
|
-
var text =
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
37
|
+
var text =
|
|
38
|
+
EITHER_PREFIX +
|
|
39
|
+
errors
|
|
40
|
+
.map(function (err) {
|
|
41
|
+
return nest(summarize(err).join('\n'))
|
|
42
|
+
})
|
|
43
|
+
.join('\n')
|
|
44
|
+
return err(text)
|
|
45
|
+
})
|
|
74
46
|
}
|
|
75
|
-
/**
|
|
76
|
-
* Accepts values accepted by any of the given decoders.
|
|
77
|
-
*
|
|
78
|
-
* The decoders are tried on the input one by one, in the given order. The
|
|
79
|
-
* first one that accepts the input "wins". If all decoders reject the input,
|
|
80
|
-
* the input gets rejected.
|
|
81
|
-
*/
|
|
82
|
-
|
|
83
47
|
|
|
84
|
-
export var either = _either
|
|
85
|
-
/**
|
|
86
|
-
* Accepts any value that is strictly-equal (using `===`) to one of the
|
|
87
|
-
* specified values.
|
|
88
|
-
*/
|
|
48
|
+
export var either = _either
|
|
89
49
|
|
|
90
50
|
export function oneOf(constants) {
|
|
91
51
|
return define(function (blob, ok, err) {
|
|
92
52
|
var winner = constants.find(function (c) {
|
|
93
|
-
return c === blob
|
|
94
|
-
})
|
|
53
|
+
return c === blob
|
|
54
|
+
})
|
|
95
55
|
|
|
96
56
|
if (winner !== undefined) {
|
|
97
|
-
return ok(winner)
|
|
57
|
+
return ok(winner)
|
|
98
58
|
}
|
|
99
59
|
|
|
100
|
-
return err(
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
60
|
+
return err(
|
|
61
|
+
'Must be one of ' +
|
|
62
|
+
constants
|
|
63
|
+
.map(function (value) {
|
|
64
|
+
return JSON.stringify(value)
|
|
65
|
+
})
|
|
66
|
+
.join(', ')
|
|
67
|
+
)
|
|
68
|
+
})
|
|
104
69
|
}
|
|
105
|
-
/**
|
|
106
|
-
* If you are decoding tagged unions you may want to use the `taggedUnion()`
|
|
107
|
-
* decoder instead of the general purpose `either()` decoder to get better
|
|
108
|
-
* error messages and better performance.
|
|
109
|
-
*
|
|
110
|
-
* This decoder is optimized for [tagged
|
|
111
|
-
* unions](https://en.wikipedia.org/wiki/Tagged_union), i.e. a union of
|
|
112
|
-
* objects where one field is used as the discriminator.
|
|
113
|
-
*
|
|
114
|
-
* ```ts
|
|
115
|
-
* const A = object({ tag: constant('A'), foo: string });
|
|
116
|
-
* const B = object({ tag: constant('B'), bar: number });
|
|
117
|
-
*
|
|
118
|
-
* const AorB = taggedUnion('tag', { A, B });
|
|
119
|
-
* // ^^^
|
|
120
|
-
* ```
|
|
121
|
-
*
|
|
122
|
-
* Decoding now works in two steps:
|
|
123
|
-
*
|
|
124
|
-
* 1. Look at the `'tag'` field in the incoming object (this is the field
|
|
125
|
-
* that decides which decoder will be used)
|
|
126
|
-
* 2. If the value is `'A'`, then decoder `A` will be used. If it's `'B'`, then
|
|
127
|
-
* decoder `B` will be used. Otherwise, this will fail.
|
|
128
|
-
*
|
|
129
|
-
* This is effectively equivalent to `either(A, B)`, but will provide better
|
|
130
|
-
* error messages and is more performant at runtime because it doesn't have to
|
|
131
|
-
* try all decoders one by one.
|
|
132
|
-
*/
|
|
133
70
|
|
|
134
71
|
export function taggedUnion(field, mapping) {
|
|
135
|
-
var _object
|
|
72
|
+
var _object
|
|
136
73
|
|
|
137
|
-
var base = object((_object = {}, _object[field] = prep(String, oneOf(Object.keys(mapping))), _object)).transform(function (o) {
|
|
138
|
-
return o[field]
|
|
139
|
-
})
|
|
74
|
+
var base = object(((_object = {}), (_object[field] = prep(String, oneOf(Object.keys(mapping)))), _object)).transform(function (o) {
|
|
75
|
+
return o[field]
|
|
76
|
+
})
|
|
140
77
|
return base.peek_UNSTABLE(function (_ref) {
|
|
141
78
|
var blob = _ref[0],
|
|
142
|
-
|
|
143
|
-
var decoder = mapping[key]
|
|
144
|
-
return decoder.decode(blob)
|
|
145
|
-
})
|
|
146
|
-
}
|
|
79
|
+
key = _ref[1]
|
|
80
|
+
var decoder = mapping[key]
|
|
81
|
+
return decoder.decode(blob)
|
|
82
|
+
})
|
|
83
|
+
}
|
package/lib/utilities.d.ts
CHANGED
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
import { Decoder } from '../Decoder';
|
|
2
2
|
|
|
3
|
+
export interface Klass<T> extends Function {
|
|
4
|
+
new (...args: readonly any[]): T;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export type Instance<K> = K extends Klass<infer T> ? T : never;
|
|
8
|
+
|
|
3
9
|
/**
|
|
4
10
|
* Accepts any value that is an ``instanceof`` the given class.
|
|
5
11
|
*/
|
|
6
|
-
export function instanceOf<
|
|
12
|
+
export function instanceOf<K extends Klass<any>>(klass: K): Decoder<Instance<K>>;
|
|
7
13
|
|
|
8
14
|
/**
|
|
9
15
|
* Lazily evaluate the given decoder. This is useful to build self-referential
|
package/lib/utilities.js
CHANGED
|
@@ -1,75 +1,48 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict'
|
|
2
2
|
|
|
3
|
-
exports.__esModule = true
|
|
4
|
-
exports.fail = void 0
|
|
5
|
-
exports.instanceOf = instanceOf
|
|
6
|
-
exports.lazy = lazy
|
|
7
|
-
exports.never = never
|
|
8
|
-
exports.prep = prep
|
|
3
|
+
exports.__esModule = true
|
|
4
|
+
exports.fail = void 0
|
|
5
|
+
exports.instanceOf = instanceOf
|
|
6
|
+
exports.lazy = lazy
|
|
7
|
+
exports.never = never
|
|
8
|
+
exports.prep = prep
|
|
9
9
|
|
|
10
|
-
var _annotate = require(
|
|
10
|
+
var _annotate = require('../annotate')
|
|
11
11
|
|
|
12
|
-
var _Decoder = require(
|
|
12
|
+
var _Decoder = require('../Decoder')
|
|
13
13
|
|
|
14
|
-
/**
|
|
15
|
-
* Accepts any value that is an ``instanceof`` the given class.
|
|
16
|
-
*/
|
|
17
14
|
function instanceOf(klass) {
|
|
18
15
|
return (0, _Decoder.define)(function (blob, ok, err) {
|
|
19
|
-
return blob instanceof klass ? ok(blob) : err(
|
|
20
|
-
|
|
21
|
-
});
|
|
16
|
+
return blob instanceof klass ? ok(blob) : err('Must be ' + klass.name + ' instance')
|
|
17
|
+
})
|
|
22
18
|
}
|
|
23
|
-
/**
|
|
24
|
-
* Lazily evaluate the given decoder. This is useful to build self-referential
|
|
25
|
-
* types for recursive data structures.
|
|
26
|
-
*/
|
|
27
|
-
|
|
28
19
|
|
|
29
20
|
function lazy(decoderFn) {
|
|
30
21
|
return (0, _Decoder.define)(function (blob) {
|
|
31
|
-
return decoderFn().decode(blob)
|
|
32
|
-
})
|
|
22
|
+
return decoderFn().decode(blob)
|
|
23
|
+
})
|
|
33
24
|
}
|
|
34
|
-
/**
|
|
35
|
-
* Pre-process the data input before passing it into the decoder. This gives
|
|
36
|
-
* you the ability to arbitrarily customize the input on the fly before passing
|
|
37
|
-
* it to the decoder. Of course, the input value at that point is still of
|
|
38
|
-
* ``unknown`` type, so you will have to deal with that accordingly.
|
|
39
|
-
*/
|
|
40
|
-
|
|
41
25
|
|
|
42
26
|
function prep(mapperFn, decoder) {
|
|
43
27
|
return (0, _Decoder.define)(function (originalInput, _, err) {
|
|
44
|
-
var blob
|
|
28
|
+
var blob
|
|
45
29
|
|
|
46
30
|
try {
|
|
47
|
-
blob = mapperFn(originalInput)
|
|
31
|
+
blob = mapperFn(originalInput)
|
|
48
32
|
} catch (e) {
|
|
49
|
-
return err((0, _annotate.annotate)(originalInput, e.message))
|
|
33
|
+
return err((0, _annotate.annotate)(originalInput, e.message))
|
|
50
34
|
}
|
|
51
35
|
|
|
52
|
-
var r = decoder.decode(blob)
|
|
53
|
-
return r.ok ? r : err((0, _annotate.annotate)(originalInput, r.error.text))
|
|
54
|
-
|
|
55
|
-
// (instead of echoing back blob)
|
|
56
|
-
});
|
|
36
|
+
var r = decoder.decode(blob)
|
|
37
|
+
return r.ok ? r : err((0, _annotate.annotate)(originalInput, r.error.text))
|
|
38
|
+
})
|
|
57
39
|
}
|
|
58
|
-
/**
|
|
59
|
-
* Rejects all inputs, and always fails with the given error message. May be
|
|
60
|
-
* useful for explicitly disallowing keys, or for testing purposes.
|
|
61
|
-
*/
|
|
62
|
-
|
|
63
40
|
|
|
64
41
|
function never(msg) {
|
|
65
42
|
return (0, _Decoder.define)(function (_, __, err) {
|
|
66
|
-
return err(msg)
|
|
67
|
-
})
|
|
43
|
+
return err(msg)
|
|
44
|
+
})
|
|
68
45
|
}
|
|
69
|
-
/**
|
|
70
|
-
* Alias of never().
|
|
71
|
-
*/
|
|
72
|
-
|
|
73
46
|
|
|
74
|
-
var fail = never
|
|
75
|
-
exports.fail = fail
|
|
47
|
+
var fail = never
|
|
48
|
+
exports.fail = fail
|
package/lib/utilities.mjs
CHANGED
|
@@ -1,60 +1,37 @@
|
|
|
1
|
-
import { annotate } from '../annotate.mjs'
|
|
2
|
-
import { define } from '../Decoder.mjs'
|
|
1
|
+
import { annotate } from '../annotate.mjs'
|
|
2
|
+
import { define } from '../Decoder.mjs'
|
|
3
3
|
|
|
4
|
-
/**
|
|
5
|
-
* Accepts any value that is an ``instanceof`` the given class.
|
|
6
|
-
*/
|
|
7
4
|
export function instanceOf(klass) {
|
|
8
5
|
return define(function (blob, ok, err) {
|
|
9
|
-
return blob instanceof klass ? ok(blob) : err(
|
|
10
|
-
|
|
11
|
-
});
|
|
6
|
+
return blob instanceof klass ? ok(blob) : err('Must be ' + klass.name + ' instance')
|
|
7
|
+
})
|
|
12
8
|
}
|
|
13
|
-
/**
|
|
14
|
-
* Lazily evaluate the given decoder. This is useful to build self-referential
|
|
15
|
-
* types for recursive data structures.
|
|
16
|
-
*/
|
|
17
9
|
|
|
18
10
|
export function lazy(decoderFn) {
|
|
19
11
|
return define(function (blob) {
|
|
20
|
-
return decoderFn().decode(blob)
|
|
21
|
-
})
|
|
12
|
+
return decoderFn().decode(blob)
|
|
13
|
+
})
|
|
22
14
|
}
|
|
23
|
-
/**
|
|
24
|
-
* Pre-process the data input before passing it into the decoder. This gives
|
|
25
|
-
* you the ability to arbitrarily customize the input on the fly before passing
|
|
26
|
-
* it to the decoder. Of course, the input value at that point is still of
|
|
27
|
-
* ``unknown`` type, so you will have to deal with that accordingly.
|
|
28
|
-
*/
|
|
29
15
|
|
|
30
16
|
export function prep(mapperFn, decoder) {
|
|
31
17
|
return define(function (originalInput, _, err) {
|
|
32
|
-
var blob
|
|
18
|
+
var blob
|
|
33
19
|
|
|
34
20
|
try {
|
|
35
|
-
blob = mapperFn(originalInput)
|
|
21
|
+
blob = mapperFn(originalInput)
|
|
36
22
|
} catch (e) {
|
|
37
|
-
return err(annotate(originalInput, e.message))
|
|
23
|
+
return err(annotate(originalInput, e.message))
|
|
38
24
|
}
|
|
39
25
|
|
|
40
|
-
var r = decoder.decode(blob)
|
|
41
|
-
return r.ok ? r : err(annotate(originalInput, r.error.text))
|
|
42
|
-
|
|
43
|
-
// (instead of echoing back blob)
|
|
44
|
-
});
|
|
26
|
+
var r = decoder.decode(blob)
|
|
27
|
+
return r.ok ? r : err(annotate(originalInput, r.error.text))
|
|
28
|
+
})
|
|
45
29
|
}
|
|
46
|
-
/**
|
|
47
|
-
* Rejects all inputs, and always fails with the given error message. May be
|
|
48
|
-
* useful for explicitly disallowing keys, or for testing purposes.
|
|
49
|
-
*/
|
|
50
30
|
|
|
51
31
|
export function never(msg) {
|
|
52
32
|
return define(function (_, __, err) {
|
|
53
|
-
return err(msg)
|
|
54
|
-
})
|
|
33
|
+
return err(msg)
|
|
34
|
+
})
|
|
55
35
|
}
|
|
56
|
-
/**
|
|
57
|
-
* Alias of never().
|
|
58
|
-
*/
|
|
59
36
|
|
|
60
|
-
export var fail = never
|
|
37
|
+
export var fail = never
|
package/package.json
CHANGED
package/result.js
CHANGED
|
@@ -1,34 +1,21 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict'
|
|
2
2
|
|
|
3
|
-
exports.__esModule = true
|
|
4
|
-
exports.err = err
|
|
5
|
-
exports.ok = ok
|
|
3
|
+
exports.__esModule = true
|
|
4
|
+
exports.err = err
|
|
5
|
+
exports.ok = ok
|
|
6
6
|
|
|
7
|
-
/**
|
|
8
|
-
* Result <value> <error>
|
|
9
|
-
* = Ok <value>
|
|
10
|
-
* | Err <error>
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Create a new Result instance representing a successful computation.
|
|
15
|
-
*/
|
|
16
7
|
function ok(value) {
|
|
17
8
|
return {
|
|
18
9
|
ok: true,
|
|
19
10
|
value: value,
|
|
20
|
-
error: undefined
|
|
21
|
-
}
|
|
11
|
+
error: undefined,
|
|
12
|
+
}
|
|
22
13
|
}
|
|
23
|
-
/**
|
|
24
|
-
* Create a new Result instance representing a failed computation.
|
|
25
|
-
*/
|
|
26
|
-
|
|
27
14
|
|
|
28
15
|
function err(error) {
|
|
29
16
|
return {
|
|
30
17
|
ok: false,
|
|
31
18
|
value: undefined,
|
|
32
|
-
error: error
|
|
33
|
-
}
|
|
34
|
-
}
|
|
19
|
+
error: error,
|
|
20
|
+
}
|
|
21
|
+
}
|