Skip to content

Commit

Permalink
Merge pull request #16 from mojotech/em/const
Browse files Browse the repository at this point in the history
Allow constant decoder to match constant arrays and objects
  • Loading branch information
mulias authored Feb 20, 2018
2 parents 1fbe837 + a710f83 commit 6e6e9d4
Show file tree
Hide file tree
Showing 5 changed files with 52 additions and 20 deletions.
22 changes: 13 additions & 9 deletions docs/classes/_decoder_.decoder.md
Original file line number Diff line number Diff line change
Expand Up @@ -386,15 +386,19 @@ Note that `constant('string to match')` returns a `Decoder<string>` which fails

Providing the type parameter is only necessary for type-literal strings and numbers, as detailed by this table:

| Decoder | Type |
| ---------------------------- | ----------------- |
| constant(true) | Decoder<true> |
| constant(false) | Decoder<false> |
| constant(null) | Decoder<null> |
| constant('alaska') | Decoder<string> |
| constant<'alaska'>('alaska') | Decoder<'alaska'> |
| constant(50) | Decoder<number> |
| constant<50>(50) | Decoder<50> |
| Decoder | Type |
| ---------------------------- | ---------------------|
| constant(true) | Decoder<true> |
| constant(false) | Decoder<false> |
| constant(null) | Decoder<null> |
| constant('alaska') | Decoder<string> |
| constant<'alaska'>('alaska') | Decoder<'alaska'> |
| constant(50) | Decoder<number> |
| constant<50>(50) | Decoder<50> |
| constant([1,2,3]) | Decoder<number[]> |
| constant<[1,2,3]>([1,2,3]) | Decoder<[1,2,3]> |
| constant({x: 't'}) | Decoder<{x: string}> |
| constant<{x: 't'}>({x: 't'}) | Decoder<{x: 't'}> |

One place where this happens is when a type-literal is in an interface:

Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@
"colors": "^1.1.2",
"cross-env": "^5.0.1",
"jest": "^22.0.2",
"lodash": "^4.17.5",
"prettier": "^1.4.4",
"rimraf": "^2.6.1",
"rollup": "^0.53.0",
Expand Down
25 changes: 15 additions & 10 deletions src/decoder.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as Result from './result';
const isEqual = require('lodash/isEqual'); // this syntax avoids TS1192

/**
* Information describing how json data failed to match a decoder.
Expand Down Expand Up @@ -177,15 +178,19 @@ export class Decoder<A> {
* and numbers, as detailed by this table:
*
* ```
* | Decoder | Type |
* | ---------------------------- | ----------------- |
* | constant(true) | Decoder<true> |
* | constant(false) | Decoder<false> |
* | constant(null) | Decoder<null> |
* | constant('alaska') | Decoder<string> |
* | constant<'alaska'>('alaska') | Decoder<'alaska'> |
* | constant(50) | Decoder<number> |
* | constant<50>(50) | Decoder<50> |
* | Decoder | Type |
* | ---------------------------- | ---------------------|
* | constant(true) | Decoder<true> |
* | constant(false) | Decoder<false> |
* | constant(null) | Decoder<null> |
* | constant('alaska') | Decoder<string> |
* | constant<'alaska'>('alaska') | Decoder<'alaska'> |
* | constant(50) | Decoder<number> |
* | constant<50>(50) | Decoder<50> |
* | constant([1,2,3]) | Decoder<number[]> |
* | constant<[1,2,3]>([1,2,3]) | Decoder<[1,2,3]> |
* | constant({x: 't'}) | Decoder<{x: string}> |
* | constant<{x: 't'}>({x: 't'}) | Decoder<{x: 't'}> |
* ```
*
*
Expand Down Expand Up @@ -234,7 +239,7 @@ export class Decoder<A> {
static constant(value: any): Decoder<any> {
return new Decoder(
(json: any) =>
json === value
isEqual(json, value)
? Result.ok(value)
: Result.err({message: `expected ${JSON.stringify(value)}, got ${JSON.stringify(json)}`})
);
Expand Down
22 changes: 22 additions & 0 deletions test/json-decode.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,28 @@ describe('constant', () => {

expect(decoder.run({x: null})).toEqual({ok: true, result: {x: null}});
});

it('can decode a constant array', () => {
type A = [1, 2, 3];
const decoder: Decoder<A> = constant<A>([1, 2, 3]);

expect(decoder.run([1, 2, 3])).toEqual({ok: true, result: [1, 2, 3]});
expect(decoder.run([1, 2, 3, 4])).toMatchObject({
ok: false,
error: {at: 'input', message: 'expected [1,2,3], got [1,2,3,4]'}
});
});

it('can decode a constant object', () => {
type O = {a: true; b: 12};
const decoder: Decoder<O> = constant<O>({a: true, b: 12});

expect(decoder.run({a: true, b: 12})).toEqual({ok: true, result: {a: true, b: 12}});
expect(decoder.run({a: true, b: 7})).toMatchObject({
ok: false,
error: {at: 'input', message: 'expected {"a":true,"b":12}, got {"a":true,"b":7}'}
});
});
});

describe('object', () => {
Expand Down
2 changes: 1 addition & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1917,7 +1917,7 @@ lodash.sortby@^4.7.0:
version "4.7.0"
resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"

lodash@^4.13.1, lodash@^4.14.0, lodash@^4.17.4:
lodash@^4.13.1, lodash@^4.14.0, lodash@^4.17.4, lodash@^4.17.5:
version "4.17.5"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.5.tgz#99a92d65c0272debe8c96b6057bc8fbfa3bed511"

Expand Down

0 comments on commit 6e6e9d4

Please sign in to comment.