lens-aeson-1.1/0000755000000000000000000000000007346545000011610 5ustar0000000000000000lens-aeson-1.1/.ghci0000755000000000000000000000012507346545000012524 0ustar0000000000000000:set -isrc -idist/build/autogen -optP-include -optPdist/build/autogen/cabal_macros.h lens-aeson-1.1/.gitignore0000755000000000000000000000043007346545000013600 0ustar0000000000000000dist dist-newstyle docs wiki TAGS tags wip .DS_Store .*.swp .*.swo *.o *.hi *~ *# .stack-work/ cabal-dev *.chi *.chs.h *.dyn_o *.dyn_hi .hpc .hsenv .cabal-sandbox/ cabal.sandbox.config *.prof *.aux *.hp *.eventlog cabal.project.local cabal.project.local~ .HTF/ .ghc.environment.* lens-aeson-1.1/.travis.yml0000755000000000000000000002160307346545000013726 0ustar0000000000000000# This Travis job script has been generated by a script via # # haskell-ci '--output=.travis.yml' '--config=cabal.haskell-ci' 'cabal.project' # # For more information, see https://github.com/haskell-CI/haskell-ci # # version: 0.5.20180830 # language: c dist: xenial git: # whether to recursively clone submodules submodules: false notifications: irc: channels: - irc.freenode.org#haskell-lens skip_join: true template: - "\"\\x0313lens-aeson\\x03/\\x0306%{branch}\\x03 \\x0314%{commit}\\x03 %{build_url} %{message}\"" cache: directories: - $HOME/.cabal/packages - $HOME/.cabal/store before_cache: - rm -fv $CABALHOME/packages/hackage.haskell.org/build-reports.log # remove files that are regenerated by 'cabal update' - rm -fv $CABALHOME/packages/hackage.haskell.org/00-index.* - rm -fv $CABALHOME/packages/hackage.haskell.org/*.json - rm -fv $CABALHOME/packages/hackage.haskell.org/01-index.cache - rm -fv $CABALHOME/packages/hackage.haskell.org/01-index.tar - rm -fv $CABALHOME/packages/hackage.haskell.org/01-index.tar.idx - rm -rfv $CABALHOME/packages/head.hackage matrix: include: - compiler: ghc-8.8.1 addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.8.1","cabal-install-3.0"]}} - compiler: ghc-8.6.5 addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.6.5","cabal-install-3.0"]}} - compiler: ghc-8.4.4 addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.4.4","cabal-install-3.0"]}} - compiler: ghc-8.2.2 addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.2.2","cabal-install-3.0"]}} - compiler: ghc-8.0.2 addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-8.0.2","cabal-install-3.0"]}} - compiler: ghc-7.10.3 addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.10.3","cabal-install-3.0"]}} - compiler: ghc-7.8.4 addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.8.4","cabal-install-3.0"]}} - compiler: ghc-7.6.3 addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.6.3","cabal-install-3.0"]}} - compiler: ghc-7.4.2 addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-7.4.2","cabal-install-3.0"]}} - compiler: ghc-head addons: {"apt":{"sources":["hvr-ghc"],"packages":["ghc-head","cabal-install-head"]}} allow_failures: - compiler: ghc-head before_install: - HC=$(echo "/opt/$CC/bin/ghc" | sed 's/-/\//') - WITHCOMPILER="-w $HC" - HADDOCK=$(echo "/opt/$CC/bin/haddock" | sed 's/-/\//') - HCPKG="$HC-pkg" - unset CC - CABAL=/opt/ghc/bin/cabal - CABALHOME=$HOME/.cabal - export PATH="$CABALHOME/bin:$PATH" - TOP=$(pwd) - "HCNUMVER=$(${HC} --numeric-version|perl -ne '/^(\\d+)\\.(\\d+)\\.(\\d+)(\\.(\\d+))?$/; print(10000 * $1 + 100 * $2 + ($3 == 0 ? $5 != 1 : $3))')" - echo $HCNUMVER - CABAL="$CABAL -vnormal+nowrap+markoutput" - set -o pipefail - | echo 'function blue(s) { printf "\033[0;34m" s "\033[0m " }' >> .colorful.awk echo 'BEGIN { state = "output"; }' >> .colorful.awk echo '/^-----BEGIN CABAL OUTPUT-----$/ { state = "cabal" }' >> .colorful.awk echo '/^-----END CABAL OUTPUT-----$/ { state = "output" }' >> .colorful.awk echo '!/^(-----BEGIN CABAL OUTPUT-----|-----END CABAL OUTPUT-----)/ {' >> .colorful.awk echo ' if (state == "cabal") {' >> .colorful.awk echo ' print blue($0)' >> .colorful.awk echo ' } else {' >> .colorful.awk echo ' print $0' >> .colorful.awk echo ' }' >> .colorful.awk echo '}' >> .colorful.awk - cat .colorful.awk - | color_cabal_output () { awk -f $TOP/.colorful.awk } - echo text | color_cabal_output install: - ${CABAL} --version - echo "$(${HC} --version) [$(${HC} --print-project-git-commit-id 2> /dev/null || echo '?')]" - TEST=--enable-tests - BENCH=--enable-benchmarks - HEADHACKAGE=false - if [ $HCNUMVER -gt 80801 ] ; then HEADHACKAGE=true ; fi - rm -f $CABALHOME/config - | echo "verbose: normal +nowrap +markoutput" >> $CABALHOME/config echo "remote-build-reporting: anonymous" >> $CABALHOME/config echo "write-ghc-environment-files: always" >> $CABALHOME/config echo "remote-repo-cache: $CABALHOME/packages" >> $CABALHOME/config echo "logs-dir: $CABALHOME/logs" >> $CABALHOME/config echo "world-file: $CABALHOME/world" >> $CABALHOME/config echo "extra-prog-path: $CABALHOME/bin" >> $CABALHOME/config echo "symlink-bindir: $CABALHOME/bin" >> $CABALHOME/config echo "installdir: $CABALHOME/bin" >> $CABALHOME/config echo "build-summary: $CABALHOME/logs/build.log" >> $CABALHOME/config echo "store-dir: $CABALHOME/store" >> $CABALHOME/config echo "install-dirs user" >> $CABALHOME/config echo " prefix: $CABALHOME" >> $CABALHOME/config echo "repository hackage.haskell.org" >> $CABALHOME/config echo " url: http://hackage.haskell.org/" >> $CABALHOME/config - | if $HEADHACKAGE; then echo "allow-newer: $($HCPKG list --simple-output | sed -E 's/([a-zA-Z-]+)-[0-9.]+/*:\1/g')" >> $CABALHOME/config echo "repository head.hackage.ghc.haskell.org" >> $CABALHOME/config echo " url: https://ghc.gitlab.haskell.org/head.hackage/" >> $CABALHOME/config echo " secure: True" >> $CABALHOME/config echo " root-keys: 7541f32a4ccca4f97aea3b22f5e593ba2c0267546016b992dfadcd2fe944e55d" >> $CABALHOME/config echo " 26021a13b401500c8eb2761ca95c61f2d625bfef951b939a8124ed12ecf07329" >> $CABALHOME/config echo " f76d08be13e9a61a377a85e2fb63f4c5435d40f8feb3e12eb05905edb8cdea89" >> $CABALHOME/config echo " key-threshold: 3" >> $CABALHOME/config fi - cat $CABALHOME/config - rm -fv cabal.project cabal.project.local cabal.project.freeze - travis_retry ${CABAL} v2-update -v - if [ $HCNUMVER -ge 80800 ] && [ $HCNUMVER -lt 80802 ] ; then (cd /tmp && ${CABAL} v2-install $WITHCOMPILER -j2 hlint --constraint='hlint ==2.1.*' | color_cabal_output) ; fi # Generate cabal.project - rm -rf cabal.project cabal.project.local cabal.project.freeze - touch cabal.project - | echo "packages: ." >> cabal.project - | - "for pkg in $($HCPKG list --simple-output); do echo $pkg | sed 's/-[^-]*$//' | (grep -vE -- '^(lens-aeson)$' || true) | sed 's/^/constraints: /' | sed 's/$/ installed/' >> cabal.project.local; done" - cat cabal.project || true - cat cabal.project.local || true - if [ -f "./configure.ac" ]; then (cd "." && autoreconf -i); fi - ${CABAL} v2-freeze $WITHCOMPILER ${TEST} ${BENCH} | color_cabal_output - "cat cabal.project.freeze | sed -E 's/^(constraints: *| *)//' | sed 's/any.//'" - rm cabal.project.freeze - ${CABAL} v2-build $WITHCOMPILER ${TEST} ${BENCH} --dep -j2 all | color_cabal_output script: - DISTDIR=$(mktemp -d /tmp/dist-test.XXXX) # Packaging... - ${CABAL} v2-sdist all | color_cabal_output # Unpacking... - mv dist-newstyle/sdist/*.tar.gz ${DISTDIR}/ - cd ${DISTDIR} || false - find . -maxdepth 1 -type f -name '*.tar.gz' -exec tar -xvf '{}' \; - find . -maxdepth 1 -type f -name '*.tar.gz' -exec rm '{}' \; - PKGDIR_lens_aeson="$(find . -maxdepth 1 -type d -regex '.*/lens-aeson-[0-9.]*')" # Generate cabal.project - rm -rf cabal.project cabal.project.local cabal.project.freeze - touch cabal.project - | echo "packages: ${PKGDIR_lens_aeson}" >> cabal.project - | - "for pkg in $($HCPKG list --simple-output); do echo $pkg | sed 's/-[^-]*$//' | (grep -vE -- '^(lens-aeson)$' || true) | sed 's/^/constraints: /' | sed 's/$/ installed/' >> cabal.project.local; done" - cat cabal.project || true - cat cabal.project.local || true # Building with tests and benchmarks... # build & run tests, build benchmarks - ${CABAL} v2-build $WITHCOMPILER ${TEST} ${BENCH} all | color_cabal_output # Testing... - ${CABAL} v2-test $WITHCOMPILER ${TEST} ${BENCH} all | color_cabal_output # HLint.. - if [ $HCNUMVER -ge 80800 ] && [ $HCNUMVER -lt 80802 ] ; then (cd ${PKGDIR_lens_aeson} && hlint --cpp-ansi --cpp-define=HLINT src) ; fi # cabal check... - (cd ${PKGDIR_lens_aeson} && ${CABAL} -vnormal check) # haddock... - ${CABAL} v2-haddock $WITHCOMPILER --with-haddock $HADDOCK ${TEST} ${BENCH} all | color_cabal_output # REGENDATA ["--output=.travis.yml","--config=cabal.haskell-ci","cabal.project"] # EOF lens-aeson-1.1/.vim.custom0000755000000000000000000000137707346545000013730 0ustar0000000000000000" Add the following to your .vimrc to automatically load this on startup " if filereadable(".vim.custom") " so .vim.custom " endif function StripTrailingWhitespace() let myline=line(".") let mycolumn = col(".") silent %s/ *$// call cursor(myline, mycolumn) endfunction " enable syntax highlighting syntax on " search for the tags file anywhere between here and / set tags=TAGS;/ " highlight tabs and trailing spaces set listchars=tab:‗‗,trail:‗ set list " f2 runs hasktags map :exec ":!hasktags -x -c --ignore src" " strip trailing whitespace before saving " au BufWritePre *.hs,*.markdown silent! cal StripTrailingWhitespace() " rebuild hasktags after saving au BufWritePost *.hs silent! :exec ":!hasktags -x -c --ignore src" lens-aeson-1.1/AUTHORS.markdown0000755000000000000000000000125207346545000014504 0ustar0000000000000000This project was started by Paul Wilson [@statusfailed](https://github.com/statusfailed). Edward Kmett stole it and decided he was going to polish it up and put it on hackage. In the process he took all sorts of liberties with the structure of the project. If you don't like the result, it is probably his fault. * [Edward Kmett](mailto:ekmett@gmail.com) [@ekmett](https://github.com/ekmett) You can watch contributors carry on the quest for bragging rights in the [contributors graph](https://github.com/analytics/compensated/graphs/contributors). Omission from this list is by no means an attempt to discount your contribution. Thank you for all of your help! -Edward Kmett lens-aeson-1.1/CHANGELOG.markdown0000755000000000000000000000161607346545000014652 0ustar00000000000000001.1 [2019.09.26] ---------------- * Generalize the type of `_JSON` from `Prism' t a` to `Prism t t a b`. If you wish to continue to use the less general type, use the newly added `_JSON'` prism. * Add pattern synonyms corresponding to the `Prism`s that `lens-aeson` provides. * Fix the test suite on 32-bit architectures. 1.0.2 ----- * Support `doctest-0.12` 1.0.1 ----- * Revamp `Setup.hs` to use `cabal-doctest`. This makes it build with `Cabal-2.0`, and makes the `doctest`s work with `cabal new-build` and sandboxes. 1.0.0.5 ---- * Fix tests to work against vector-0.11 * Documentation fixes * No functional changes since 1.0.0.4 1.0.0.3 ---- * Move lens upper bound to < 5 like the other packages in the family 1 ---- * Module migrated from lens package to Data.Aeson.Lens 0.1.2 ----- * Added `members` and `values` 0.1.1 ----- * Broadened dependencies 0.1 --- * Repository initialized lens-aeson-1.1/LICENSE0000644000000000000000000000203707346545000012617 0ustar0000000000000000Copyright (C) 2013 Paul Wilson Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. lens-aeson-1.1/README.markdown0000755000000000000000000000116007346545000014312 0ustar0000000000000000lens-aeson ========== [![Hackage](https://img.shields.io/hackage/v/lens-aeson.svg)](https://hackage.haskell.org/package/lens-aeson) [![Build Status](https://secure.travis-ci.org/lens/lens-aeson.svg)](http://travis-ci.org/lens/lens-aeson) The goal of `lens-aeson` is to provide traversals and prisms for the [Aeson](http://hackage.haskell.org/package/aeson) library's Value type, while obeying the `Traversal`/`Prism` laws. Contact Information ------------------- Contributions and bug reports are welcome! Please feel free to contact me through github or on the #haskell IRC channel on irc.freenode.net. -Edward Kmett lens-aeson-1.1/Setup.lhs0000644000000000000000000000124107346545000013416 0ustar0000000000000000\begin{code} {-# LANGUAGE CPP #-} {-# OPTIONS_GHC -Wall #-} module Main (main) where #ifndef MIN_VERSION_cabal_doctest #define MIN_VERSION_cabal_doctest(x,y,z) 0 #endif #if MIN_VERSION_cabal_doctest(1,0,0) import Distribution.Extra.Doctest ( defaultMainWithDoctests ) main :: IO () main = defaultMainWithDoctests "doctests" #else #ifdef MIN_VERSION_Cabal -- If the macro is defined, we have new cabal-install, -- but for some reason we don't have cabal-doctest in package-db -- -- Probably we are running cabal sdist, when otherwise using new-build -- workflow import Warning () #endif import Distribution.Simple main :: IO () main = defaultMain #endif \end{code} lens-aeson-1.1/Warning.hs0000755000000000000000000000040007346545000013546 0ustar0000000000000000module Warning {-# WARNING ["You are configuring this package without cabal-doctest installed.", "The doctests test-suite will not work as a result.", "To fix this, install cabal-doctest before configuring."] #-} () where lens-aeson-1.1/lens-aeson.cabal0000644000000000000000000000424207346545000014642 0ustar0000000000000000name: lens-aeson category: Numeric version: 1.1 license: MIT cabal-version: >= 1.8 license-file: LICENSE author: Edward A. Kmett maintainer: Edward A. Kmett stability: provisional homepage: http://github.com/lens/lens-aeson/ bug-reports: http://github.com/lens/lens-aeson/issues copyright: Copyright (C) 2012 Paul Wilson Copyright (C) 2013 Edward A. Kmett build-type: Custom tested-with: GHC == 7.4.2 , GHC == 7.6.3 , GHC == 7.8.4 , GHC == 7.10.3 , GHC == 8.0.2 , GHC == 8.2.2 , GHC == 8.4.4 , GHC == 8.6.5 , GHC == 8.8.1 synopsis: Law-abiding lenses for aeson description: Law-abiding lenses for aeson. extra-source-files: .travis.yml .ghci .gitignore .vim.custom travis/cabal-apt-install travis/config AUTHORS.markdown README.markdown CHANGELOG.markdown Warning.hs source-repository head type: git location: https://github.com/lens/lens-aeson custom-setup setup-depends: base >= 4 && < 5, Cabal, cabal-doctest >= 1 && < 1.1 -- You can disable the doctests test suite with -f-test-doctests flag test-doctests default: True manual: True library build-depends: base >= 4.5 && < 5, lens >= 4.4 && < 5, text >= 0.11.1.10 && < 1.3, vector >= 0.9 && < 0.13, unordered-containers >= 0.2.3 && < 0.3, attoparsec >= 0.10 && < 0.14, bytestring >= 0.9 && < 0.11, aeson >= 0.7.0.5 && < 1.5, scientific >= 0.3.2 && < 0.4 exposed-modules: Data.Aeson.Lens ghc-options: -Wall -fwarn-tabs -O2 hs-source-dirs: src test-suite doctests type: exitcode-stdio-1.0 main-is: doctests.hs ghc-options: -Wall -threaded hs-source-dirs: tests if !flag(test-doctests) buildable: False else build-depends: base, doctest >= 0.11.1 && < 0.17, generic-deriving, lens-aeson, semigroups >= 0.9, simple-reflect >= 0.3.1 lens-aeson-1.1/src/Data/Aeson/0000755000000000000000000000000007346545000014315 5ustar0000000000000000lens-aeson-1.1/src/Data/Aeson/Lens.hs0000644000000000000000000003534107346545000015560 0ustar0000000000000000{-# LANGUAGE CPP #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE Trustworthy #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE DefaultSignatures #-} {-# OPTIONS_GHC -fno-warn-orphans #-} #if __GLASGOW_HASKELL__ >= 800 {-# LANGUAGE PatternSynonyms #-} {-# LANGUAGE ViewPatterns #-} #endif -------------------------------------------------------------------- -- | -- Copyright : (c) Edward Kmett 2013-2019, (c) Paul Wilson 2012 -- License : BSD3 -- Maintainer: Edward Kmett -- Stability : experimental -- Portability: non-portable -- -- This module also exports orphan @'Ixed' 'Value'@ and -- @'Plated' 'Value'@ instances. -------------------------------------------------------------------- module Data.Aeson.Lens ( -- * Numbers AsNumber(..) , _Integral , nonNull -- * Primitive , Primitive(..) , AsPrimitive(..) -- * Objects and Arrays , AsValue(..) , key, members , nth, values -- * Decoding , AsJSON(..) , _JSON' -- * Pattern Synonyms #if __GLASGOW_HASKELL__ >= 800 , pattern JSON , pattern Value_ , pattern Number_ , pattern Double , pattern Integer , pattern Integral , pattern Primitive , pattern Bool_ , pattern String_ , pattern Null_ #endif ) where import Control.Applicative import Control.Lens import Data.Aeson import Data.Aeson.Parser (value) import Data.Attoparsec.ByteString.Lazy (maybeResult, parse) import Data.Scientific (Scientific) import qualified Data.Scientific as Scientific import qualified Data.ByteString as Strict import Data.ByteString.Lazy.Char8 as Lazy hiding (putStrLn) import Data.Data import Data.HashMap.Strict (HashMap) import Data.Text as Text import qualified Data.Text.Lazy as LazyText import Data.Text.Lens (packed) import qualified Data.Text.Encoding as StrictText import qualified Data.Text.Lazy.Encoding as LazyText import Data.Vector (Vector) import Prelude hiding (null) -- $setup -- >>> import Data.ByteString.Char8 as Strict.Char8 -- >>> import qualified Data.Vector as Vector -- >>> :set -XOverloadedStrings ------------------------------------------------------------------------------ -- Scientific prisms ------------------------------------------------------------------------------ class AsNumber t where -- | -- >>> "[1, \"x\"]" ^? nth 0 . _Number -- Just 1.0 -- -- >>> "[1, \"x\"]" ^? nth 1 . _Number -- Nothing _Number :: Prism' t Scientific default _Number :: AsPrimitive t => Prism' t Scientific _Number = _Primitive._Number {-# INLINE _Number #-} -- | -- Prism into an 'Double' over a 'Value', 'Primitive' or 'Scientific' -- -- >>> "[10.2]" ^? nth 0 . _Double -- Just 10.2 _Double :: Prism' t Double _Double = _Number.iso Scientific.toRealFloat realToFrac {-# INLINE _Double #-} -- | -- Prism into an 'Integer' over a 'Value', 'Primitive' or 'Scientific' -- -- >>> "[10]" ^? nth 0 . _Integer -- Just 10 -- -- >>> "[10.5]" ^? nth 0 . _Integer -- Just 10 -- -- >>> "42" ^? _Integer -- Just 42 _Integer :: Prism' t Integer _Integer = _Number.iso floor fromIntegral {-# INLINE _Integer #-} instance AsNumber Value where _Number = prism Number $ \v -> case v of Number n -> Right n; _ -> Left v {-# INLINE _Number #-} instance AsNumber Scientific where _Number = id {-# INLINE _Number #-} instance AsNumber Strict.ByteString instance AsNumber Lazy.ByteString instance AsNumber Text instance AsNumber LazyText.Text instance AsNumber String ------------------------------------------------------------------------------ -- Conversion Prisms ------------------------------------------------------------------------------ -- | Access Integer 'Value's as Integrals. -- -- >>> "[10]" ^? nth 0 . _Integral -- Just 10 -- -- >>> "[10.5]" ^? nth 0 . _Integral -- Just 10 _Integral :: (AsNumber t, Integral a) => Prism' t a _Integral = _Number . iso floor fromIntegral {-# INLINE _Integral #-} ------------------------------------------------------------------------------ -- Null values and primitives ------------------------------------------------------------------------------ -- | Primitives of 'Value' data Primitive = StringPrim !Text | NumberPrim !Scientific | BoolPrim !Bool | NullPrim deriving (Eq,Ord,Show,Data,Typeable) instance AsNumber Primitive where _Number = prism NumberPrim $ \v -> case v of NumberPrim s -> Right s; _ -> Left v {-# INLINE _Number #-} class AsNumber t => AsPrimitive t where -- | -- >>> "[1, \"x\", null, true, false]" ^? nth 0 . _Primitive -- Just (NumberPrim 1.0) -- -- >>> "[1, \"x\", null, true, false]" ^? nth 1 . _Primitive -- Just (StringPrim "x") -- -- >>> "[1, \"x\", null, true, false]" ^? nth 2 . _Primitive -- Just NullPrim -- -- >>> "[1, \"x\", null, true, false]" ^? nth 3 . _Primitive -- Just (BoolPrim True) -- -- >>> "[1, \"x\", null, true, false]" ^? nth 4 . _Primitive -- Just (BoolPrim False) _Primitive :: Prism' t Primitive default _Primitive :: AsValue t => Prism' t Primitive _Primitive = _Value._Primitive {-# INLINE _Primitive #-} -- | -- >>> "{\"a\": \"xyz\", \"b\": true}" ^? key "a" . _String -- Just "xyz" -- -- >>> "{\"a\": \"xyz\", \"b\": true}" ^? key "b" . _String -- Nothing -- -- >>> _Object._Wrapped # [("key" :: Text, _String # "value")] :: String -- "{\"key\":\"value\"}" _String :: Prism' t Text _String = _Primitive.prism StringPrim (\v -> case v of StringPrim s -> Right s; _ -> Left v) {-# INLINE _String #-} -- | -- >>> "{\"a\": \"xyz\", \"b\": true}" ^? key "b" . _Bool -- Just True -- -- >>> "{\"a\": \"xyz\", \"b\": true}" ^? key "a" . _Bool -- Nothing -- -- >>> _Bool # True :: String -- "true" -- -- >>> _Bool # False :: String -- "false" _Bool :: Prism' t Bool _Bool = _Primitive.prism BoolPrim (\v -> case v of BoolPrim b -> Right b; _ -> Left v) {-# INLINE _Bool #-} -- | -- >>> "{\"a\": \"xyz\", \"b\": null}" ^? key "b" . _Null -- Just () -- -- >>> "{\"a\": \"xyz\", \"b\": null}" ^? key "a" . _Null -- Nothing -- -- >>> _Null # () :: String -- "null" _Null :: Prism' t () _Null = _Primitive.prism (const NullPrim) (\v -> case v of NullPrim -> Right (); _ -> Left v) {-# INLINE _Null #-} instance AsPrimitive Value where _Primitive = prism fromPrim toPrim where toPrim (String s) = Right $ StringPrim s toPrim (Number n) = Right $ NumberPrim n toPrim (Bool b) = Right $ BoolPrim b toPrim Null = Right NullPrim toPrim v = Left v {-# INLINE toPrim #-} fromPrim (StringPrim s) = String s fromPrim (NumberPrim n) = Number n fromPrim (BoolPrim b) = Bool b fromPrim NullPrim = Null {-# INLINE fromPrim #-} {-# INLINE _Primitive #-} _String = prism String $ \v -> case v of String s -> Right s; _ -> Left v {-# INLINE _String #-} _Bool = prism Bool (\v -> case v of Bool b -> Right b; _ -> Left v) {-# INLINE _Bool #-} _Null = prism (const Null) (\v -> case v of Null -> Right (); _ -> Left v) {-# INLINE _Null #-} instance AsPrimitive Strict.ByteString instance AsPrimitive Lazy.ByteString instance AsPrimitive Text.Text instance AsPrimitive LazyText.Text instance AsPrimitive String instance AsPrimitive Primitive where _Primitive = id {-# INLINE _Primitive #-} -- | Prism into non-'Null' values -- -- >>> "{\"a\": \"xyz\", \"b\": null}" ^? key "a" . nonNull -- Just (String "xyz") -- -- >>> "{\"a\": {}, \"b\": null}" ^? key "a" . nonNull -- Just (Object (fromList [])) -- -- >>> "{\"a\": \"xyz\", \"b\": null}" ^? key "b" . nonNull -- Nothing nonNull :: Prism' Value Value nonNull = prism id (\v -> if isn't _Null v then Right v else Left v) {-# INLINE nonNull #-} ------------------------------------------------------------------------------ -- Non-primitive traversals ------------------------------------------------------------------------------ class AsPrimitive t => AsValue t where -- | -- >>> preview _Value "[1,2,3]" == Just (Array (Vector.fromList [Number 1.0,Number 2.0,Number 3.0])) -- True _Value :: Prism' t Value -- | -- >>> "{\"a\": {}, \"b\": null}" ^? key "a" . _Object -- Just (fromList []) -- -- >>> "{\"a\": {}, \"b\": null}" ^? key "b" . _Object -- Nothing -- -- >>> _Object._Wrapped # [("key" :: Text, _String # "value")] :: String -- "{\"key\":\"value\"}" _Object :: Prism' t (HashMap Text Value) _Object = _Value.prism Object (\v -> case v of Object o -> Right o; _ -> Left v) {-# INLINE _Object #-} -- | -- >>> preview _Array "[1,2,3]" == Just (Vector.fromList [Number 1.0,Number 2.0,Number 3.0]) -- True _Array :: Prism' t (Vector Value) _Array = _Value.prism Array (\v -> case v of Array a -> Right a; _ -> Left v) {-# INLINE _Array #-} instance AsValue Value where _Value = id {-# INLINE _Value #-} instance AsValue Strict.ByteString where _Value = _JSON {-# INLINE _Value #-} instance AsValue Lazy.ByteString where _Value = _JSON {-# INLINE _Value #-} instance AsValue String where _Value = strictUtf8._JSON {-# INLINE _Value #-} instance AsValue Text where _Value = strictTextUtf8._JSON {-# INLINE _Value #-} instance AsValue LazyText.Text where _Value = lazyTextUtf8._JSON {-# INLINE _Value #-} -- | -- Like 'ix', but for 'Object' with Text indices. This often has better -- inference than 'ix' when used with OverloadedStrings. -- -- >>> "{\"a\": 100, \"b\": 200}" ^? key "a" -- Just (Number 100.0) -- -- >>> "[1,2,3]" ^? key "a" -- Nothing key :: AsValue t => Text -> Traversal' t Value key i = _Object . ix i {-# INLINE key #-} -- | An indexed Traversal into Object properties -- -- >>> Data.List.sort ("{\"a\": 4, \"b\": 7}" ^@.. members . _Number) -- [("a",4.0),("b",7.0)] -- -- >>> "{\"a\": 4}" & members . _Number *~ 10 -- "{\"a\":40}" members :: AsValue t => IndexedTraversal' Text t Value members = _Object . itraversed {-# INLINE members #-} -- | Like 'ix', but for Arrays with Int indexes -- -- >>> "[1,2,3]" ^? nth 1 -- Just (Number 2.0) -- -- >>> "{\"a\": 100, \"b\": 200}" ^? nth 1 -- Nothing -- -- >>> "[1,2,3]" & nth 1 .~ Number 20 -- "[1,20,3]" nth :: AsValue t => Int -> Traversal' t Value nth i = _Array . ix i {-# INLINE nth #-} -- | An indexed Traversal into Array elements -- -- >>> "[1,2,3]" ^.. values -- [Number 1.0,Number 2.0,Number 3.0] -- -- >>> "[1,2,3]" & values . _Number *~ 10 -- "[10,20,30]" values :: AsValue t => IndexedTraversal' Int t Value values = _Array . traversed {-# INLINE values #-} strictUtf8 :: Iso' String Strict.ByteString strictUtf8 = packed . strictTextUtf8 strictTextUtf8 :: Iso' Text.Text Strict.ByteString strictTextUtf8 = iso StrictText.encodeUtf8 StrictText.decodeUtf8 lazyTextUtf8 :: Iso' LazyText.Text Lazy.ByteString lazyTextUtf8 = iso LazyText.encodeUtf8 LazyText.decodeUtf8 _JSON' :: (AsJSON t, FromJSON a, ToJSON a) => Prism' t a _JSON' = _JSON class AsJSON t where -- | '_JSON' is a 'Prism' from something containing JSON to something encoded in that structure _JSON :: (FromJSON a, ToJSON b) => Prism t t a b instance AsJSON Strict.ByteString where _JSON = lazy._JSON {-# INLINE _JSON #-} instance AsJSON Lazy.ByteString where _JSON = prism' encode decodeValue where decodeValue :: (FromJSON a) => Lazy.ByteString -> Maybe a decodeValue s = maybeResult (parse value s) >>= \x -> case fromJSON x of Success v -> Just v _ -> Nothing {-# INLINE _JSON #-} instance AsJSON String where _JSON = strictUtf8._JSON {-# INLINE _JSON #-} instance AsJSON Text where _JSON = strictTextUtf8._JSON {-# INLINE _JSON #-} instance AsJSON LazyText.Text where _JSON = lazyTextUtf8._JSON {-# INLINE _JSON #-} instance AsJSON Value where _JSON = prism toJSON $ \x -> case fromJSON x of Success y -> Right y; _ -> Left x {-# INLINE _JSON #-} ------------------------------------------------------------------------------ -- Some additional tests for prismhood; see https://github.com/ekmett/lens/issues/439. ------------------------------------------------------------------------------ -- $LazyByteStringTests -- >>> "42" ^? (_JSON :: Prism' Lazy.ByteString Value) -- Just (Number 42.0) -- -- >>> preview (_Integer :: Prism' Lazy.ByteString Integer) "42" -- Just 42 -- -- >>> Lazy.unpack (review (_Integer :: Prism' Lazy.ByteString Integer) 42) -- "42" -- $StrictByteStringTests -- >>> "42" ^? (_JSON :: Prism' Strict.ByteString Value) -- Just (Number 42.0) -- -- >>> preview (_Integer :: Prism' Strict.ByteString Integer) "42" -- Just 42 -- -- >>> Strict.Char8.unpack (review (_Integer :: Prism' Strict.ByteString Integer) 42) -- "42" -- $StringTests -- >>> "42" ^? (_JSON :: Prism' String Value) -- Just (Number 42.0) -- -- >>> preview (_Integer :: Prism' String Integer) "42" -- Just 42 -- -- >>> review (_Integer :: Prism' String Integer) 42 -- "42" ------------------------------------------------------------------------------ -- Orphan instances for lens library interop ------------------------------------------------------------------------------ type instance Index Value = Text type instance IxValue Value = Value instance Ixed Value where ix i f (Object o) = Object <$> ix i f o ix _ _ v = pure v {-# INLINE ix #-} instance Plated Value where plate f (Object o) = Object <$> traverse f o plate f (Array a) = Array <$> traverse f a plate _ xs = pure xs {-# INLINE plate #-} ------------------------------------------------------------------------------ -- Pattern Synonyms ------------------------------------------------------------------------------ #if __GLASGOW_HASKELL__ >= 800 pattern JSON :: (FromJSON a, ToJSON a, AsJSON t) => () => a -> t pattern JSON a <- (preview _JSON -> Just a) where JSON a = _JSON # a pattern Value_ :: (FromJSON a, ToJSON a) => () => a -> Value pattern Value_ a <- (fromJSON -> Success a) where Value_ a = toJSON a pattern Number_ :: AsNumber t => Scientific -> t pattern Number_ n <- (preview _Number -> Just n) where Number_ n = _Number # n pattern Double :: AsNumber t => Double -> t pattern Double d <- (preview _Double -> Just d) where Double d = _Double # d pattern Integer :: AsNumber t => Integer -> t pattern Integer i <- (preview _Integer -> Just i) where Integer i = _Integer # i pattern Integral :: (AsNumber t, Integral a) => a -> t pattern Integral d <- (preview _Integral -> Just d) where Integral d = _Integral # d pattern Primitive :: AsPrimitive t => Primitive -> t pattern Primitive p <- (preview _Primitive -> Just p) where Primitive p = _Primitive # p pattern Bool_ :: AsPrimitive t => Bool -> t pattern Bool_ b <- (preview _Bool -> Just b) where Bool_ b = _Bool # b pattern String_ :: AsPrimitive t => Text -> t pattern String_ p <- (preview _String -> Just p) where String_ p = _String # p pattern Null_ :: AsPrimitive t => t pattern Null_ <- (preview _Null -> Just ()) where Null_ = _Null # () #endif lens-aeson-1.1/tests/0000755000000000000000000000000007346545000012752 5ustar0000000000000000lens-aeson-1.1/tests/doctests.hs0000644000000000000000000000147207346545000015142 0ustar0000000000000000----------------------------------------------------------------------------- -- | -- Module : Main (doctests) -- Copyright : (C) 2012-14 Edward Kmett -- License : BSD-style (see the file LICENSE) -- Maintainer : Edward Kmett -- Stability : provisional -- Portability : portable -- -- This module provides doctests for a project based on the actual versions -- of the packages it was built with. It requires a corresponding Setup.lhs -- to be added to the project ----------------------------------------------------------------------------- module Main where import Build_doctests (flags, pkgs, module_sources) import Data.Foldable (traverse_) import Test.DocTest main :: IO () main = do traverse_ putStrLn args doctest args where args = flags ++ pkgs ++ module_sources lens-aeson-1.1/travis/0000755000000000000000000000000007346545000013120 5ustar0000000000000000lens-aeson-1.1/travis/cabal-apt-install0000755000000000000000000000127207346545000016340 0ustar0000000000000000#! /bin/bash set -eu APT="sudo apt-get -q -y" CABAL_INSTALL_DEPS="cabal install --only-dependencies --force-reinstall" $APT update $APT install dctrl-tools # Find potential system packages to satisfy cabal dependencies deps() { local M='^\([^ ]\+\)-[0-9.]\+ (.*$' local G=' -o ( -FPackage -X libghc-\L\1\E-dev )' local E="$($CABAL_INSTALL_DEPS "$@" --dry-run -v 2> /dev/null \ | sed -ne "s/$M/$G/p" | sort -u)" grep-aptavail -n -sPackage \( -FNone -X None \) $E | sort -u } $APT install $(deps "$@") libghc-quickcheck2-dev # QuickCheck is special $CABAL_INSTALL_DEPS "$@" # Install the rest via Hackage if ! $APT install hlint ; then $APT install $(deps hlint) cabal install hlint fi lens-aeson-1.1/travis/config0000755000000000000000000000120607346545000014312 0ustar0000000000000000-- This provides a custom ~/.cabal/config file for use when hackage is down that should work on unix -- -- This is particularly useful for travis-ci to get it to stop complaining -- about a broken build when everything is still correct on our end. -- -- This uses Luite Stegeman's mirror of hackage provided by his 'hdiff' site instead -- -- To enable this, uncomment the before_script in .travis.yml remote-repo: hdiff.luite.com:http://hdiff.luite.com/packages/archive remote-repo-cache: ~/.cabal/packages world-file: ~/.cabal/world build-summary: ~/.cabal/logs/build.log remote-build-reporting: anonymous install-dirs user install-dirs global