packages feed

argo 0.2021.11.11 → 0.2021.11.13

raw patch · 14 files changed

+370/−440 lines, 14 filesPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

API changes (from Hackage documentation)

- Argo: class FromValue a
- Argo: class ToValue a
- Argo.Class.FromValue: class FromValue a
- Argo.Class.FromValue: instance (Argo.Class.FromValue.FromValue a, Argo.Class.FromValue.FromValue b) => Argo.Class.FromValue.FromValue (a, b)
- Argo.Class.FromValue: instance Argo.Class.FromValue.FromValue ()
- Argo.Class.FromValue: instance Argo.Class.FromValue.FromValue Argo.Json.Value.Value
- Argo.Class.FromValue: instance Argo.Class.FromValue.FromValue Argo.Pointer.Pointer.Pointer
- Argo.Class.FromValue: instance Argo.Class.FromValue.FromValue Argo.Vendor.Text.LazyText
- Argo.Class.FromValue: instance Argo.Class.FromValue.FromValue Data.Text.Internal.Text
- Argo.Class.FromValue: instance Argo.Class.FromValue.FromValue GHC.Base.String
- Argo.Class.FromValue: instance Argo.Class.FromValue.FromValue GHC.Int.Int16
- Argo.Class.FromValue: instance Argo.Class.FromValue.FromValue GHC.Int.Int32
- Argo.Class.FromValue: instance Argo.Class.FromValue.FromValue GHC.Int.Int64
- Argo.Class.FromValue: instance Argo.Class.FromValue.FromValue GHC.Int.Int8
- Argo.Class.FromValue: instance Argo.Class.FromValue.FromValue GHC.Integer.Type.Integer
- Argo.Class.FromValue: instance Argo.Class.FromValue.FromValue GHC.Types.Bool
- Argo.Class.FromValue: instance Argo.Class.FromValue.FromValue GHC.Types.Char
- Argo.Class.FromValue: instance Argo.Class.FromValue.FromValue GHC.Types.Double
- Argo.Class.FromValue: instance Argo.Class.FromValue.FromValue GHC.Types.Float
- Argo.Class.FromValue: instance Argo.Class.FromValue.FromValue GHC.Types.Int
- Argo.Class.FromValue: instance Argo.Class.FromValue.FromValue GHC.Types.Word
- Argo.Class.FromValue: instance Argo.Class.FromValue.FromValue GHC.Word.Word16
- Argo.Class.FromValue: instance Argo.Class.FromValue.FromValue GHC.Word.Word32
- Argo.Class.FromValue: instance Argo.Class.FromValue.FromValue GHC.Word.Word64
- Argo.Class.FromValue: instance Argo.Class.FromValue.FromValue GHC.Word.Word8
- Argo.Class.FromValue: instance Argo.Class.FromValue.FromValue a => Argo.Class.FromValue.FromValue (Data.Map.Internal.Map Data.Text.Internal.Text a)
- Argo.Class.FromValue: instance Argo.Class.FromValue.FromValue a => Argo.Class.FromValue.FromValue (GHC.Base.NonEmpty a)
- Argo.Class.FromValue: instance Argo.Class.FromValue.FromValue a => Argo.Class.FromValue.FromValue (GHC.Maybe.Maybe a)
- Argo.Class.FromValue: instance Argo.Class.FromValue.FromValue a => Argo.Class.FromValue.FromValue [a]
- Argo.Class.FromValue: viaInteger :: (Integral a, Bits a) => Value -> Either String a
- Argo.Class.FromValue: withArray :: String -> ([Value] -> Either String a) -> Value -> Either String a
- Argo.Class.FromValue: withBoolean :: String -> (Bool -> Either String a) -> Value -> Either String a
- Argo.Class.FromValue: withNumber :: String -> (Decimal -> Either String a) -> Value -> Either String a
- Argo.Class.FromValue: withObject :: String -> ([MemberOf Value] -> Either String a) -> Value -> Either String a
- Argo.Class.FromValue: withString :: String -> (Text -> Either String a) -> Value -> Either String a
- Argo.Class.ToValue: class ToValue a
- Argo.Class.ToValue: digitsToDecimal :: [Int] -> Int -> Decimal
- Argo.Class.ToValue: instance (Argo.Class.ToValue.ToValue a, Argo.Class.ToValue.ToValue b) => Argo.Class.ToValue.ToValue (a, b)
- Argo.Class.ToValue: instance Argo.Class.ToValue.ToValue ()
- Argo.Class.ToValue: instance Argo.Class.ToValue.ToValue Argo.Json.Value.Value
- Argo.Class.ToValue: instance Argo.Class.ToValue.ToValue Argo.Pointer.Pointer.Pointer
- Argo.Class.ToValue: instance Argo.Class.ToValue.ToValue Argo.Vendor.Text.LazyText
- Argo.Class.ToValue: instance Argo.Class.ToValue.ToValue Data.Text.Internal.Text
- Argo.Class.ToValue: instance Argo.Class.ToValue.ToValue GHC.Base.String
- Argo.Class.ToValue: instance Argo.Class.ToValue.ToValue GHC.Int.Int16
- Argo.Class.ToValue: instance Argo.Class.ToValue.ToValue GHC.Int.Int32
- Argo.Class.ToValue: instance Argo.Class.ToValue.ToValue GHC.Int.Int64
- Argo.Class.ToValue: instance Argo.Class.ToValue.ToValue GHC.Int.Int8
- Argo.Class.ToValue: instance Argo.Class.ToValue.ToValue GHC.Integer.Type.Integer
- Argo.Class.ToValue: instance Argo.Class.ToValue.ToValue GHC.Types.Bool
- Argo.Class.ToValue: instance Argo.Class.ToValue.ToValue GHC.Types.Char
- Argo.Class.ToValue: instance Argo.Class.ToValue.ToValue GHC.Types.Double
- Argo.Class.ToValue: instance Argo.Class.ToValue.ToValue GHC.Types.Float
- Argo.Class.ToValue: instance Argo.Class.ToValue.ToValue GHC.Types.Int
- Argo.Class.ToValue: instance Argo.Class.ToValue.ToValue GHC.Types.Word
- Argo.Class.ToValue: instance Argo.Class.ToValue.ToValue GHC.Word.Word16
- Argo.Class.ToValue: instance Argo.Class.ToValue.ToValue GHC.Word.Word32
- Argo.Class.ToValue: instance Argo.Class.ToValue.ToValue GHC.Word.Word64
- Argo.Class.ToValue: instance Argo.Class.ToValue.ToValue GHC.Word.Word8
- Argo.Class.ToValue: instance Argo.Class.ToValue.ToValue a => Argo.Class.ToValue.ToValue (Data.Map.Internal.Map Data.Text.Internal.Text a)
- Argo.Class.ToValue: instance Argo.Class.ToValue.ToValue a => Argo.Class.ToValue.ToValue (GHC.Base.NonEmpty a)
- Argo.Class.ToValue: instance Argo.Class.ToValue.ToValue a => Argo.Class.ToValue.ToValue (GHC.Maybe.Maybe a)
- Argo.Class.ToValue: instance Argo.Class.ToValue.ToValue a => Argo.Class.ToValue.ToValue [a]
- Argo.Class.ToValue: realFloatToValue :: RealFloat a => a -> Value
- Argo.Type.Codec: boolCodec :: ValueCodec Bool
- Argo.Type.Codec: booleanCodec :: ValueCodec Boolean
- Argo.Type.Codec: detect :: (a -> Bool) -> [a] -> Maybe (a, [a])
- Argo.Type.Codec: detectWith :: ([a] -> [a]) -> (a -> Bool) -> [a] -> Maybe (a, [a])
- Argo.Type.Codec: eitherCodec :: ValueCodec a -> ValueCodec b -> ValueCodec (Either a b)
- Argo.Type.Codec: mapBoth :: (Functor r, Alternative w) => (o2 -> o1) -> (i1 -> Maybe i2) -> CodecOf r w i2 o2 -> CodecOf r w i1 o1
- Argo.Type.Codec: maybeCodec :: ValueCodec a -> ValueCodec (Maybe a)
- Argo.Type.Codec: nullCodec :: ValueCodec Null
- Argo.Type.Codec: numberCodec :: ValueCodec Number
- Argo.Type.Codec: stringCodec :: ValueCodec String
- Argo.Type.Codec: textCodec :: ValueCodec Text
- Argo.Type.Codec: tupleCodec :: ValueCodec a -> ValueCodec b -> ValueCodec (a, b)
- Argo.Type.Codec: valueCodec :: ValueCodec Value
+ Argo: class HasCodec a
+ Argo: codec :: HasCodec a => ValueCodec a
+ Argo.Class.HasCodec: basicCodec :: String -> (a -> Value) -> (Value -> Maybe a) -> ValueCodec a
+ Argo.Class.HasCodec: castValue :: String -> (Value -> Maybe a) -> ReaderT Value (ExceptT String Identity) a
+ Argo.Class.HasCodec: class HasCodec a
+ Argo.Class.HasCodec: codec :: HasCodec a => ValueCodec a
+ Argo.Class.HasCodec: instance (Argo.Class.HasCodec.HasCodec a, Argo.Class.HasCodec.HasCodec b) => Argo.Class.HasCodec.HasCodec (Data.Either.Either a b)
+ Argo.Class.HasCodec: instance (Argo.Class.HasCodec.HasCodec a, Argo.Class.HasCodec.HasCodec b) => Argo.Class.HasCodec.HasCodec (a, b)
+ Argo.Class.HasCodec: instance Argo.Class.HasCodec.HasCodec ()
+ Argo.Class.HasCodec: instance Argo.Class.HasCodec.HasCodec Argo.Json.Boolean.Boolean
+ Argo.Class.HasCodec: instance Argo.Class.HasCodec.HasCodec Argo.Json.Null.Null
+ Argo.Class.HasCodec: instance Argo.Class.HasCodec.HasCodec Argo.Json.Number.Number
+ Argo.Class.HasCodec: instance Argo.Class.HasCodec.HasCodec Argo.Json.String.String
+ Argo.Class.HasCodec: instance Argo.Class.HasCodec.HasCodec Argo.Json.Value.Value
+ Argo.Class.HasCodec: instance Argo.Class.HasCodec.HasCodec Argo.Pointer.Pointer.Pointer
+ Argo.Class.HasCodec: instance Argo.Class.HasCodec.HasCodec Argo.Type.Decimal.Decimal
+ Argo.Class.HasCodec: instance Argo.Class.HasCodec.HasCodec Argo.Vendor.Text.LazyText
+ Argo.Class.HasCodec: instance Argo.Class.HasCodec.HasCodec Data.Text.Internal.Text
+ Argo.Class.HasCodec: instance Argo.Class.HasCodec.HasCodec GHC.Base.String
+ Argo.Class.HasCodec: instance Argo.Class.HasCodec.HasCodec GHC.Int.Int16
+ Argo.Class.HasCodec: instance Argo.Class.HasCodec.HasCodec GHC.Int.Int32
+ Argo.Class.HasCodec: instance Argo.Class.HasCodec.HasCodec GHC.Int.Int64
+ Argo.Class.HasCodec: instance Argo.Class.HasCodec.HasCodec GHC.Int.Int8
+ Argo.Class.HasCodec: instance Argo.Class.HasCodec.HasCodec GHC.Integer.Type.Integer
+ Argo.Class.HasCodec: instance Argo.Class.HasCodec.HasCodec GHC.Types.Bool
+ Argo.Class.HasCodec: instance Argo.Class.HasCodec.HasCodec GHC.Types.Char
+ Argo.Class.HasCodec: instance Argo.Class.HasCodec.HasCodec GHC.Types.Double
+ Argo.Class.HasCodec: instance Argo.Class.HasCodec.HasCodec GHC.Types.Float
+ Argo.Class.HasCodec: instance Argo.Class.HasCodec.HasCodec GHC.Types.Int
+ Argo.Class.HasCodec: instance Argo.Class.HasCodec.HasCodec GHC.Types.Word
+ Argo.Class.HasCodec: instance Argo.Class.HasCodec.HasCodec GHC.Word.Word16
+ Argo.Class.HasCodec: instance Argo.Class.HasCodec.HasCodec GHC.Word.Word32
+ Argo.Class.HasCodec: instance Argo.Class.HasCodec.HasCodec GHC.Word.Word64
+ Argo.Class.HasCodec: instance Argo.Class.HasCodec.HasCodec GHC.Word.Word8
+ Argo.Class.HasCodec: instance Argo.Class.HasCodec.HasCodec a => Argo.Class.HasCodec.HasCodec (Argo.Json.Array.ArrayOf a)
+ Argo.Class.HasCodec: instance Argo.Class.HasCodec.HasCodec a => Argo.Class.HasCodec.HasCodec (Argo.Json.Object.ObjectOf a)
+ Argo.Class.HasCodec: instance Argo.Class.HasCodec.HasCodec a => Argo.Class.HasCodec.HasCodec (Data.Map.Internal.Map Argo.Json.Name.Name a)
+ Argo.Class.HasCodec: instance Argo.Class.HasCodec.HasCodec a => Argo.Class.HasCodec.HasCodec (GHC.Base.NonEmpty a)
+ Argo.Class.HasCodec: instance Argo.Class.HasCodec.HasCodec a => Argo.Class.HasCodec.HasCodec (GHC.Maybe.Maybe a)
+ Argo.Class.HasCodec: instance Argo.Class.HasCodec.HasCodec a => Argo.Class.HasCodec.HasCodec [a]
+ Argo.Class.HasCodec: typeMismatch :: String -> Value -> String
+ Argo.Json.Member: fromTuple :: (Name, value) -> MemberOf value
+ Argo.Json.Member: toTuple :: MemberOf value -> (Name, value)
+ Argo.Json.Name: instance GHC.Classes.Ord Argo.Json.Name.Name
+ Argo.Json.String: instance GHC.Classes.Ord Argo.Json.String.String
+ Argo.Type.Codec: mapMaybe :: (Alternative r, Alternative w, Monad r, Monad w) => (o2 -> Maybe o1) -> (i1 -> Maybe i2) -> CodecOf r w i2 o2 -> CodecOf r w i1 o1
+ Argo.Type.Codec: tap :: Functor f => (a -> f b) -> a -> f a
+ Argo.Type.Codec: toAlternative :: Alternative m => Maybe a -> m a
+ Argo.Type.Decimal: fromDigits :: [Int] -> Int -> Decimal
+ Argo.Type.Decimal: fromInteger :: Integer -> Decimal
+ Argo.Type.Decimal: fromRealFloat :: RealFloat a => a -> Maybe Decimal
+ Argo.Type.Decimal: toInteger :: Decimal -> Maybe Integer
+ Argo.Type.Decimal: toRealFloat :: RealFloat a => Decimal -> a
- Argo: decode :: FromValue a => ByteString -> Either String a
+ Argo: decode :: HasCodec a => ByteString -> Either String a
- Argo: encode :: ToValue a => a -> Builder
+ Argo: encode :: HasCodec a => a -> Builder
- Argo: encodeWith :: ToValue a => Indent -> a -> Builder
+ Argo: encodeWith :: HasCodec a => Indent -> a -> Builder
- Argo: fromValue :: FromValue a => Value -> Either String a
+ Argo: fromValue :: HasCodec a => Value -> Either String a
- Argo: toValue :: ToValue a => a -> Value
+ Argo: toValue :: HasCodec a => a -> Value
- Argo.Class.FromValue: fromValue :: FromValue a => Value -> Either String a
+ Argo.Class.FromValue: fromValue :: HasCodec a => Value -> Either String a
- Argo.Class.ToValue: toValue :: ToValue a => a -> Value
+ Argo.Class.ToValue: toValue :: HasCodec a => a -> Value
- Argo.Decode: decode :: FromValue a => ByteString -> Either String a
+ Argo.Decode: decode :: HasCodec a => ByteString -> Either String a
- Argo.Encode: encode :: ToValue a => a -> Builder
+ Argo.Encode: encode :: HasCodec a => a -> Builder
- Argo.Encode: encodeWith :: ToValue a => Indent -> a -> Builder
+ Argo.Encode: encodeWith :: HasCodec a => Indent -> a -> Builder

Files

argo.cabal view
@@ -1,7 +1,7 @@ cabal-version: 2.2  name: argo-version: 0.2021.11.11+version: 0.2021.11.13  build-type: Simple category: JSON@@ -68,6 +68,7 @@     exposed-modules:         Argo         Argo.Class.FromValue+        Argo.Class.HasCodec         Argo.Class.ToValue         Argo.Decode         Argo.Encode@@ -100,6 +101,7 @@         Argo.Vendor.Builder         Argo.Vendor.ByteString         Argo.Vendor.DeepSeq+        Argo.Vendor.Map         Argo.Vendor.TemplateHaskell         Argo.Vendor.Text         Argo.Vendor.Transformers
source/library/Argo.hs view
@@ -15,8 +15,9 @@     , Encode.encodeWith     , Indent.Indent(Spaces, Tab)     , Decode.decode-    , FromValue.FromValue(fromValue)-    , ToValue.ToValue(toValue)+    , FromValue.fromValue+    , ToValue.toValue+    , HasCodec.HasCodec(codec)     , QuasiQuoter.value     , QuasiQuoter.pointer     , Pointer.Pointer(Pointer)@@ -28,6 +29,7 @@     ) where  import qualified Argo.Class.FromValue as FromValue+import qualified Argo.Class.HasCodec as HasCodec import qualified Argo.Class.ToValue as ToValue import qualified Argo.Decode as Decode import qualified Argo.Encode as Encode
source/library/Argo/Class/FromValue.hs view
@@ -1,162 +1,8 @@-{-# LANGUAGE FlexibleInstances #-}- module Argo.Class.FromValue where -import qualified Argo.Json.Member as Member+import qualified Argo.Class.HasCodec as HasCodec import qualified Argo.Json.Value as Value-import qualified Argo.Pattern as Pattern-import qualified Argo.Pointer.Pointer as Pointer-import qualified Argo.Type.Decimal as Decimal-import qualified Argo.Type.Decoder as Decoder-import qualified Argo.Vendor.Text as Text-import qualified Data.Bits as Bits-import qualified Data.Int as Int-import qualified Data.List.NonEmpty as NonEmpty-import qualified Data.Map as Map-import qualified Data.Word as Word--class FromValue a where-    fromValue :: Value.Value -> Either String a--instance FromValue Value.Value where-    fromValue = Right--instance FromValue Bool where-    fromValue = withBoolean "Bool" pure--instance FromValue Char where-    fromValue = withString "Char" $ \x -> case Text.uncons x of-        Just (y, z) | Text.null z -> pure y-        _ -> Left $ "expected single character but got " <> show x--instance FromValue Int where-    fromValue = viaInteger--instance FromValue Int.Int8 where-    fromValue = viaInteger--instance FromValue Int.Int16 where-    fromValue = viaInteger--instance FromValue Int.Int32 where-    fromValue = viaInteger--instance FromValue Int.Int64 where-    fromValue = viaInteger--instance FromValue Word where-    fromValue = viaInteger--instance FromValue Word.Word8 where-    fromValue = viaInteger--instance FromValue Word.Word16 where-    fromValue = viaInteger--instance FromValue Word.Word32 where-    fromValue = viaInteger--instance FromValue Word.Word64 where-    fromValue = viaInteger--instance FromValue Integer where-    fromValue = withNumber "Integer" $ \x@(Decimal.Decimal s e) -> if e < 0-        then Left $ "expected integer but got " <> show x-        else pure $ s * 10 ^ e--instance FromValue Float where-    fromValue = withNumber "Float" $ pure . fromRational . Decimal.toRational--instance FromValue Double where-    fromValue = withNumber "Double" $ pure . fromRational . Decimal.toRational--instance {-# OVERLAPPING #-} FromValue String where-    fromValue = fmap Text.unpack . fromValue--instance FromValue Text.Text where-    fromValue = withString "Text" pure--instance FromValue Text.LazyText where-    fromValue = fmap Text.fromStrict . fromValue--instance FromValue a => FromValue (Maybe a) where-    fromValue x = case x of-        Pattern.Null -> pure Nothing-        _ -> Just <$> fromValue x--instance FromValue () where-    fromValue = withArray "()" $ \xs -> case xs of-        [] -> pure ()-        _ -> Left $ "expected empty list but got " <> show xs--instance (FromValue a, FromValue b) => FromValue (a, b) where-    fromValue = withArray "(a, b)" $ \xs -> case xs of-        [x, y] -> (,) <$> fromValue x <*> fromValue y-        _ -> Left $ "expected tuple but got " <> show xs--instance FromValue a => FromValue [a] where-    fromValue = withArray "[a]" $ traverse fromValue--instance FromValue a => FromValue (NonEmpty.NonEmpty a) where-    fromValue value = do-        list <- fromValue value-        case NonEmpty.nonEmpty list of-            Nothing -> Left "unexpected empty list"-            Just nonEmpty -> pure nonEmpty--instance FromValue a => FromValue (Map.Map Text.Text a) where-    fromValue = withObject "Map" $ fmap Map.fromList . traverse-        (\(Member.Member (Pattern.Name k) v) -> (,) k <$> fromValue v)--instance FromValue Pointer.Pointer where-    fromValue =-        withString "Pointer" $ Decoder.run Pointer.decode . Text.encodeUtf8--withBoolean-    :: String -> (Bool -> Either String a) -> Value.Value -> Either String a-withBoolean s f x = case x of-    Pattern.Boolean y -> f y-    _ -> Left $ "expected " <> s <> " but got " <> show x--withNumber-    :: String-    -> (Decimal.Decimal -> Either String a)-    -> Value.Value-    -> Either String a-withNumber s f x = case x of-    Pattern.Number y -> f y-    _ -> Left $ "expected " <> s <> " but got " <> show x--withString-    :: String-    -> (Text.Text -> Either String a)-    -> Value.Value-    -> Either String a-withString s f x = case x of-    Pattern.String y -> f y-    _ -> Left $ "expected " <> s <> " but got " <> show x--withArray-    :: String-    -> ([Value.Value] -> Either String a)-    -> Value.Value-    -> Either String a-withArray s f x = case x of-    Pattern.Array y -> f y-    _ -> Left $ "expected " <> s <> " but got " <> show x--withObject-    :: String-    -> ([Member.MemberOf Value.Value] -> Either String a)-    -> Value.Value-    -> Either String a-withObject s f x = case x of-    Pattern.Object y -> f y-    _ -> Left $ "expected " <> s <> " but got " <> show x+import qualified Argo.Type.Codec as Codec -viaInteger :: (Integral a, Bits.Bits a) => Value.Value -> Either String a-viaInteger value = do-    integer <- fromValue value-    case Bits.toIntegralSized (integer :: Integer) of-        Nothing -> Left $ "integer out of bounds " <> show integer-        Just x -> pure x+fromValue :: HasCodec.HasCodec a => Value.Value -> Either String a+fromValue = Codec.decodeWith HasCodec.codec
+ source/library/Argo/Class/HasCodec.hs view
@@ -0,0 +1,257 @@+{-# LANGUAGE FlexibleInstances #-}++module Argo.Class.HasCodec where++import Control.Applicative ((<|>))++import qualified Argo.Json.Array as Array+import qualified Argo.Json.Boolean as Boolean+import qualified Argo.Json.Member as Member+import qualified Argo.Json.Name as Name+import qualified Argo.Json.Null as Null+import qualified Argo.Json.Number as Number+import qualified Argo.Json.Object as Object+import qualified Argo.Json.String as String+import qualified Argo.Json.Value as Value+import qualified Argo.Pointer.Pointer as Pointer+import qualified Argo.Type.Codec as Codec+import qualified Argo.Type.Config as Config+import qualified Argo.Type.Decimal as Decimal+import qualified Argo.Type.Decoder as Decoder+import qualified Argo.Type.Encoder as Encoder+import qualified Argo.Type.Permission as Permission+import qualified Argo.Vendor.Builder as Builder+import qualified Argo.Vendor.ByteString as ByteString+import qualified Argo.Vendor.Map as Map+import qualified Argo.Vendor.Text as Text+import qualified Argo.Vendor.Transformers as Trans+import qualified Data.Bits as Bits+import qualified Data.Functor.Identity as Identity+import qualified Data.Int as Int+import qualified Data.List.NonEmpty as NonEmpty+import qualified Data.Word as Word++class HasCodec a where+    codec :: Codec.ValueCodec a++instance HasCodec Value.Value where+    codec = Codec.Codec+        { Codec.decode = Trans.ask+        , Codec.encode = Codec.tap $ Trans.lift . Trans.put+        }++instance HasCodec Null.Null where+    codec = basicCodec "Null" Value.Null $ \ value -> case value of+        Value.Null null_ -> Just null_+        _ -> Nothing++instance HasCodec Boolean.Boolean where+    codec = basicCodec "Boolean" Value.Boolean $ \ value -> case value of+        Value.Boolean boolean -> Just boolean+        _ -> Nothing++instance HasCodec Number.Number where+    codec = basicCodec "Number" Value.Number $ \ value -> case value of+        Value.Number number -> Just number+        _ -> Nothing++instance HasCodec String.String where+    codec = basicCodec "String" Value.String $ \ value -> case value of+        Value.String string -> Just string+        _ -> Nothing++instance HasCodec a => HasCodec (Array.ArrayOf a) where+    codec = Codec.Codec+        { Codec.decode = do+            array <- castValue "Array" $ \ value -> case value of+                Value.Array array -> Just array+                _ -> Nothing+            either (Trans.lift . Trans.throwE) (pure . Array.fromList)+                . traverse (Codec.decodeWith codec)+                $ Array.toList array+        , Codec.encode = Codec.tap+            $ Trans.lift+            . Trans.put+            . Value.Array+            . Array.fromList+            . fmap (Codec.encodeWith codec)+            . Array.toList+        }++instance HasCodec a => HasCodec (Object.ObjectOf a) where+    codec = Codec.Codec+        { Codec.decode = do+            object <- castValue "Object" $ \ value -> case value of+                Value.Object object -> Just object+                _ -> Nothing+            either (Trans.lift . Trans.throwE) (pure . Object.fromList)+                . traverse (\ (Member.Member k v) -> Member.Member k <$> Codec.decodeWith codec v)+                $ Object.toList object+        , Codec.encode = Codec.tap+            $ Trans.lift+            . Trans.put+            . Value.Object+            . Object.fromList+            . fmap (\ (Member.Member k v) -> Member.Member k $ Codec.encodeWith codec v)+            . Object.toList+        }++instance HasCodec a => HasCodec (Maybe a) where+    codec = Codec.mapMaybe (Just . Just) id codec+        <|> Codec.dimap (const Nothing) (const $ Null.fromUnit ()) codec++instance (HasCodec a, HasCodec b) => HasCodec (Either a b) where+    codec = Codec.mapMaybe (Just . Left) (either Just $ const Nothing) (Codec.tagged "Left" codec)+        <|> Codec.mapMaybe (Just . Right) (either (const Nothing) Just) (Codec.tagged "Right" codec)++instance HasCodec () where+    codec = Codec.fromArrayCodec Permission.Forbid $ pure ()++instance (HasCodec a, HasCodec b) => HasCodec (a, b) where+    codec = Codec.fromArrayCodec Permission.Forbid $ (,)+        <$> Codec.project fst (Codec.element codec)+        <*> Codec.project snd (Codec.element codec)++instance HasCodec Bool where+    codec = Codec.dimap Boolean.toBool Boolean.fromBool codec++instance HasCodec Decimal.Decimal where+    codec = Codec.dimap Number.toDecimal Number.fromDecimal codec++instance HasCodec Text.Text where+    codec = Codec.dimap String.toText String.fromText codec++instance {-# OVERLAPPABLE #-} HasCodec a => HasCodec [a] where+    codec = Codec.dimap Array.toList Array.fromList codec++instance HasCodec a => HasCodec (Map.Map Name.Name a) where+    codec = Codec.dimap+        (Map.fromList . fmap Member.toTuple . Object.toList)+        (Object.fromList . fmap Member.fromTuple . Map.toList)+        codec++instance HasCodec String where+    codec = Codec.dimap Text.unpack Text.pack codec++instance HasCodec Char where+    codec = Codec.mapMaybe (\ x -> case Text.uncons x of+        Just (y, z) | Text.null z -> Just y+        _ -> Nothing) (Just . Text.singleton) codec++instance HasCodec Text.LazyText where+    codec = Codec.dimap Text.fromStrict Text.toStrict codec++instance HasCodec a => HasCodec (NonEmpty.NonEmpty a) where+    codec = Codec.mapMaybe NonEmpty.nonEmpty (Just . NonEmpty.toList) codec++instance HasCodec Integer where+    codec = Codec.mapMaybe Decimal.toInteger (Just . Decimal.fromInteger) codec++instance HasCodec Int where+    codec = let+        from = Bits.toIntegralSized :: Integer -> Maybe Int+        into = fromIntegral :: Int -> Integer+        in Codec.mapMaybe from (Just . into) codec++instance HasCodec Int.Int8 where+    codec = let+        from = Bits.toIntegralSized :: Integer -> Maybe Int.Int8+        into = fromIntegral :: Int.Int8 -> Integer+        in Codec.mapMaybe from (Just . into) codec++instance HasCodec Int.Int16 where+    codec = let+        from = Bits.toIntegralSized :: Integer -> Maybe Int.Int16+        into = fromIntegral :: Int.Int16 -> Integer+        in Codec.mapMaybe from (Just . into) codec++instance HasCodec Int.Int32 where+    codec = let+        from = Bits.toIntegralSized :: Integer -> Maybe Int.Int32+        into = fromIntegral :: Int.Int32 -> Integer+        in Codec.mapMaybe from (Just . into) codec++instance HasCodec Int.Int64 where+    codec = let+        from = Bits.toIntegralSized :: Integer -> Maybe Int.Int64+        into = fromIntegral :: Int.Int64 -> Integer+        in Codec.mapMaybe from (Just . into) codec++instance HasCodec Word where+    codec = let+        from = Bits.toIntegralSized :: Integer -> Maybe Word+        into = fromIntegral :: Word -> Integer+        in Codec.mapMaybe from (Just . into) codec++instance HasCodec Word.Word8 where+    codec = let+        from = Bits.toIntegralSized :: Integer -> Maybe Word.Word8+        into = fromIntegral :: Word.Word8 -> Integer+        in Codec.mapMaybe from (Just . into) codec++instance HasCodec Word.Word16 where+    codec = let+        from = Bits.toIntegralSized :: Integer -> Maybe Word.Word16+        into = fromIntegral :: Word.Word16 -> Integer+        in Codec.mapMaybe from (Just . into) codec++instance HasCodec Word.Word32 where+    codec = let+        from = Bits.toIntegralSized :: Integer -> Maybe Word.Word32+        into = fromIntegral :: Word.Word32 -> Integer+        in Codec.mapMaybe from (Just . into) codec++instance HasCodec Word.Word64 where+    codec = let+        from = Bits.toIntegralSized :: Integer -> Maybe Word.Word64+        into = fromIntegral :: Word.Word64 -> Integer+        in Codec.mapMaybe from (Just . into) codec++instance HasCodec Float where+    codec = Codec.mapMaybe (Just . Decimal.toRealFloat) Decimal.fromRealFloat codec++instance HasCodec Double where+    codec = Codec.mapMaybe (Just . Decimal.toRealFloat) Decimal.fromRealFloat codec++instance HasCodec Pointer.Pointer where+    codec = Codec.mapMaybe+        ( either (const Nothing) Just+        . Decoder.run Pointer.decode+        . Text.encodeUtf8+        )+        ( either (const Nothing) Just+        . Text.decodeUtf8'+        . ByteString.toStrict+        . Builder.toLazyByteString+        . Encoder.run Config.initial+        . Pointer.encode+        )+        codec++basicCodec :: String -> (a -> Value.Value) -> (Value.Value -> Maybe a) -> Codec.ValueCodec a+basicCodec expected toValue fromValue = Codec.Codec+    { Codec.decode = castValue expected fromValue+    , Codec.encode = Codec.tap $ Trans.lift . Trans.put . toValue+    }++castValue+    :: String+    -> (Value.Value -> Maybe a)+    -> Trans.ReaderT Value.Value (Trans.ExceptT String Identity.Identity) a+castValue expected fromValue = do+    value <- Trans.ask+    case fromValue value of+        Nothing -> Trans.lift . Trans.throwE $ typeMismatch expected value+        Just x -> pure x++typeMismatch :: String -> Value.Value -> String+typeMismatch expected value =+    let+        actual = case value of+            Value.Null _ -> "Null"+            Value.Boolean _ -> "Boolean"+            Value.Number _ -> "Number"+            Value.String _ -> "String"+            Value.Array _ -> "Array"+            Value.Object _ -> "Object"+    in "expected " <> expected <> " but got " <> actual
source/library/Argo/Class/ToValue.hs view
@@ -1,133 +1,8 @@-{-# LANGUAGE FlexibleInstances #-}- module Argo.Class.ToValue where -import qualified Argo.Json.Member as Member-import qualified Argo.Json.Number as Number+import qualified Argo.Class.HasCodec as HasCodec import qualified Argo.Json.Value as Value-import qualified Argo.Pattern as Pattern-import qualified Argo.Pointer.Pointer as Pointer-import qualified Argo.Type.Config as Config-import qualified Argo.Type.Decimal as Decimal-import qualified Argo.Type.Encoder as Encoder-import qualified Argo.Vendor.Builder as Builder-import qualified Argo.Vendor.ByteString as ByteString-import qualified Argo.Vendor.Text as Text-import qualified Data.Int as Int-import qualified Data.List as List-import qualified Data.List.NonEmpty as NonEmpty-import qualified Data.Map as Map-import qualified Data.Word as Word-import qualified Numeric--class ToValue a where-    toValue :: a -> Value.Value--instance ToValue Value.Value where-    toValue = id--instance ToValue Bool where-    toValue = Pattern.Boolean--instance ToValue Char where-    toValue = toValue . Text.singleton--instance ToValue Int where-    toValue = toValue . toInteger--instance ToValue Int.Int8 where-    toValue = toValue . toInteger--instance ToValue Int.Int16 where-    toValue = toValue . toInteger--instance ToValue Int.Int32 where-    toValue = toValue . toInteger--instance ToValue Int.Int64 where-    toValue = toValue . toInteger--instance ToValue Word where-    toValue = toValue . toInteger--instance ToValue Word.Word8 where-    toValue = toValue . toInteger--instance ToValue Word.Word16 where-    toValue = toValue . toInteger--instance ToValue Word.Word32 where-    toValue = toValue . toInteger--instance ToValue Word.Word64 where-    toValue = toValue . toInteger--instance ToValue Integer where-    toValue x = Pattern.Number $ Decimal.decimal x 0--instance ToValue Float where-    toValue = realFloatToValue--instance ToValue Double where-    toValue = realFloatToValue--instance {-# OVERLAPPING #-} ToValue String where-    toValue = toValue . Text.pack--instance ToValue Text.Text where-    toValue = Pattern.String--instance ToValue Text.LazyText where-    toValue = toValue . Text.toStrict--instance ToValue a => ToValue (Maybe a) where-    toValue = maybe Pattern.Null toValue--instance ToValue () where-    toValue = const $ toValue ([] :: [Value.Value])--instance (ToValue a, ToValue b) => ToValue (a, b) where-    toValue (x, y) = toValue [toValue x, toValue y]--instance ToValue a => ToValue [a] where-    toValue = Pattern.Array . fmap toValue--instance ToValue a => ToValue (NonEmpty.NonEmpty a) where-    toValue = toValue . NonEmpty.toList--instance ToValue a => ToValue (Map.Map Text.Text a) where-    toValue x =-        Pattern.Object-            . fmap (\(k, v) -> Member.Member (Pattern.Name k) (toValue v))-            $ Map.toAscList x--instance ToValue Pointer.Pointer where-    toValue =-        either (error . mappend "Pointer.toValue: " . show) toValue-            . Text.decodeUtf8'-            . ByteString.toStrict-            . Builder.toLazyByteString-            . Encoder.run Config.initial-            . Pointer.encode--realFloatToValue :: RealFloat a => a -> Value.Value-realFloatToValue x-    | isNaN x-    = Pattern.Null-    | isInfinite x-    = Pattern.Null-    | otherwise-    = let isNegative = x < 0-      in-          Value.Number-          . Number.fromDecimal-          . (if isNegative then Decimal.negate else id)-          . uncurry digitsToDecimal-          . Numeric.floatToDigits 10-          $ abs x+import qualified Argo.Type.Codec as Codec -digitsToDecimal :: [Int] -> Int -> Decimal.Decimal-digitsToDecimal ds e = uncurry Decimal.decimal $ List.foldl'-    (\(a, n) d -> (a * 10 + toInteger d, n - 1))-    (0, toInteger e)-    ds+toValue :: HasCodec.HasCodec a => a -> Value.Value+toValue = Codec.encodeWith HasCodec.codec
source/library/Argo/Decode.hs view
@@ -1,12 +1,13 @@ module Argo.Decode where  import qualified Argo.Class.FromValue as FromValue+import qualified Argo.Class.HasCodec as HasCodec import qualified Argo.Json.Value as Value import qualified Argo.Pointer.Pointer as Pointer import qualified Argo.Type.Decoder as Decoder import qualified Argo.Vendor.ByteString as ByteString -decode :: FromValue.FromValue a => ByteString.ByteString -> Either String a+decode :: HasCodec.HasCodec a => ByteString.ByteString -> Either String a decode x = do     y <- Decoder.run (Decoder.spaces *> Value.decode) x     FromValue.fromValue y
source/library/Argo/Encode.hs view
@@ -1,5 +1,6 @@ module Argo.Encode where +import qualified Argo.Class.HasCodec as HasCodec import qualified Argo.Class.ToValue as ToValue import qualified Argo.Json.Value as Value import qualified Argo.Literal as Literal@@ -11,10 +12,10 @@ import qualified Argo.Vendor.Transformers as Trans import qualified Control.Monad as Monad -encode :: ToValue.ToValue a => a -> Builder.Builder+encode :: HasCodec.HasCodec a => a -> Builder.Builder encode = encodeWith $ Indent.Spaces 0 -encodeWith :: ToValue.ToValue a => Indent.Indent -> a -> Builder.Builder+encodeWith :: HasCodec.HasCodec a => Indent.Indent -> a -> Builder.Builder encodeWith i x =     let c = Config.initial { Config.indent = i }     in
source/library/Argo/Json/Member.hs view
@@ -19,6 +19,12 @@ data MemberOf value = Member Name.Name value     deriving (Eq, Generics.Generic, TH.Lift, DeepSeq.NFData, Show) +fromTuple :: (Name.Name, value) -> MemberOf value+fromTuple = uncurry Member++toTuple :: MemberOf value -> (Name.Name, value)+toTuple (Member k v) = (k, v)+ encode     :: (value -> Encoder.Encoder ()) -> MemberOf value -> Encoder.Encoder () encode f (Member x y) = do
source/library/Argo/Json/Name.hs view
@@ -14,7 +14,7 @@  newtype Name     = Name String.String-    deriving (Eq, Generics.Generic, TH.Lift, DeepSeq.NFData, Show)+    deriving (Eq, Generics.Generic, TH.Lift, DeepSeq.NFData, Ord, Show)  instance Data.String.IsString Name where     fromString = fromString . Data.String.fromString
source/library/Argo/Json/String.hs view
@@ -21,7 +21,7 @@  newtype String     = String Text.Text-    deriving (Eq, Generics.Generic, TH.Lift, DeepSeq.NFData, Show)+    deriving (Eq, Generics.Generic, TH.Lift, DeepSeq.NFData, Ord, Show)  instance String.IsString Argo.Json.String.String where     fromString = fromText . String.fromString
source/library/Argo/Type/Codec.hs view
@@ -3,11 +3,9 @@ import Control.Applicative ((<|>))  import qualified Argo.Json.Array as Array-import qualified Argo.Json.Boolean as Boolean import qualified Argo.Json.Member as Member import qualified Argo.Json.Name as Name import qualified Argo.Json.Null as Null-import qualified Argo.Json.Number as Number import qualified Argo.Json.Object as Object import qualified Argo.Json.String as String import qualified Argo.Json.Value as Value@@ -16,6 +14,7 @@ import qualified Control.Applicative as Applicative import qualified Control.Monad as Monad import qualified Data.Functor.Identity as Identity+import qualified Data.List as List import qualified Data.Text as Text  decodeWith :: ValueCodec a -> Value.Value -> Either String a@@ -67,81 +66,15 @@ dimap f g c =     Codec { decode = f <$> decode c, encode = fmap f . encode c . g } +tap :: Functor f => (a -> f b) -> a -> f a+tap f x = x <$ f x+ type ValueCodec a     = Codec           (Trans.ReaderT Value.Value (Trans.ExceptT String Identity.Identity))           (Trans.MaybeT (Trans.StateT Value.Value Identity.Identity))           a -valueCodec :: ValueCodec Value.Value-valueCodec = Codec-    { decode = Trans.ask-    , encode = \x -> do-        Trans.lift $ Trans.put x-        pure x-    }--nullCodec :: ValueCodec Null.Null-nullCodec = Codec-    { decode = do-        x <- Trans.ask-        case x of-            Value.Null y -> pure y-            _ ->-                Trans.lift . Trans.throwE $ "expected Null but got " <> show x-    , encode = \x -> do-        Trans.lift . Trans.put $ Value.Null x-        pure x-    }--booleanCodec :: ValueCodec Boolean.Boolean-booleanCodec = Codec-    { decode = do-        x <- Trans.ask-        case x of-            Value.Boolean y -> pure y-            _ ->-                Trans.lift-                    . Trans.throwE-                    $ "expected Boolean but got "-                    <> show x-    , encode = \x -> do-        Trans.lift . Trans.put $ Value.Boolean x-        pure x-    }--numberCodec :: ValueCodec Number.Number-numberCodec = Codec-    { decode = do-        x <- Trans.ask-        case x of-            Value.Number y -> pure y-            _ ->-                Trans.lift-                    . Trans.throwE-                    $ "expected Number but got "-                    <> show x-    , encode = \x -> do-        Trans.lift . Trans.put $ Value.Number x-        pure x-    }--stringCodec :: ValueCodec String.String-stringCodec = Codec-    { decode = do-        x <- Trans.ask-        case x of-            Value.String y -> pure y-            _ ->-                Trans.lift-                    . Trans.throwE-                    $ "expected String but got "-                    <> show x-    , encode = \x -> do-        Trans.lift . Trans.put $ Value.String x-        pure x-    }- arrayCodec :: ValueCodec (Array.ArrayOf Value.Value) arrayCodec = Codec     { decode = do@@ -171,35 +104,25 @@         pure x     } -boolCodec :: ValueCodec Bool-boolCodec = dimap Boolean.toBool Boolean.fromBool booleanCodec--textCodec :: ValueCodec Text.Text-textCodec = dimap String.toText String.fromText stringCodec--maybeCodec :: ValueCodec a -> ValueCodec (Maybe a)-maybeCodec c =-    mapBoth Just id c-        <|> dimap (const Nothing) (const $ Null.fromUnit ()) nullCodec--eitherCodec :: ValueCodec a -> ValueCodec b -> ValueCodec (Either a b)-eitherCodec cx cy =-    mapBoth Left (either Just (const Nothing)) (tagged "Left" cx)-        <|> mapBoth Right (either (const Nothing) Just) (tagged "Right" cy)--mapBoth-    :: (Functor r, Applicative.Alternative w)-    => (o2 -> o1)+mapMaybe+    :: (Applicative.Alternative r, Applicative.Alternative w, Monad r, Monad w)+    => (o2 -> Maybe o1)     -> (i1 -> Maybe i2)     -> CodecOf r w i2 o2     -> CodecOf r w i1 o1-mapBoth f g c = Codec-    { decode = f <$> decode c-    , encode = \x -> case g x of-        Nothing -> Applicative.empty-        Just y -> f <$> encode c y+mapMaybe f g c = Codec+    { decode = do+        o2 <- decode c+        toAlternative $ f o2+    , encode = \ i1 -> do+        i2 <- toAlternative $ g i1+        o2 <- encode c i2+        toAlternative $ f o2     } +toAlternative :: Applicative.Alternative m => Maybe a -> m a+toAlternative = maybe Applicative.empty pure+ tagged :: String -> ValueCodec a -> ValueCodec a tagged t c =     dimap snd ((,) ())@@ -288,13 +211,6 @@         pure x     } -tupleCodec :: ValueCodec a -> ValueCodec b -> ValueCodec (a, b)-tupleCodec cx cy =-    fromArrayCodec Permission.Forbid-        $ (,)-        <$> project fst (element cx)-        <*> project snd (element cy)- type ObjectCodec a = ListCodec (Member.MemberOf Value.Value) a  fromObjectCodec :: Permission.Permission -> ObjectCodec a -> ValueCodec a@@ -321,24 +237,16 @@ optional k c = Codec     { decode = do         xs <- Trans.get-        case detect (\(Member.Member j _) -> j == k) xs of-            Nothing -> pure Nothing-            Just (Member.Member _ x, ys) -> case decodeWith c x of+        case List.partition (\(Member.Member j _) -> j == k) xs of+            (Member.Member _ x : _, ys) -> case decodeWith c x of                 Left y -> Trans.lift $ Trans.throwE y                 Right y -> do                     Trans.put ys                     pure $ Just y+            _ -> pure Nothing     , encode = \x -> do         case x of             Nothing -> pure ()             Just y -> Trans.tell [Member.Member k $ encodeWith c y]         pure x     }--detect :: (a -> Bool) -> [a] -> Maybe (a, [a])-detect = detectWith id--detectWith :: ([a] -> [a]) -> (a -> Bool) -> [a] -> Maybe (a, [a])-detectWith f p xs = case xs of-    [] -> Nothing-    x : ys -> if p x then Just (x, f ys) else detectWith (f . (x :)) p ys
source/library/Argo/Type/Decimal.hs view
@@ -8,8 +8,10 @@  import qualified Argo.Vendor.DeepSeq as DeepSeq import qualified Argo.Vendor.TemplateHaskell as TH+import qualified Data.List as List import qualified Data.Ratio as Ratio import qualified GHC.Generics as Generics+import qualified Numeric  data Decimal = Decimal Integer Integer     deriving (Eq, Generics.Generic, TH.Lift, DeepSeq.NFData, Show)@@ -27,9 +29,32 @@         let (q, r) = quotRem s 10         in if r == 0 then normalize $ Decimal q (e + 1) else Decimal s e +fromInteger :: Integer -> Decimal+fromInteger = flip decimal 0++toInteger :: Decimal -> Maybe Integer+toInteger (Decimal s e) = if e < 0 then Nothing else Just $ s * 10 ^ e++fromRealFloat :: RealFloat a => a -> Maybe Decimal+fromRealFloat x = if isNaN x || isInfinite x then Nothing else+    Just+    . (if x < 0 then Argo.Type.Decimal.negate else id)+    . uncurry fromDigits+    . Numeric.floatToDigits 10+    $ abs x++toRealFloat :: RealFloat a => Decimal -> a+toRealFloat = Prelude.fromRational . Argo.Type.Decimal.toRational++fromDigits :: [Int] -> Int -> Decimal+fromDigits ds e = uncurry decimal $ List.foldl'+    (\(a, n) d -> (a * 10 + Prelude.toInteger d, n - 1))+    (0, Prelude.toInteger e)+    ds+ toRational :: Decimal -> Rational-toRational (Decimal s e) =-    if e < 0 then s % (10 ^ (-e)) else fromInteger $ s * 10 ^ e+toRational d@(Decimal s e) =+    maybe (s % (10 ^ (-e))) fromIntegral $ Argo.Type.Decimal.toInteger d  fromRational :: Rational -> Maybe Decimal fromRational r =
+ source/library/Argo/Vendor/Map.hs view
@@ -0,0 +1,7 @@+module Argo.Vendor.Map+    ( Map.Map+    , Map.fromList+    , Map.toList+    ) where++import qualified Data.Map as Map
source/test-suite/Main.hs view
@@ -341,8 +341,8 @@             Argo.fromValue (Argo.Array []) @?= Right ([] :: [Bool])         , Tasty.testCase "NonEmpty a" $ do             Argo.fromValue (Argo.Array [Argo.Boolean False]) @?= Right (False :| [])-        , Tasty.testCase "Map Text a" $ do-            Argo.fromValue (Argo.Object [Argo.Member (Argo.Name "a") $ Argo.Boolean False]) @?= Right (Map.fromList [("a" :: Text.Text, False)])+        , Tasty.testCase "Map Name a" $ do+            Argo.fromValue (Argo.Object [Argo.Member (Argo.Name "a") $ Argo.Boolean False]) @?= Right (Map.fromList [(Argo.Name "a", False)])         , Tasty.testCase "Pointer" $ do             Argo.fromValue (Argo.String "") @?= Right (Argo.Pointer [])         ]@@ -395,8 +395,8 @@             Argo.toValue ([] :: [Bool]) @?= Argo.Array []         , Tasty.testCase "NonEmpty a" $ do             Argo.toValue (False :| []) @?= Argo.Array [Argo.Boolean False]-        , Tasty.testCase "Map Text a" $ do-            Argo.toValue (Map.fromList [("a" :: Text.Text, False)]) @?= Argo.Object [Argo.Member (Argo.Name "a") $ Argo.Boolean False]+        , Tasty.testCase "Map Name a" $ do+            Argo.toValue (Map.fromList [(Argo.Name "a", False)]) @?= Argo.Object [Argo.Member (Argo.Name "a") $ Argo.Boolean False]         , Tasty.testCase "Pointer" $ do             Argo.toValue (Argo.Pointer []) @?= Argo.String ""         ]@@ -474,43 +474,43 @@                 Argo.fromValue (Argo.toValue x) === Right (x :: [Bool])             , property "NonEmpty a" $ \ x ->                 Argo.fromValue (Argo.toValue x) === Right (x :: NonEmpty Bool)-            , property "Map Text a" $ \ x ->-                Argo.fromValue (Argo.toValue x) === Right (x :: Map.Map Text.Text Bool)+            , property "Map Name a" $ \ x ->+                Argo.fromValue (Argo.toValue x) === Right (x :: Map.Map Argo.Name Bool)             , property "Pointer" $ \ x ->                 Argo.fromValue (Argo.toValue x) === Right (x :: Argo.Pointer)             ]         ]     , Tasty.testGroup "Codec"         [ Tasty.testCase "encode text" $ do-            Codec.encodeWith Codec.textCodec "" @?= Argo.String ""+            Codec.encodeWith Argo.codec ("" :: Text.Text) @?= Argo.String ""         , Tasty.testCase "decode text" $ do-            Codec.decodeWith Codec.textCodec (Argo.String "") @?= Right ""+            Codec.decodeWith Argo.codec (Argo.String "") @?= Right ("" :: Text.Text)         , Tasty.testCase "encode bool" $ do-            Codec.encodeWith Codec.boolCodec False @?= Argo.Boolean False+            Codec.encodeWith Argo.codec False @?= Argo.Boolean False         , Tasty.testCase "decode bool" $ do-            Codec.decodeWith Codec.boolCodec (Argo.Boolean False) @?= Right False-        , Tasty.testCase "encode maybe text" $ do-            Codec.encodeWith (Codec.maybeCodec Codec.textCodec) Nothing @?= Argo.Null-            Codec.encodeWith (Codec.maybeCodec Codec.textCodec) (Just "") @?= Argo.String ""-        , Tasty.testCase "decode maybe text" $ do-            Codec.decodeWith (Codec.maybeCodec Codec.textCodec) Argo.Null @?= Right Nothing-            Codec.decodeWith (Codec.maybeCodec Codec.textCodec) (Argo.String "") @?= Right (Just "")+            Codec.decodeWith Argo.codec (Argo.Boolean False) @?= Right False+        , Tasty.testCase "encode maybe bool" $ do+            Codec.encodeWith Argo.codec (Nothing :: Maybe Bool) @?= Argo.Null+            Codec.encodeWith Argo.codec (Just False) @?= Argo.Boolean False+        , Tasty.testCase "decode maybe bool" $ do+            Codec.decodeWith Argo.codec Argo.Null @?= Right (Nothing :: Maybe Bool)+            Codec.decodeWith Argo.codec (Argo.Boolean False) @?= Right (Just False)         , Tasty.testCase "encode either text bool" $ do-            Codec.encodeWith (Codec.eitherCodec Codec.textCodec Codec.boolCodec) (Left "") @?= Argo.Object [Argo.Member (Argo.Name "type") $ Argo.String "Left", Argo.Member (Argo.Name "value") $ Argo.String ""]-            Codec.encodeWith (Codec.eitherCodec Codec.textCodec Codec.boolCodec) (Right False) @?= Argo.Object [Argo.Member (Argo.Name "type") $ Argo.String "Right", Argo.Member (Argo.Name "value") $ Argo.Boolean False]+            Codec.encodeWith Argo.codec (Left "" :: Either Text.Text Bool) @?= Argo.Object [Argo.Member (Argo.Name "type") $ Argo.String "Left", Argo.Member (Argo.Name "value") $ Argo.String ""]+            Codec.encodeWith Argo.codec (Right False :: Either Text.Text Bool) @?= Argo.Object [Argo.Member (Argo.Name "type") $ Argo.String "Right", Argo.Member (Argo.Name "value") $ Argo.Boolean False]         , Tasty.testCase "decode either text bool" $ do-            Codec.decodeWith (Codec.eitherCodec Codec.textCodec Codec.boolCodec) (Argo.Object [Argo.Member (Argo.Name "type") $ Argo.String "Left", Argo.Member (Argo.Name "value") $ Argo.String ""]) @?= Right (Left "")-            Codec.decodeWith (Codec.eitherCodec Codec.textCodec Codec.boolCodec) (Argo.Object [Argo.Member (Argo.Name "type") $ Argo.String "Right", Argo.Member (Argo.Name "value") $ Argo.Boolean False]) @?= Right (Right False)+            Codec.decodeWith Argo.codec (Argo.Object [Argo.Member (Argo.Name "type") $ Argo.String "Left", Argo.Member (Argo.Name "value") $ Argo.String ""]) @?= Right (Left "" :: Either Text.Text Bool)+            Codec.decodeWith Argo.codec (Argo.Object [Argo.Member (Argo.Name "type") $ Argo.String "Right", Argo.Member (Argo.Name "value") $ Argo.Boolean False]) @?= Right (Right False :: Either Text.Text Bool)         , Tasty.testCase "encode tuple text bool" $ do-            Codec.encodeWith (Codec.tupleCodec Codec.textCodec Codec.boolCodec) ("", False) @?= Argo.Array [Argo.String "", Argo.Boolean False]+            Codec.encodeWith Argo.codec ("" :: Text.Text, False) @?= Argo.Array [Argo.String "", Argo.Boolean False]         , Tasty.testCase "decode tuple text bool" $ do-            Codec.decodeWith (Codec.tupleCodec Codec.textCodec Codec.boolCodec) (Argo.Array [Argo.String "", Argo.Boolean False]) @?= Right ("", False)+            Codec.decodeWith Argo.codec (Argo.Array [Argo.String "", Argo.Boolean False]) @?= Right ("" :: Text.Text, False)         , Tasty.testCase "encode record" $ do-            Codec.encodeWith recordCodec (Record False Nothing) @?= Argo.Object [Argo.Member (Argo.Name "bool") $ Argo.Boolean False]-            Codec.encodeWith recordCodec (Record False $ Just "") @?= Argo.Object [Argo.Member (Argo.Name "bool") $ Argo.Boolean False, Argo.Member (Argo.Name "text") $ Argo.String ""]+            Codec.encodeWith Argo.codec (Record False Nothing) @?= Argo.Object [Argo.Member (Argo.Name "bool") $ Argo.Boolean False]+            Codec.encodeWith Argo.codec (Record False $ Just "") @?= Argo.Object [Argo.Member (Argo.Name "bool") $ Argo.Boolean False, Argo.Member (Argo.Name "text") $ Argo.String ""]         , Tasty.testCase "decode record" $ do-            Codec.decodeWith recordCodec (Argo.Object [Argo.Member (Argo.Name "bool") $ Argo.Boolean False]) @?= Right (Record False Nothing)-            Codec.decodeWith recordCodec (Argo.Object [Argo.Member (Argo.Name "bool") $ Argo.Boolean False, Argo.Member (Argo.Name "text") $ Argo.String ""]) @?= Right (Record False $ Just "")+            Codec.decodeWith Argo.codec (Argo.Object [Argo.Member (Argo.Name "bool") $ Argo.Boolean False]) @?= Right (Record False Nothing)+            Codec.decodeWith Argo.codec (Argo.Object [Argo.Member (Argo.Name "bool") $ Argo.Boolean False, Argo.Member (Argo.Name "text") $ Argo.String ""]) @?= Right (Record False $ Just "")         ]     , Tasty.testGroup "Pointer"         $ let pointer = Argo.Pointer . fmap Argo.Token in@@ -578,10 +578,10 @@     , recordText :: Maybe Text.Text     } deriving (Eq, Show) -recordCodec :: Codec.ValueCodec Record-recordCodec = Codec.fromObjectCodec Permission.Allow $ Record-    <$> Codec.project recordBool (Codec.required (Argo.Name "bool") Codec.boolCodec)-    <*> Codec.project recordText (Codec.optional (Argo.Name "text") Codec.textCodec)+instance Argo.HasCodec Record where+    codec = Codec.fromObjectCodec Permission.Allow $ Record+        <$> Codec.project recordBool (Codec.required (Argo.Name "bool") Argo.codec)+        <*> Codec.project recordText (Codec.optional (Argo.Name "text") Argo.codec)  property     :: (Show t, Tasty.Testable prop, Tasty.Arbitrary t)