aeson-yak 0.1.1.1 → 0.1.1.2
raw patch · 5 files changed
+144/−140 lines, 5 filesdep ~aesonsetup-changed
Dependency ranges changed: aeson
Files
- CHANGELOG +10/−6
- LICENSE +20/−20
- Setup.hs +2/−2
- aeson-yak.cabal +31/−31
- src/Data/Aeson/Yak.hs +81/−81
CHANGELOG view
@@ -1,7 +1,11 @@-0.1.1.0: Eq and Show instances for Lousy. - -0.1.0.2: Get CHANGELOG into the tarball. - -0.1.0.1: Fix description rendering on Hackage. - +0.1.1.2: Eliminate upper bounds on Aeson++0.1.1.1: Bump upper bounds on Aeson++0.1.1.0: Eq and Show instances for Lousy.++0.1.0.2: Get CHANGELOG into the tarball.++0.1.0.1: Fix description rendering on Hackage.+ 0.1.0.0: Initial release.
LICENSE view
@@ -1,20 +1,20 @@-Copyright (c) 2015 Theodore Lief Gannon - -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. +Copyright (c) 2015 Theodore Lief Gannon++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.
Setup.hs view
@@ -1,2 +1,2 @@-import Distribution.Simple -main = defaultMain +import Distribution.Simple+main = defaultMain
aeson-yak.cabal view
@@ -1,31 +1,31 @@-name: aeson-yak -version: 0.1.1.1 -synopsis: Handle JSON that may or may not be a list, or exist -description: - According to the standard promoted by Schema.org, the same JSON object - field may legally contain an array or a single element, be null, or be - absent entirely. This library provides an intermediary data type and - supporting functions to help aeson parse and output JSON conforming to this - frustrating behavior. - -homepage: https://github.com/tejon/aeson-yak -license: MIT -license-file: LICENSE -author: Theodore Lief Gannon -maintainer: tanuki@gmail.com -copyright: Copyright (c) Theodore Lief Gannon, 2015 -category: Data -build-type: Simple -extra-source-files: CHANGELOG -cabal-version: >=1.10 - -source-repository head - type: git - location: https://github.com/tejon/aeson-yak - -library - exposed-modules: Data.Aeson.Yak - build-depends: base >= 4.8 && < 5 - , aeson >= 0.4 && < 0.12 - hs-source-dirs: src - default-language: Haskell2010 +name: aeson-yak+version: 0.1.1.2+synopsis: Handle JSON that may or may not be a list, or exist+description:+ According to the standard promoted by Schema.org, the same JSON object+ field may legally contain an array or a single element, be null, or be+ absent entirely. This library provides an intermediary data type and+ supporting functions to help aeson parse and output JSON conforming to this+ frustrating behavior.++homepage: https://github.com/tejon/aeson-yak+license: MIT+license-file: LICENSE+author: Theodore Lief Gannon+maintainer: tanuki@gmail.com+copyright: Copyright (c) Theodore Lief Gannon, 2015-2017+category: Data+build-type: Simple+extra-source-files: CHANGELOG+cabal-version: >=1.10++source-repository head+ type: git+ location: https://github.com/tejon/aeson-yak++library+ exposed-modules: Data.Aeson.Yak+ build-depends: base >= 4.8 && < 5+ , aeson >= 0.4+ hs-source-dirs: src+ default-language: Haskell2010
src/Data/Aeson/Yak.hs view
@@ -1,81 +1,81 @@--- | --- There are two ways to use this library: the way with extra boilerplate, --- or the way with a leaky abstraction. A truly good solution would fix it --- all with Template Haskell; but the author is not a truly good Haskeller, --- so this will have to do for now. --- --- The boilerplate way: --- --- @ --- data Hideous = Hideous { yak :: [String] } --- instance ToJSON Hideous where --- toJSON x = object [ "yak" .= hairy (yak x) ] --- instance FromJSON Hideous where --- parseJSON (Object o) = Hideous \<$> (shave \<$> o .:? "yak") --- @ --- >>> encode $ Hideous ["foo","bar"] --- "{\"yak\":[\"foo\",\"bar\"]}" --- >>> encode $ Hideous ["baz"] --- "{\"yak\":\"baz\"}" --- >>> encode $ Hideous [] --- "{\"yak\":null}" --- >>> yak <$> decode "{\"yak\":[\"foo\",\"bar\"]}" --- Just ["foo", "bar"] --- >>> yak <$> decode "{\"yak\":\"baz\"}" --- Just ["baz"] --- >>> yak <$> decode "{}" --- Just [] --- --- The leaky way: --- --- @ --- data Abhorrent = Abhorrent { yak :: Yak String } --- $(deriveJSON defaultOptions{omitNothingFields=True} ''Abhorrent) --- @ --- >>> encode . Abhorrent . hairy $ ["shaven","shorn","sheared"] --- "{\"yak\":[\"shaven\",\"shorn\",\"sheared\"]}" --- >>> shave . yak <$> decode "{}" --- Just [] --- --- Which to prefer depends on how many yaks you need to deal with /vs./ how --- much you hate cleaning up yak droppings in the rest of your codebase. -module Data.Aeson.Yak -( Yak -, hairy -, shave) -where - -import Data.Aeson -import Data.Foldable - --- | Data whose JSON representation may legally be an array, a single element, --- or null\/absent. No, please, calm down. It'll be okay. Mostly. --- --- /('Lousy' is not exposed to avoid namespace infestation./ --- /This is open for discussion if a use case can be shown.)/ -type Yak a = Maybe (Lousy a) - --- | Convert a @'Foldable'@ to a 'Yak'. Should probably be specific to lists, --- but what's life without a little adventure? -hairy :: (Foldable f) => f a -> Yak a -hairy beast = case toList beast of - [] -> Nothing - yak -> Just (Lousy yak) - --- | Convert a 'Yak' to a list. Relax, and allow yourself to breathe. -shave :: Yak a -> [a] -shave Nothing = [] -shave (Just nit) = pick nit - -newtype Lousy a = Lousy { pick :: [a] } deriving (Eq) -instance (Show a) => Show (Lousy a) where - show = ("Lousy " ++) . show . pick - -instance (ToJSON a) => ToJSON (Lousy a) where - toJSON nit = case pick nit of - [x] -> toJSON x - xs -> toJSON xs - -instance (FromJSON a) => FromJSON (Lousy a) where - parseJSON vs@(Array _) = Lousy <$> parseJSON vs - parseJSON v = (\a -> Lousy [a]) <$> parseJSON v +-- |+-- There are two ways to use this library: the way with extra boilerplate,+-- or the way with a leaky abstraction. A truly good solution would fix it+-- all with Template Haskell; but the author is not a truly good Haskeller,+-- so this will have to do for now.+-- +-- The boilerplate way:+-- +-- @+-- data Hideous = Hideous { yak :: [String] }+-- instance ToJSON Hideous where+-- toJSON x = object [ "yak" .= hairy (yak x) ]+-- instance FromJSON Hideous where+-- parseJSON (Object o) = Hideous \<$> (shave \<$> o .:? "yak")+-- @+-- >>> encode $ Hideous ["foo","bar"]+-- "{\"yak\":[\"foo\",\"bar\"]}"+-- >>> encode $ Hideous ["baz"]+-- "{\"yak\":\"baz\"}"+-- >>> encode $ Hideous []+-- "{\"yak\":null}"+-- >>> yak <$> decode "{\"yak\":[\"foo\",\"bar\"]}"+-- Just ["foo", "bar"]+-- >>> yak <$> decode "{\"yak\":\"baz\"}"+-- Just ["baz"]+-- >>> yak <$> decode "{}"+-- Just []+-- +-- The leaky way:+-- +-- @+-- data Abhorrent = Abhorrent { yak :: Yak String }+-- $(deriveJSON defaultOptions{omitNothingFields=True} ''Abhorrent)+-- @+-- >>> encode . Abhorrent . hairy $ ["shaven","shorn","sheared"]+-- "{\"yak\":[\"shaven\",\"shorn\",\"sheared\"]}"+-- >>> shave . yak <$> decode "{}"+-- Just []+-- +-- Which to prefer depends on how many yaks you need to deal with /vs./ how+-- much you hate cleaning up yak droppings in the rest of your codebase.+module Data.Aeson.Yak+( Yak+, hairy+, shave)+where++import Data.Aeson+import Data.Foldable++-- | Data whose JSON representation may legally be an array, a single element,+-- or null\/absent. No, please, calm down. It'll be okay. Mostly.+-- +-- /('Lousy' is not exposed to avoid namespace infestation./+-- /This is open for discussion if a use case can be shown.)/+type Yak a = Maybe (Lousy a)++-- | Convert a @'Foldable'@ to a 'Yak'. Should probably be specific to lists,+-- but what's life without a little adventure?+hairy :: (Foldable f) => f a -> Yak a+hairy beast = case toList beast of+ [] -> Nothing+ yak -> Just (Lousy yak)++-- | Convert a 'Yak' to a list. Relax, and allow yourself to breathe.+shave :: Yak a -> [a]+shave Nothing = []+shave (Just nit) = pick nit++newtype Lousy a = Lousy { pick :: [a] } deriving (Eq)+instance (Show a) => Show (Lousy a) where+ show = ("Lousy " ++) . show . pick++instance (ToJSON a) => ToJSON (Lousy a) where+ toJSON nit = case pick nit of+ [x] -> toJSON x+ xs -> toJSON xs++instance (FromJSON a) => FromJSON (Lousy a) where+ parseJSON vs@(Array _) = Lousy <$> parseJSON vs+ parseJSON v = (\a -> Lousy [a]) <$> parseJSON v