aeson-filthy-0.1.4: Several newtypes and combinators for dealing with less-than-cleanly JSON input.

Safe HaskellNone
LanguageHaskell2010

Data.Aeson.Filthy

Contents

Description

Several newtypes and combinators for dealing with less-than-cleanly JSON input.

Synopsis

Double-Encodings

newtype JSONString a Source #

A double-encoded JSON value.

>>> encode (JSONString True)
"\"true\""
>>> decode "\"true\"" :: Maybe (JSONString Bool)
Just (JSONString {jsonString = True})

Constructors

JSONString 

Fields

Instances
Bounded a => Bounded (JSONString a) Source # 
Instance details

Defined in Data.Aeson.Filthy

Enum a => Enum (JSONString a) Source # 
Instance details

Defined in Data.Aeson.Filthy

Eq a => Eq (JSONString a) Source # 
Instance details

Defined in Data.Aeson.Filthy

Methods

(==) :: JSONString a -> JSONString a -> Bool #

(/=) :: JSONString a -> JSONString a -> Bool #

Floating a => Floating (JSONString a) Source # 
Instance details

Defined in Data.Aeson.Filthy

Fractional a => Fractional (JSONString a) Source # 
Instance details

Defined in Data.Aeson.Filthy

Integral a => Integral (JSONString a) Source # 
Instance details

Defined in Data.Aeson.Filthy

Num a => Num (JSONString a) Source # 
Instance details

Defined in Data.Aeson.Filthy

Ord a => Ord (JSONString a) Source # 
Instance details

Defined in Data.Aeson.Filthy

Read a => Read (JSONString a) Source # 
Instance details

Defined in Data.Aeson.Filthy

Real a => Real (JSONString a) Source # 
Instance details

Defined in Data.Aeson.Filthy

RealFloat a => RealFloat (JSONString a) Source # 
Instance details

Defined in Data.Aeson.Filthy

RealFrac a => RealFrac (JSONString a) Source # 
Instance details

Defined in Data.Aeson.Filthy

Methods

properFraction :: Integral b => JSONString a -> (b, JSONString a) #

truncate :: Integral b => JSONString a -> b #

round :: Integral b => JSONString a -> b #

ceiling :: Integral b => JSONString a -> b #

floor :: Integral b => JSONString a -> b #

Show a => Show (JSONString a) Source # 
Instance details

Defined in Data.Aeson.Filthy

Ix a => Ix (JSONString a) Source # 
Instance details

Defined in Data.Aeson.Filthy

IsString a => IsString (JSONString a) Source # 
Instance details

Defined in Data.Aeson.Filthy

Methods

fromString :: String -> JSONString a #

Generic (JSONString a) Source # 
Instance details

Defined in Data.Aeson.Filthy

Associated Types

type Rep (JSONString a) :: Type -> Type #

Methods

from :: JSONString a -> Rep (JSONString a) x #

to :: Rep (JSONString a) x -> JSONString a #

ToJSON a => ToJSON (JSONString a) Source # 
Instance details

Defined in Data.Aeson.Filthy

FromJSON a => FromJSON (JSONString a) Source # 
Instance details

Defined in Data.Aeson.Filthy

Storable a => Storable (JSONString a) Source # 
Instance details

Defined in Data.Aeson.Filthy

Methods

sizeOf :: JSONString a -> Int #

alignment :: JSONString a -> Int #

peekElemOff :: Ptr (JSONString a) -> Int -> IO (JSONString a) #

pokeElemOff :: Ptr (JSONString a) -> Int -> JSONString a -> IO () #

peekByteOff :: Ptr b -> Int -> IO (JSONString a) #

pokeByteOff :: Ptr b -> Int -> JSONString a -> IO () #

peek :: Ptr (JSONString a) -> IO (JSONString a) #

poke :: Ptr (JSONString a) -> JSONString a -> IO () #

Bits a => Bits (JSONString a) Source # 
Instance details

Defined in Data.Aeson.Filthy

FiniteBits a => FiniteBits (JSONString a) Source # 
Instance details

Defined in Data.Aeson.Filthy

type Rep (JSONString a) Source # 
Instance details

Defined in Data.Aeson.Filthy

type Rep (JSONString a) = D1 (MetaData "JSONString" "Data.Aeson.Filthy" "aeson-filthy-0.1.4-9i8NYkemH3d81NjvMU5aPu" True) (C1 (MetaCons "JSONString" PrefixI True) (S1 (MetaSel (Just "jsonString") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 a)))

(.:$) :: FromJSON a => Object -> Text -> Parser a Source #

Works like aeson's (.:), but assumes the value being parsed is double-encoded. Mnemonic: $ sorta looks like an S (for String).

(.=$) :: ToJSON a => Text -> a -> Pair Source #

Works like aeson's (.=), but double-encodes the value being serialized.

Booleans

There's a surprising number of ways people like to encode Booleans. At present, the docs below lie a bit in that values which don't parse to a True value are considered false. For instance,

>>> oneOrZero <$> decode "0"
Just False
>>> oneOrZero <$> decode "1"
Just True
>>> oneOrZero <$> decode "2"
Just False

newtype OneOrZero Source #

Values rendered 0 or 1

>>> oneOrZero <$> decode "1"
Just True
>>> oneOrZero <$> decode "0"
Just False

Constructors

OneOrZero 

Fields

Instances
Bounded OneOrZero Source # 
Instance details

Defined in Data.Aeson.Filthy

Enum OneOrZero Source # 
Instance details

Defined in Data.Aeson.Filthy

Eq OneOrZero Source # 
Instance details

Defined in Data.Aeson.Filthy

Ord OneOrZero Source # 
Instance details

Defined in Data.Aeson.Filthy

Read OneOrZero Source # 
Instance details

Defined in Data.Aeson.Filthy

Show OneOrZero Source # 
Instance details

Defined in Data.Aeson.Filthy

Ix OneOrZero Source # 
Instance details

Defined in Data.Aeson.Filthy

Generic OneOrZero Source # 
Instance details

Defined in Data.Aeson.Filthy

Associated Types

type Rep OneOrZero :: Type -> Type #

ToJSON OneOrZero Source # 
Instance details

Defined in Data.Aeson.Filthy

FromJSON OneOrZero Source # 
Instance details

Defined in Data.Aeson.Filthy

Storable OneOrZero Source # 
Instance details

Defined in Data.Aeson.Filthy

Bits OneOrZero Source # 
Instance details

Defined in Data.Aeson.Filthy

FiniteBits OneOrZero Source # 
Instance details

Defined in Data.Aeson.Filthy

type Rep OneOrZero Source # 
Instance details

Defined in Data.Aeson.Filthy

type Rep OneOrZero = D1 (MetaData "OneOrZero" "Data.Aeson.Filthy" "aeson-filthy-0.1.4-9i8NYkemH3d81NjvMU5aPu" True) (C1 (MetaCons "OneOrZero" PrefixI True) (S1 (MetaSel (Just "oneOrZero") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 Bool)))

newtype YesOrNo Source #

Values rendered "yes" or "no"

>>> yesOrNo <$> decode "\"yes\""
Just True
>>> yesOrNo <$> decode "\"no\""
Just False

Constructors

YesOrNo 

Fields

Instances
Bounded YesOrNo Source # 
Instance details

Defined in Data.Aeson.Filthy

Enum YesOrNo Source # 
Instance details

Defined in Data.Aeson.Filthy

Eq YesOrNo Source # 
Instance details

Defined in Data.Aeson.Filthy

Methods

(==) :: YesOrNo -> YesOrNo -> Bool #

(/=) :: YesOrNo -> YesOrNo -> Bool #

Ord YesOrNo Source # 
Instance details

Defined in Data.Aeson.Filthy

Read YesOrNo Source # 
Instance details

Defined in Data.Aeson.Filthy

Show YesOrNo Source # 
Instance details

Defined in Data.Aeson.Filthy

Ix YesOrNo Source # 
Instance details

Defined in Data.Aeson.Filthy

Generic YesOrNo Source # 
Instance details

Defined in Data.Aeson.Filthy

Associated Types

type Rep YesOrNo :: Type -> Type #

Methods

from :: YesOrNo -> Rep YesOrNo x #

to :: Rep YesOrNo x -> YesOrNo #

ToJSON YesOrNo Source # 
Instance details

Defined in Data.Aeson.Filthy

FromJSON YesOrNo Source # 
Instance details

Defined in Data.Aeson.Filthy

Storable YesOrNo Source # 
Instance details

Defined in Data.Aeson.Filthy

Bits YesOrNo Source # 
Instance details

Defined in Data.Aeson.Filthy

FiniteBits YesOrNo Source # 
Instance details

Defined in Data.Aeson.Filthy

type Rep YesOrNo Source # 
Instance details

Defined in Data.Aeson.Filthy

type Rep YesOrNo = D1 (MetaData "YesOrNo" "Data.Aeson.Filthy" "aeson-filthy-0.1.4-9i8NYkemH3d81NjvMU5aPu" True) (C1 (MetaCons "YesOrNo" PrefixI True) (S1 (MetaSel (Just "yesOrNo") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 Bool)))

newtype OnOrOff Source #

Values rendered "on" or "off"

>>> onOrOff <$> decode "\"on\""
Just True
>>> onOrOff <$> decode "\"off\""
Just False

Constructors

OnOrOff 

Fields

Instances
Bounded OnOrOff Source # 
Instance details

Defined in Data.Aeson.Filthy

Enum OnOrOff Source # 
Instance details

Defined in Data.Aeson.Filthy

Eq OnOrOff Source # 
Instance details

Defined in Data.Aeson.Filthy

Methods

(==) :: OnOrOff -> OnOrOff -> Bool #

(/=) :: OnOrOff -> OnOrOff -> Bool #

Ord OnOrOff Source # 
Instance details

Defined in Data.Aeson.Filthy

Read OnOrOff Source # 
Instance details

Defined in Data.Aeson.Filthy

Show OnOrOff Source # 
Instance details

Defined in Data.Aeson.Filthy

Ix OnOrOff Source # 
Instance details

Defined in Data.Aeson.Filthy

Generic OnOrOff Source # 
Instance details

Defined in Data.Aeson.Filthy

Associated Types

type Rep OnOrOff :: Type -> Type #

Methods

from :: OnOrOff -> Rep OnOrOff x #

to :: Rep OnOrOff x -> OnOrOff #

ToJSON OnOrOff Source # 
Instance details

Defined in Data.Aeson.Filthy

FromJSON OnOrOff Source # 
Instance details

Defined in Data.Aeson.Filthy

Storable OnOrOff Source # 
Instance details

Defined in Data.Aeson.Filthy

Bits OnOrOff Source # 
Instance details

Defined in Data.Aeson.Filthy

FiniteBits OnOrOff Source # 
Instance details

Defined in Data.Aeson.Filthy

type Rep OnOrOff Source # 
Instance details

Defined in Data.Aeson.Filthy

type Rep OnOrOff = D1 (MetaData "OnOrOff" "Data.Aeson.Filthy" "aeson-filthy-0.1.4-9i8NYkemH3d81NjvMU5aPu" True) (C1 (MetaCons "OnOrOff" PrefixI True) (S1 (MetaSel (Just "onOrOff") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 Bool)))

newtype AnyBool Source #

Values rendered as more-or-less anything.

>>> let Just bs = decode "[1, \"1\", \"true\", \"yes\", \"on\", true]"
>>> and $ map anyBool bs
True

Constructors

AnyBool 

Fields

Instances
Bounded AnyBool Source # 
Instance details

Defined in Data.Aeson.Filthy

Enum AnyBool Source # 
Instance details

Defined in Data.Aeson.Filthy

Eq AnyBool Source # 
Instance details

Defined in Data.Aeson.Filthy

Methods

(==) :: AnyBool -> AnyBool -> Bool #

(/=) :: AnyBool -> AnyBool -> Bool #

Ord AnyBool Source # 
Instance details

Defined in Data.Aeson.Filthy

Read AnyBool Source # 
Instance details

Defined in Data.Aeson.Filthy

Show AnyBool Source # 
Instance details

Defined in Data.Aeson.Filthy

Ix AnyBool Source # 
Instance details

Defined in Data.Aeson.Filthy

Generic AnyBool Source # 
Instance details

Defined in Data.Aeson.Filthy

Associated Types

type Rep AnyBool :: Type -> Type #

Methods

from :: AnyBool -> Rep AnyBool x #

to :: Rep AnyBool x -> AnyBool #

FromJSON AnyBool Source # 
Instance details

Defined in Data.Aeson.Filthy

Storable AnyBool Source # 
Instance details

Defined in Data.Aeson.Filthy

Bits AnyBool Source # 
Instance details

Defined in Data.Aeson.Filthy

FiniteBits AnyBool Source # 
Instance details

Defined in Data.Aeson.Filthy

type Rep AnyBool Source # 
Instance details

Defined in Data.Aeson.Filthy

type Rep AnyBool = D1 (MetaData "AnyBool" "Data.Aeson.Filthy" "aeson-filthy-0.1.4-9i8NYkemH3d81NjvMU5aPu" True) (C1 (MetaCons "AnyBool" PrefixI True) (S1 (MetaSel (Just "anyBool") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 Bool)))

Maybe

newtype EmptyAsNothing a Source #

Sometimes an empty string in a JSON object actually means Nothing

>>> emptyAsNothing <$> decode "\"\"" :: Maybe (Maybe Text)
Just Nothing
>>> emptyAsNothing <$> decode "\"something\"" :: Maybe (Maybe Text)
Just (Just "something")

Constructors

EmptyAsNothing 

Fields

Instances
Monad EmptyAsNothing Source # 
Instance details

Defined in Data.Aeson.Filthy

Functor EmptyAsNothing Source # 
Instance details

Defined in Data.Aeson.Filthy

Methods

fmap :: (a -> b) -> EmptyAsNothing a -> EmptyAsNothing b #

(<$) :: a -> EmptyAsNothing b -> EmptyAsNothing a #

MonadFix EmptyAsNothing Source # 
Instance details

Defined in Data.Aeson.Filthy

Methods

mfix :: (a -> EmptyAsNothing a) -> EmptyAsNothing a #

Applicative EmptyAsNothing Source # 
Instance details

Defined in Data.Aeson.Filthy

Foldable EmptyAsNothing Source # 
Instance details

Defined in Data.Aeson.Filthy

Methods

fold :: Monoid m => EmptyAsNothing m -> m #

foldMap :: Monoid m => (a -> m) -> EmptyAsNothing a -> m #

foldr :: (a -> b -> b) -> b -> EmptyAsNothing a -> b #

foldr' :: (a -> b -> b) -> b -> EmptyAsNothing a -> b #

foldl :: (b -> a -> b) -> b -> EmptyAsNothing a -> b #

foldl' :: (b -> a -> b) -> b -> EmptyAsNothing a -> b #

foldr1 :: (a -> a -> a) -> EmptyAsNothing a -> a #

foldl1 :: (a -> a -> a) -> EmptyAsNothing a -> a #

toList :: EmptyAsNothing a -> [a] #

null :: EmptyAsNothing a -> Bool #

length :: EmptyAsNothing a -> Int #

elem :: Eq a => a -> EmptyAsNothing a -> Bool #

maximum :: Ord a => EmptyAsNothing a -> a #

minimum :: Ord a => EmptyAsNothing a -> a #

sum :: Num a => EmptyAsNothing a -> a #

product :: Num a => EmptyAsNothing a -> a #

Traversable EmptyAsNothing Source # 
Instance details

Defined in Data.Aeson.Filthy

Methods

traverse :: Applicative f => (a -> f b) -> EmptyAsNothing a -> f (EmptyAsNothing b) #

sequenceA :: Applicative f => EmptyAsNothing (f a) -> f (EmptyAsNothing a) #

mapM :: Monad m => (a -> m b) -> EmptyAsNothing a -> m (EmptyAsNothing b) #

sequence :: Monad m => EmptyAsNothing (m a) -> m (EmptyAsNothing a) #

Alternative EmptyAsNothing Source # 
Instance details

Defined in Data.Aeson.Filthy

MonadPlus EmptyAsNothing Source # 
Instance details

Defined in Data.Aeson.Filthy

Eq a => Eq (EmptyAsNothing a) Source # 
Instance details

Defined in Data.Aeson.Filthy

Ord a => Ord (EmptyAsNothing a) Source # 
Instance details

Defined in Data.Aeson.Filthy

Read a => Read (EmptyAsNothing a) Source # 
Instance details

Defined in Data.Aeson.Filthy

Show a => Show (EmptyAsNothing a) Source # 
Instance details

Defined in Data.Aeson.Filthy

Generic (EmptyAsNothing a) Source # 
Instance details

Defined in Data.Aeson.Filthy

Associated Types

type Rep (EmptyAsNothing a) :: Type -> Type #

Semigroup a => Semigroup (EmptyAsNothing a) Source # 
Instance details

Defined in Data.Aeson.Filthy

Semigroup a => Monoid (EmptyAsNothing a) Source # 
Instance details

Defined in Data.Aeson.Filthy

ToJSON a => ToJSON (EmptyAsNothing a) Source # 
Instance details

Defined in Data.Aeson.Filthy

FromJSON a => FromJSON (EmptyAsNothing a) Source # 
Instance details

Defined in Data.Aeson.Filthy

Generic1 EmptyAsNothing Source # 
Instance details

Defined in Data.Aeson.Filthy

Associated Types

type Rep1 EmptyAsNothing :: k -> Type #

type Rep (EmptyAsNothing a) Source # 
Instance details

Defined in Data.Aeson.Filthy

type Rep (EmptyAsNothing a) = D1 (MetaData "EmptyAsNothing" "Data.Aeson.Filthy" "aeson-filthy-0.1.4-9i8NYkemH3d81NjvMU5aPu" True) (C1 (MetaCons "EmptyAsNothing" PrefixI True) (S1 (MetaSel (Just "emptyAsNothing") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 (Maybe a))))
type Rep1 EmptyAsNothing Source # 
Instance details

Defined in Data.Aeson.Filthy

type Rep1 EmptyAsNothing = D1 (MetaData "EmptyAsNothing" "Data.Aeson.Filthy" "aeson-filthy-0.1.4-9i8NYkemH3d81NjvMU5aPu" True) (C1 (MetaCons "EmptyAsNothing" PrefixI True) (S1 (MetaSel (Just "emptyAsNothing") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec1 Maybe)))

EmptyObject

newtype EmptyObject Source #

Sometimes an empty object is all there is (e.g. returned instead of HTTP 204).

>>> decode "{}" :: Maybe EmptyObject
Just (EmptyObject {emptyObject = ()})
> eitherDecode "{\"\":\"\"}" :: Either String EmptyObject

Left "Error in $: parsing EmptyObject failed, encountered non-empty Object"

>>> encode (EmptyObject ())
"{}"

Constructors

EmptyObject 

Fields

Instances
Bounded EmptyObject Source # 
Instance details

Defined in Data.Aeson.Filthy

Enum EmptyObject Source # 
Instance details

Defined in Data.Aeson.Filthy

Eq EmptyObject Source # 
Instance details

Defined in Data.Aeson.Filthy

Ord EmptyObject Source # 
Instance details

Defined in Data.Aeson.Filthy

Read EmptyObject Source # 
Instance details

Defined in Data.Aeson.Filthy

Show EmptyObject Source # 
Instance details

Defined in Data.Aeson.Filthy

Generic EmptyObject Source # 
Instance details

Defined in Data.Aeson.Filthy

Associated Types

type Rep EmptyObject :: Type -> Type #

ToJSON EmptyObject Source # 
Instance details

Defined in Data.Aeson.Filthy

FromJSON EmptyObject Source # 
Instance details

Defined in Data.Aeson.Filthy

type Rep EmptyObject Source # 
Instance details

Defined in Data.Aeson.Filthy

type Rep EmptyObject = D1 (MetaData "EmptyObject" "Data.Aeson.Filthy" "aeson-filthy-0.1.4-9i8NYkemH3d81NjvMU5aPu" True) (C1 (MetaCons "EmptyObject" PrefixI True) (S1 (MetaSel (Just "emptyObject") NoSourceUnpackedness NoSourceStrictness DecidedLazy) (Rec0 ())))

Time

newtype RFC2822Time Source #

A RFC 2822 encoded time value, allowing the modern RFC 2822 format. These parsers do not currently handle the more messy whitespace and comments allowed by the RFC.

The primary use for this if JSON APIs that dump JS datetimes as strings into the JSON.

Encoding follows the modern RFC 2822 recomended format:

>>> encode (RFC2822Time (read "2011-10-13 18:02:00 UTC"))
"\"Thu, 13 Oct 2011 18:02:00 +0000\""

Decoding though must be far more liberal:

>>> decode "\"Thu, 13 Oct 2011 18:02:00 GMT\"" :: Maybe RFC2822Time
Just (RFC2822Time {fromRFC2822Time = 2011-10-13 18:02:00 UTC})
>>> decode "\"Fri, 21 Nov 1997 09:55:06 -0600\"" :: Maybe RFC2822Time
Just (RFC2822Time {fromRFC2822Time = 1997-11-21 15:55:06 UTC})
>>> decode "\"Tue, 1 Jul 2003 10:52:37 +0200\"" :: Maybe RFC2822Time
Just (RFC2822Time {fromRFC2822Time = 2003-07-01 08:52:37 UTC})
>>> decode "\"Thu, 13 Feb 1969 23:32:54 -0330\"" :: Maybe RFC2822Time
Just (RFC2822Time {fromRFC2822Time = 1969-02-14 03:02:54 UTC})

RFC 822 obsolete dates:

>>> decode "\"21 Nov 97 09:55:06 GMT\"" :: Maybe RFC2822Time
Just (RFC2822Time {fromRFC2822Time = 0097-11-21 09:55:06 UTC})

Things that should parse but don't:

decode ""Thu,n 13n Febn 1969n 23:32n -0330 (Newfoundland Time)"" :: Maybe RFC2822Time

Just (RFC2822Time {fromRFC2822Time = 1969-02-14 03:02:00 UTC})

decode ""Fri, 21 Nov 1997 09(comment): 55 : 06 -0600"" :: Maybe RFC2822Time

Just (RFC2822Time {fromRFC2822Time = 1997-11-21 15:55:06 UTC})

Constructors

RFC2822Time 

Case Insensitive Keys

(.:~) :: FromJSON a => Object -> Text -> Parser a Source #

Some systems attempt to treat keys in JSON objects case-insensitively(ish). Golang's JSON marshalling is a prominent example: https://golang.org/pkg/encoding/json/#Marshal. The (.:~) combinator works like (.:), but if it fails to match, attempts to find a case-insensitive variant of the key being sought. If there is an exact match, (.:~) will take that; if there are multiple non-exact matches, the choice of selected value is unspecified. Mnemonic: ~ swaps case in vi.

>>> data Foo = Foo Int deriving (Read, Show)
>>> instance FromJSON Foo where parseJSON (Object o) = Foo <$> o .:~ "foo"
>>> decode "{\"FOO\": 12}" :: Maybe Foo
Just (Foo 12)
>>> decode "{\"foo\": 17, \"FOO\": 12}" :: Maybe Foo
Just (Foo 17)