diff --git a/index.js b/index.js index d9ba959e..fb8ac0a8 100644 --- a/index.js +++ b/index.js @@ -2760,24 +2760,28 @@ )(s); }); - //# parseJson :: String -> Maybe Any + //# parseJson :: TypeRep a -> String -> Maybe a //. - //. Takes a string which may or may not be valid JSON, and returns Just - //. the result of applying `JSON.parse` to the string if valid; Nothing - //. otherwise. + //. Takes a [type representative](#type-representatives) and a string which + //. may or may not be valid JSON, and returns Just the result of applying + //. `JSON.parse` to the string *if* the result is of the specified type + //. (according to [`is`](#is)); Nothing otherwise. //. //. ```javascript - //. > S.parseJson('["foo","bar","baz"]') + //. > S.parseJson(Array, '["foo","bar","baz"]') //. Just(['foo', 'bar', 'baz']) //. - //. > S.parseJson('[') + //. > S.parseJson(Array, '[') + //. Nothing() + //. + //. > S.parseJson(Object, '["foo","bar","baz"]') //. Nothing() //. ``` S.parseJson = def('parseJson', {}, - [$.String, $Maybe($.Any)], - encase(JSON.parse)); + [TypeRep, $.String, $Maybe(a)], + function(type, s) { return filter(is(type), encase(JSON.parse, s)); }); //. ### RegExp diff --git a/test/index.js b/test/index.js index 60f58bca..a65c7b75 100644 --- a/test/index.js +++ b/test/index.js @@ -5125,19 +5125,31 @@ describe('parse', function() { describe('parseJson', function() { - it('is a unary function', function() { + it('is a binary function', function() { eq(typeof S.parseJson, 'function'); - eq(S.parseJson.length, 1); + eq(S.parseJson.length, 2); }); it('type checks its arguments', function() { - throws(function() { S.parseJson([1, 2, 3]); }, + throws(function() { S.parseJson('String'); }, errorEq(TypeError, 'Invalid value\n' + '\n' + - 'parseJson :: String -> Maybe Any\n' + - ' ^^^^^^\n' + - ' 1\n' + + 'parseJson :: TypeRep -> String -> Maybe a\n' + + ' ^^^^^^^\n' + + ' 1\n' + + '\n' + + '1) "String" :: String\n' + + '\n' + + 'The value at position 1 is not a member of ‘TypeRep’.\n')); + + throws(function() { S.parseJson(Array, [1, 2, 3]); }, + errorEq(TypeError, + 'Invalid value\n' + + '\n' + + 'parseJson :: TypeRep -> String -> Maybe a\n' + + ' ^^^^^^\n' + + ' 1\n' + '\n' + '1) [1, 2, 3] :: Array Number, Array FiniteNumber, Array NonZeroFiniteNumber, Array Integer, Array ValidNumber\n' + '\n' + @@ -5145,11 +5157,15 @@ describe('parse', function() { }); it('returns a Just when applied to a valid JSON string', function() { - eq(S.parseJson('["foo","bar"]'), S.Just(['foo', 'bar'])); + eq(S.parseJson(Array, '["foo","bar"]'), S.Just(['foo', 'bar'])); }); it('returns a Nothing when applied to an invalid JSON string', function() { - eq(S.parseJson('[Invalid JSON]'), S.Nothing()); + eq(S.parseJson(Object, '[Invalid JSON]'), S.Nothing()); + }); + + it('returns a Nothing when the parsed result is not a member of the given type', function() { + eq(S.parseJson(Array, '{"foo":"bar"}'), S.Nothing()); }); });