Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PoC: Add json :: Shell Text -> Shell Value #166

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Add json
Mitsutoshi Aoe committed Aug 22, 2016
commit 3b56b3ce4505b8fd8d06077d5fb0441f0d23f162
41 changes: 41 additions & 0 deletions src/Turtle/Prelude.hs
Original file line number Diff line number Diff line change
@@ -184,6 +184,7 @@ module Turtle.Prelude (
, limit
, limitWhile
, cache
, json

-- * Folds
, countChars
@@ -247,14 +248,19 @@ import qualified Control.Foldl.Text
import Control.Monad (liftM, msum, when, unless)
import Control.Monad.IO.Class (MonadIO(..))
import Control.Monad.Managed (MonadManaged(..), managed, managed_, runManaged)
import qualified Data.Aeson as Aeson
import qualified Data.Aeson.Parser as Aeson
import qualified Data.Attoparsec.ByteString as A
#ifdef mingw32_HOST_OS
import Data.Bits ((.&.))
#endif
import qualified Data.ByteString as ByteString
import Data.IORef (newIORef, readIORef, writeIORef)
import Data.Text (Text, pack, unpack)
import Data.Time (NominalDiffTime, UTCTime, getCurrentTime)
import Data.Traversable
import qualified Data.Text as Text
import qualified Data.Text.Encoding as Text
import qualified Data.Text.IO as Text
import Data.Typeable (Typeable)
import qualified Filesystem
@@ -1475,6 +1481,41 @@ cache file s = do
empty
justs <|> nothing

{- | Decode JSON text into aeson's 'Aeson.Value'. Invalid JSON values are
implicitly discarded.

>>> view $ json $ select ["{ \"ke", "y\": [", " 1] }[", "]1"]
Object (fromList [("key",Array [Number 1.0])])
Array []
Number 1.0
>>> view $ json $ select ["][]"]
Array []
-}
json :: Shell Text -> Shell Aeson.Value
json s = Shell _foldIO'
where
_foldIO' (FoldM step begin done) = foldIO s
(Control.Foldl.premapM Text.encodeUtf8 (FoldM step' begin' done'))
where
step' (x, r) bs = case A.feed r bs of
A.Fail leftover _ _ ->
step' (x, r0) (ByteString.drop 1 leftover)
r'@(A.Partial {}) -> return (x, r')
r'@(A.Done leftover val) -> do
x' <- step x val
if ByteString.null leftover
then return (x', r')
else step' (x', r0) leftover
begin' = do
x0 <- begin
return (x0, r0)
done' (x, r) = case r of
A.Partial {} -> do
(x', _) <- step' (x, r) ""
done x'
_ -> done x
r0 = A.Partial (A.parse Aeson.value)

-- | Split a line into chunks delimited by the given `Pattern`
cut :: Pattern a -> Text -> [Text]
cut pattern txt = head (match (selfless chars `sepBy` pattern) txt)
3 changes: 3 additions & 0 deletions turtle.cabal
Original file line number Diff line number Diff line change
@@ -48,7 +48,10 @@ Library
HS-Source-Dirs: src
Build-Depends:
base >= 4.6 && < 5 ,
aeson < 1.1,
async >= 2.0.0.0 && < 2.2,
attoparsec >= 0.10.0 && < 0.14,
bytestring < 0.11,
clock >= 0.4.1.2 && < 0.8,
directory >= 1.0.7 && < 1.3,
foldl >= 1.1 && < 1.3,