Safe Haskell | Safe-Inferred |
---|---|
Language | Haskell2010 |
Exposes functions for building JSON decoders that harness the power of the simdjson::ondemand API.
A decoder is really a function from a simdjson Value
to some Haskell type in the DecoderM
monad.
It looks like
Data.Aeson.parseJSON,
except the Value
is opaque and can only be used when it's passed by
reference across the C FFI.
decodeEither
provides the quickest way to feed the initial Value
to your decoder.
It does this by obtaining a top-level Value
from the simdjson document
instance. Decoding a document into a scalar from a Value
is not supported
by simdjson. While simdjson can cast a document directly to a scalar, this
library currently exposes no interface for this.
Synopsis
- decodeEither :: Decoder a -> ByteString -> Either HermesException a
- decodeEitherIO :: Decoder a -> ByteString -> IO a
- parseByteString :: HermesEnv -> Decoder a -> ByteString -> Either HermesException a
- parseByteStringIO :: HermesEnv -> Decoder a -> ByteString -> IO a
- data Decoder a
- data FieldsDecoder a
- data DecoderM a
- data HermesEnv
- mkHermesEnv :: Maybe Int -> IO HermesEnv
- mkHermesEnv_ :: IO HermesEnv
- withHermesEnv :: Maybe Int -> (HermesEnv -> IO a) -> IO a
- withHermesEnv_ :: (HermesEnv -> IO a) -> IO a
- atKey :: Text -> Decoder a -> FieldsDecoder a
- atKeyOptional :: Text -> Decoder a -> FieldsDecoder (Maybe a)
- atKeyStrict :: Text -> Decoder a -> FieldsDecoder a
- atPointer :: Text -> Decoder a -> Decoder a
- bool :: Decoder Bool
- char :: Decoder Char
- double :: Decoder Double
- int :: Decoder Int
- uint :: Decoder Word
- object :: FieldsDecoder a -> Decoder a
- scientific :: Decoder Scientific
- string :: Decoder String
- text :: Decoder Text
- list :: Decoder a -> Decoder [a]
- listOfInt :: Decoder [Int]
- listOfDouble :: Decoder [Double]
- vector :: Vector v a => Decoder a -> Decoder (v a)
- nullable :: Decoder a -> Decoder (Maybe a)
- objectAsKeyValues :: (Text -> Decoder k) -> Decoder v -> Decoder [(k, v)]
- objectAsMap :: Ord k => (Text -> Decoder k) -> Decoder v -> Decoder (Map k v)
- day :: Decoder Day
- month :: Decoder Month
- quarter :: Decoder Quarter
- timeOfDay :: Decoder TimeOfDay
- timeZone :: Decoder TimeZone
- localTime :: Decoder LocalTime
- utcTime :: Decoder UTCTime
- zonedTime :: Decoder ZonedTime
- data HermesException
- data DocumentError = DocumentError {}
- getType :: Decoder ValueType
- isNull :: Decoder Bool
- withBool :: (Bool -> Decoder a) -> Decoder a
- withDouble :: (Double -> Decoder a) -> Decoder a
- withInt :: (Int -> Decoder a) -> Decoder a
- withObjectAsMap :: Ord k => (Text -> Decoder k) -> Decoder v -> (Map k v -> Decoder a) -> Decoder a
- withScientific :: (Scientific -> Decoder a) -> Decoder a
- withString :: (String -> Decoder a) -> Decoder a
- withText :: (Text -> Decoder a) -> Decoder a
- withType :: (ValueType -> Decoder a) -> Decoder a
- withVector :: Vector v a => Decoder a -> (v a -> Decoder a) -> Decoder a
- withRawByteString :: (ByteString -> Decoder a) -> Decoder a
- data Array
- data ArrayIter
- data Document
- data InputBuffer
- data Object
- data Parser
- data Value
- data ValueType
Decoding from ByteString input
decodeEither :: Decoder a -> ByteString -> Either HermesException a Source #
Decode a strict ByteString
using the simdjson::ondemand bindings.
Creates simdjson instances on each decode.
decodeEitherIO :: Decoder a -> ByteString -> IO a Source #
Decode a strict ByteString
using the simdjson::ondemand bindings.
Creates simdjson instances on each decode. Runs in IO instead of discharging it.
parseByteString :: HermesEnv -> Decoder a -> ByteString -> Either HermesException a Source #
parseByteStringIO :: HermesEnv -> Decoder a -> ByteString -> IO a Source #
data FieldsDecoder a Source #
Newtype over field decoders. This is helpful so users avoid unsafe decoders like `object $ object ...`.
Instances
Decoder monad
DecoderM is some context around the IO needed by the C FFI to allocate local memory.
Users have no access to the underlying IO, since this could allow decoders to launch nukes.
Using decodeEither
discharges the IO and returns us to purity,
since we know decoding a document is referentially transparent.
Contains foreign references to the allocated simdjson::parser and simdjson::document. Also maintains state for error reporting that is updated when an object field or array value is entered.
mkHermesEnv :: Maybe Int -> IO HermesEnv Source #
Allocates foreign references to a simdjson::ondemand::parser and a
simdjson::ondemand::document. The optional capacity argument sets the max
capacity in bytes for the simdjson::ondemand::parser, which defaults to 4GB.
It is preferable to use withHermesEnv
to keep foreign references in scope.
Be careful using this, the foreign references can be finalized if the
HermesEnv
goes out of scope.
Do _not_ share a HermesEnv
across multiple threads. Each thread should get its own.
Object field decoders
atKey :: Text -> Decoder a -> FieldsDecoder a Source #
Find an object field by key, where an exception is thrown if the key is missing.
atKeyOptional :: Text -> Decoder a -> FieldsDecoder (Maybe a) Source #
Find an object field by key, where Nothing is returned if the key is missing.
atKeyStrict :: Text -> Decoder a -> FieldsDecoder a Source #
Uses find_field, which means if you access a field out-of-order this will throw an exception. It also cannot support optional fields.
Decoders
JSON pointer
atPointer :: Text -> Decoder a -> Decoder a Source #
Decode a value at the particular JSON pointer following RFC 6901. Be careful where you use this because it rewinds the document on each successive call.
decodeEither (atPointer "/statuses/99" decodeObject) input
Values
scientific :: Decoder Scientific Source #
Parse a Scientific from a Value.
string :: Decoder String Source #
Parse a JSON string into a Haskell String.
For best performance you should use text
instead.
listOfDouble :: Decoder [Double] Source #
Is more efficient by looping in C++ instead of Haskell.
vector :: Vector v a => Decoder a -> Decoder (v a) Source #
Parse a homogenous JSON array into a generic Vector
.
nullable :: Decoder a -> Decoder (Maybe a) Source #
Transforms a parser to return Nothing when the value is null.
:: (Text -> Decoder k) | Parses a Text key in the Decoder monad. JSON keys are always text. |
-> Decoder v | Decoder for the field value. |
-> Decoder [(k, v)] |
Parse an object into a homogenous list of key-value tuples.
:: Ord k | |
=> (Text -> Decoder k) | Parses a Text key in the Decoder monad. JSON keys are always text. |
-> Decoder v | Decoder for the field value. |
-> Decoder (Map k v) |
Parse an object into a strict Map
.
Date and time
Parses date and time types from Data.Time using the same Text parsers as Data.Aeson via https://hackage.haskell.org/package/text-iso8601.
Parse a date of the form [+-]YYYY-MM-DD. The year must contain at least 4 digits, to avoid the Y2K problem: a two-digit year YY may mean YY, 19YY, or 20YY, and we make it an error to prevent the ambiguity. Years from 0000 to 0999 must thus be zero-padded. The year may have more than 4 digits.
timeZone :: Decoder TimeZone Source #
Parse a time zone, and return Nothing
if the offset from UTC is
zero. (This makes some speedups possible.)
localTime :: Decoder LocalTime Source #
Parse a date and time, of the form YYYY-MM-DD HH:MM[:SS[.SSS]]
.
The space may be replaced with a T
. The number of seconds is optional
and may be followed by a fractional component.
utcTime :: Decoder UTCTime Source #
Behaves as zonedTime
, but converts any time zone offset into a UTC time.
zonedTime :: Decoder ZonedTime Source #
Parse a date with time zone info. Acceptable formats:
YYYY-MM-DD HH:MM Z
YYYY-MM-DD HH:MM:SS Z
YYYY-MM-DD HH:MM:SS.SSS Z
The first space may instead be a T
, and the second space is
optional. The Z
represents UTC. The Z
may be replaced with a
time zone offset of the form +0000
or -08:00
, where the first
two digits are hours, the :
is optional and the second two digits
(also optional) are minutes.
Error Types
data HermesException Source #
The library can throw exceptions from simdjson in addition to its own exceptions.
SIMDException !DocumentError | An exception thrown from the simdjson library. |
InternalException !DocumentError | An exception thrown from an internal library function. |
Instances
data DocumentError Source #
Record containing all pertinent information for troubleshooting an exception.
Instances
Value helpers
withBool :: (Bool -> Decoder a) -> Decoder a Source #
Helper to work with a Bool parsed from a Value.
withDouble :: (Double -> Decoder a) -> Decoder a Source #
Helper to work with a Double parsed from a Value.
withScientific :: (Scientific -> Decoder a) -> Decoder a Source #
withString :: (String -> Decoder a) -> Decoder a Source #
Helper to work with a String parsed from a Value.
withText :: (Text -> Decoder a) -> Decoder a Source #
Helper to work with a Text parsed from a Value.
Raw ByteString access
withRawByteString :: (ByteString -> Decoder a) -> Decoder a Source #
Helper to work with the raw ByteString of the JSON token parsed from the given Value.
simdjson Opaque Types
data InputBuffer Source #
A reference to an opaque simdjson::padded_string.
Instances
Bounded ValueType Source # | |
Enum ValueType Source # | |
Defined in Data.Hermes.SIMDJSON.Types succ :: ValueType -> ValueType # pred :: ValueType -> ValueType # fromEnum :: ValueType -> Int # enumFrom :: ValueType -> [ValueType] # enumFromThen :: ValueType -> ValueType -> [ValueType] # enumFromTo :: ValueType -> ValueType -> [ValueType] # enumFromThenTo :: ValueType -> ValueType -> ValueType -> [ValueType] # | |
Show ValueType Source # | |
Eq ValueType Source # | |