typed-encoding 0.3.0.0 → 0.3.0.1
raw patch · 44 files changed
+416/−74 lines, 44 files
Files
- ChangeLog.md +6/−0
- README.md +16/−4
- src/Data/TypedEncoding.hs +1/−1
- src/Data/TypedEncoding/Combinators/Common.hs +7/−1
- src/Data/TypedEncoding/Combinators/Decode.hs +7/−3
- src/Data/TypedEncoding/Combinators/Encode.hs +5/−0
- src/Data/TypedEncoding/Combinators/Promotion.hs +7/−7
- src/Data/TypedEncoding/Combinators/ToEncStr.hs +2/−1
- src/Data/TypedEncoding/Combinators/Unsafe.hs +5/−5
- src/Data/TypedEncoding/Combinators/Validate.hs +5/−1
- src/Data/TypedEncoding/Common/Class.hs +5/−1
- src/Data/TypedEncoding/Common/Class/IsStringR.hs +2/−0
- src/Data/TypedEncoding/Common/Class/Superset.hs +2/−0
- src/Data/TypedEncoding/Common/Class/Util.hs +16/−1
- src/Data/TypedEncoding/Common/Class/Util/StringConstraints.hs +8/−1
- src/Data/TypedEncoding/Common/Class/Validate.hs +6/−1
- src/Data/TypedEncoding/Common/Types/CheckedEnc.hs +15/−2
- src/Data/TypedEncoding/Common/Types/Common.hs +16/−2
- src/Data/TypedEncoding/Common/Types/Decoding.hs +15/−2
- src/Data/TypedEncoding/Common/Types/Enc.hs +2/−0
- src/Data/TypedEncoding/Common/Types/Exceptions.hs +12/−0
- src/Data/TypedEncoding/Common/Types/SomeAnnotation.hs +9/−2
- src/Data/TypedEncoding/Common/Types/SomeEnc.hs +11/−7
- src/Data/TypedEncoding/Common/Types/UncheckedEnc.hs +8/−0
- src/Data/TypedEncoding/Common/Types/Unsafe.hs +6/−0
- src/Data/TypedEncoding/Common/Types/Validation.hs +10/−0
- src/Data/TypedEncoding/Common/Util/TypeLits.hs +57/−9
- src/Data/TypedEncoding/Conv/ByteString/Char8.hs +4/−0
- src/Data/TypedEncoding/Instances/Do/Sample.hs +13/−3
- src/Data/TypedEncoding/Instances/Enc/Base64.hs +49/−0
- src/Data/TypedEncoding/Instances/Restriction/ASCII.hs +2/−0
- src/Data/TypedEncoding/Instances/Restriction/Bool.hs +2/−1
- src/Data/TypedEncoding/Instances/Restriction/Misc.hs +4/−0
- src/Data/TypedEncoding/Instances/Restriction/UTF8.hs +15/−4
- src/Data/TypedEncoding/Instances/Support/Common.hs +6/−0
- src/Data/TypedEncoding/Instances/Support/Decode.hs +2/−0
- src/Data/TypedEncoding/Instances/Support/Encode.hs +3/−1
- src/Data/TypedEncoding/Instances/Support/Helpers.hs +16/−0
- src/Data/TypedEncoding/Instances/Support/Unsafe.hs +10/−1
- src/Data/TypedEncoding/Instances/Support/Validate.hs +10/−2
- src/Examples/TypedEncoding/Conversions.hs +9/−6
- src/Examples/TypedEncoding/DiySignEncoding.hs +7/−2
- src/Examples/TypedEncoding/Overview.hs +1/−1
- typed-encoding.cabal +2/−2
ChangeLog.md view
@@ -5,6 +5,12 @@ - `Data.TypedEncoding.Internal.Class.IsStringR` expected to be be changed / replaced - (post 0.3) "enc-B64" will be moved to a different package (more distant goal) +## 0.3.0.1++- Documentation changes / corrections+- New _doctest_ tests+- Haddock coverage and @since flags+ ## 0.3 - Breaking: Numerous changes on the implementation side, new version should be largely compatible on the call site except
README.md view
@@ -46,7 +46,7 @@ - applied or undone partially (if encoding is reversible) One of more interesting uses of this library are encoding restrictions. -(Arbitrary) bounded alpha-numeric (`r-ban`) restrictions +(Arbitrary) bounded alpha-numeric (`"r-ban"`) restrictions and a simple annotation Boolean algebra are both provided. ```Haskell@@ -61,15 +61,27 @@ ## Examples -Please see `Examples.TypedEncoding` it the module list.+Here are some code examples: +- [Overview](src/Examples/TypedEncoding/Overview.hs)+- [Conversions between encodings](src/Examples/TypedEncoding/Conversions.hs)+- [Adding a new encoding, error handling](src/Examples/TypedEncoding/DiySignEncoding.hs)+- [To and from string conversions](src/Examples/TypedEncoding/ToEncString.hs)+- [Unsafe - working inside encodings](src/Examples/TypedEncoding/Unsafe.hs)+ ++## Hackage++https://hackage.haskell.org/package/typed-encoding++ ## Other encoding packages My approach will be to write specific encodings (e.g. _HTTP_) or wrap encodings from other packages using separate "bridge" projects. -Currently `typed-encoding` depends on+Currently /typed-encoding/ depends on -- `base64-bytestring` because it was my driving example, this is likely to move out to a separate bridge project at some point. +- /base64-bytestring/ because it was my driving example, this is likely to move out to a separate bridge project at some point. Bridge work:
src/Data/TypedEncoding.hs view
@@ -103,7 +103,7 @@ -- -- ... and needed conversions. ----- Conversion combinator module structure is similar to one found in @text@ and @bytestring@ packages+-- Conversion combinator module structure is similar to one found in /text/ and /bytestring/ packages -- And can be found (since 0.2.2) in -- -- * "Data.TypedEncoding.Conv.Text"
src/Data/TypedEncoding/Combinators/Common.hs view
@@ -28,6 +28,8 @@ -- replayed on top of another encoding stack. -- -- This subsumes various /encodePart, decodePart, recreatePart/ combinators.+--+-- @since 0.3.0.0 aboveF :: forall (ts :: [Symbol]) xs ys f c str . (Functor f) => (Enc xs c str -> f (Enc ys c str)) -> Enc (Append xs ts) c str -> f (Enc (Append ys ts) c str)@@ -35,7 +37,8 @@ let re :: f (Enc ys c str) = fn $ UnsafeMkEnc Proxy conf str in UnsafeMkEnc Proxy conf . getPayload <$> re -+-- |+-- @since 0.3.0.0 above :: forall (ts :: [Symbol]) xs ys c str . (Enc xs c str -> Enc ys c str) -> Enc (Append xs ts) c str -> Enc (Append ys ts) c str@@ -46,6 +49,9 @@ -- * Other ++-- |+-- @since 0.3.0.0 getTransformF :: forall e1 e2 f c s1 s2 . Functor f => (Enc e1 c s1 -> f (Enc e2 c s2)) -> c -> s1 -> f s2 getTransformF fn c str = getPayload <$> fn (unsafeSetPayload c str)
src/Data/TypedEncoding/Combinators/Decode.hs view
@@ -7,7 +7,11 @@ {-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE TypeApplications #-} --- | Combinators reexported in Data.TypedEncoding+-- | Combinators reexported in Data.TypedEncoding.+-- +-- Decoding combinators that are backward compatible to v0.2 versions.+--+-- @since 0.3.0.0 module Data.TypedEncoding.Combinators.Decode where import Data.TypedEncoding.Common.Types.Enc@@ -20,7 +24,7 @@ import GHC.TypeLits --- * Convenience combinators which mimic pre-v0.3 type signatures. These assume that @algs@ are the same as @nms@+-- * Convenience combinators which mimic v0.2 combinators signatures. These assume that @algs@ are the same as @nms@ decodeF :: forall nm xs f c str . (Decode f nm nm c str) => Enc (nm ': xs) c str -> f (Enc xs c str) decodeF = decodeF' @nm @nm@@ -45,7 +49,7 @@ --- * Convenience combinators which mimic pre-v0.3 type signatures. These do not try to figure out @algs@ or assume much about them+-- * Convenience combinators which mimic v0.2 type signatures. These do not try to figure out @algs@ or assume much about them decodeF' :: forall alg nm xs f c str . (Decode f nm alg c str) => Enc (nm ': xs) c str -> f (Enc xs c str) decodeF' = runDecoding (decoding @f @nm @alg)
src/Data/TypedEncoding/Combinators/Encode.hs view
@@ -9,6 +9,11 @@ {-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE TypeApplications #-} +-- | Combinators reexported in Data.TypedEncoding.+-- +-- Decoding combinators that are backward compatible to v0.2 versions.+--+-- @since 0.3.0.0 module Data.TypedEncoding.Combinators.Encode where import Data.TypedEncoding.Common.Types.Enc
src/Data/TypedEncoding/Combinators/Promotion.hs view
@@ -35,7 +35,7 @@ -- >>> displ $ demoteFlattenTop (unsafeSetPayload () "" :: Enc '["r-ASCII", "r-UTF8", "r-boo"] () T.Text) -- "Enc '[r-ASCII,r-boo] () (Text )" ----- @since 0.2.2.0 (moved)+-- @since 0.2.2.0 demoteFlattenTop :: forall y x xs c str . (IsSuperset y x ~ 'True) => Enc (x ': y ': xs) c str -> Enc (x ': xs) c str demoteFlattenTop = withUnsafeCoerce id @@ -44,7 +44,7 @@ -- >>> displ $ promoteUnFlattenTop @"r-UTF8" (unsafeSetPayload () "" :: Enc '["r-ASCII", "r-boo"] () T.Text) -- "Enc '[r-ASCII,r-UTF8,r-boo] () (Text )" ----- @since 0.2.2.0 (moved)+-- @since 0.2.2.0 promoteUnFlattenTop :: forall y x xs c str . (IsSuperset y x ~ 'True) => Enc (x ': xs) c str -> Enc (x ': y ': xs) c str promoteUnFlattenTop = withUnsafeCoerce id @@ -53,7 +53,7 @@ -- >>> displ $ demoteRemoveTop (unsafeSetPayload () "" :: Enc '["r-UTF8", "r-ASCII", "r-boo"] () T.Text) -- "Enc '[r-ASCII,r-boo] () (Text )" ----- @since 0.2.2.0 (moved)+-- @since 0.2.2.0 demoteRemoveTop :: forall y x xs c str . (IsSuperset y x ~ 'True) => Enc (y ': x ' : xs) c str -> Enc (x ': xs) c str demoteRemoveTop = withUnsafeCoerce id @@ -62,7 +62,7 @@ -- >>> displ $ promoteAddTop @"r-UTF8" (unsafeSetPayload () "" :: Enc '["r-ASCII", "r-boo"] () T.Text) -- "Enc '[r-UTF8,r-ASCII,r-boo] () (Text )" ----- @since 0.2.2.0 (moved)+-- @since 0.2.2.0 promoteAddTop :: forall y x xs c str . (IsSuperset y x ~ 'True) => Enc (x ': xs) c str -> Enc (y ': x ' : xs) c str promoteAddTop = withUnsafeCoerce id @@ -71,7 +71,7 @@ -- >>> displ $ demoteRemoveBot (unsafeSetPayload () "" :: Enc '["r-boo", "r-ASCII", "r-UTF8"] () T.Text) -- "Enc '[r-boo,r-ASCII] () (Text )" ----- @since 0.2.2.0 (moved)+-- @since 0.2.2.0 demoteRemoveBot :: (UnSnoc xs ~ '(,) ys y, UnSnoc ys ~ '(,) zs x, IsSuperset y x ~ 'True) => Enc xs c str -> Enc ys c str demoteRemoveBot = withUnsafeCoerce id @@ -87,7 +87,7 @@ -- >>> displ $ demoteFlattenBot (unsafeSetPayload () "" :: Enc '["r-boo", "r-UTF8", "r-ASCII"] () T.Text) -- "Enc '[r-boo,r-ASCII] () (Text )" ----- @since 0.2.2.0 (moved)+-- @since 0.2.2.0 demoteFlattenBot :: (UnSnoc xs ~ '(,) ys x, UnSnoc ys ~ '(,) zs y, IsSuperset y x ~ 'True) => Enc xs c str -> Enc (Snoc zs x) c str demoteFlattenBot = withUnsafeCoerce id @@ -96,6 +96,6 @@ -- >>> displ $ promoteUnFlattenBot @"r-UTF8" (unsafeSetPayload () "" :: Enc '["r-boo", "r-ASCII"] () T.Text) -- "Enc '[r-boo,r-UTF8,r-ASCII] () (Text )" ----- @since 0.2.2.0 (moved)+-- @since 0.2.2.0 promoteUnFlattenBot :: forall y x xs c str ys . (UnSnoc xs ~ '(,) ys x, IsSuperset y x ~ 'True) => Enc xs c str -> Enc (Snoc (Snoc ys y) x) c str promoteUnFlattenBot = withUnsafeCoerce id
src/Data/TypedEncoding/Combinators/ToEncStr.hs view
@@ -11,7 +11,8 @@ {-# LANGUAGE TypeApplications #-} {-# LANGUAGE AllowAmbiguousTypes #-} --- | v0.2 like (backward compatible) combinators for covering to and from encoded string.+-- | +-- v0.2 like (backward compatible) combinators for covering to and from encoded string. -- -- @since 0.3.0.0
src/Data/TypedEncoding/Combinators/Unsafe.hs view
@@ -9,15 +9,15 @@ -- |--- Currently recommended way of recreating encoding from trusted input,--- if avoiding cost of "Data.TypedEncoding.Common.Types.Validation" is important+-- Currently this is the recommended way of recreating encoding from trusted input,+-- if avoiding cost of "Data.TypedEncoding.Common.Types.Validation" is important. -- --- @since 0.1.0.0 (moved)+-- @since 0.1.0.0 unsafeSetPayload :: conf -> str -> Enc enc conf str unsafeSetPayload = UnsafeMkEnc Proxy -- |--- @since 0.1.0.0 (moved)+-- @since 0.1.0.0 withUnsafeCoerce :: (s1 -> s2) -> Enc e1 c s1 -> Enc e2 c s2 withUnsafeCoerce f (UnsafeMkEnc _ conf str) = UnsafeMkEnc Proxy conf (f str) @@ -27,6 +27,6 @@ withUnsafeCoerceF f (UnsafeMkEnc _ conf str) = UnsafeMkEnc Proxy conf <$> f str -- |--- @since 0.1.0.0 (moved)+-- @since 0.1.0.0 unsafeChangePayload :: (s1 -> s2) -> Enc e c s1 -> Enc e c s2 unsafeChangePayload f (UnsafeMkEnc p conf str) = UnsafeMkEnc p conf (f str)
src/Data/TypedEncoding/Combinators/Validate.hs view
@@ -7,7 +7,11 @@ {-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE TypeApplications #-} --- | Combinators reexported in Data.TypedEncoding+-- | Combinators re-exported in Data.TypedEncoding.+-- +-- Decoding combinators that are backward compatible to v0.2 versions.+--+-- @since 0.3.0.0 module Data.TypedEncoding.Combinators.Validate where import Data.TypedEncoding.Combinators.Common
src/Data/TypedEncoding/Common/Class.hs view
@@ -38,11 +38,14 @@ -- -- Encodes @a@ as @Enc '[xs]@ specifying algorithm @alg@ and using effect @f@ --+-- @since 0.2.0.0 class (KnownSymbol nm, KnownSymbol ann) => ToEncString f nm ann a str where toEncF :: a -> f (Enc '[nm] () str) -- | -- Reverse of 'ToEncString' decodes encoded string back to @a@+--+-- @since 0.2.0.0 class (KnownSymbol nm, KnownSymbol ann) => FromEncString f nm ann a str where fromEncF :: Enc '[nm] () str -> f a @@ -57,7 +60,8 @@ -- -- Now encoded data has form @Enc '["r-ASCII"] c str@ -- and there is no danger of it begin incorrectly decoded.-+--+-- @since 0.1.0.0 class FlattenAs (y :: Symbol) (x :: Symbol) where flattenAs :: Enc (x ': xs) c str -> Enc '[y] c str flattenAs = withUnsafeCoerce id
src/Data/TypedEncoding/Common/Class/IsStringR.hs view
@@ -38,6 +38,8 @@ -- Note: ByteString is not a valid instance, ByteString "r-ASCII", or "r-UTF8" would -- be needed. -- @B.unpack $ B.pack "\160688" == "\176"@+--+-- @since 0.2.0.0 class IsStringR a where toString :: a -> String
src/Data/TypedEncoding/Common/Class/Superset.hs view
@@ -52,6 +52,8 @@ IsSuperset "r-UTF8" "r-UTF8" = 'True IsSuperset y x = IsSupersetOpen y (TakeUntil x ":") (ToList x) +-- |+-- @since 0.2.2.0 type family IsSupersetOpen (y :: Symbol) (x :: Symbol) (xs :: [Symbol]) :: Bool -- |
src/Data/TypedEncoding/Common/Class/Util.hs view
@@ -11,6 +11,10 @@ {-# LANGUAGE TypeApplications #-} {-# LANGUAGE AllowAmbiguousTypes #-} +-- | This module should be merged with +-- "Data.TypedEncoding.Common.Util.TypeLits"+--+-- Since both provide type level helpers module Data.TypedEncoding.Common.Class.Util where import Data.TypedEncoding.Common.Types.Common@@ -29,6 +33,8 @@ -- * Symbol List +-- |+-- @since 0.2.0.0 class SymbolList (xs::[Symbol]) where symbolVals :: [String] @@ -47,6 +53,8 @@ -- * Display -- | Human friendly version of Show+--+-- @since 0.2.0.0 class Displ x where displ :: x -> String @@ -76,12 +84,19 @@ -- * Other --- | TODO should this be imported from somewhere?+-- TODO should this be imported from somewhere?++-- |+-- Type level list append+-- +-- @since 0.1.0.0 type family Append (xs :: [k]) (ys :: [k]) :: [k] where Append '[] xs = xs Append (y ': ys) xs = y ': Append ys xs -- | Polymorphic data payloads used to encode/decode+--+-- @since 0.1.0.0 class HasA a c where has :: c -> a
src/Data/TypedEncoding/Common/Class/Util/StringConstraints.hs view
@@ -10,7 +10,8 @@ {-# LANGUAGE TypeApplications #-} {-# LANGUAGE AllowAmbiguousTypes #-} --- | Future replacement for "Data.TypedEncoding.Common.Class.IsStringR"+-- | +-- 'ToStrInj' and 'ToStrIso' are future replacement for "Data.TypedEncoding.Common.Class.IsStringR" (currently not used). module Data.TypedEncoding.Common.Class.Util.StringConstraints where import qualified Data.List as L@@ -46,6 +47,8 @@ -- -- This class is separated from @ToStrIso@ to allow instances from /smaller/ types -- the can inject into the 'String' type.+--+-- @since 0.3.0.0 class ToStrInj str from where toString :: from -> str @@ -84,6 +87,8 @@ -- @ -- fromString . toString == id -- @+--+-- @since 0.3.0.0 class ToStrInj str from => ToStrIso str from where prop_fromStringToString :: forall s . (IsString s, ToStrIso String s, Eq s) => s -> Bool@@ -102,6 +107,8 @@ -- | -- Used to find exceptions that violated "r-" encoding -- Expected to be used to check encoding of ASCII-7 so Text and ByteString are compatible.+--+-- @since 0.3.0.0 class Char8Find str where find :: (Char -> Bool) -> str -> Maybe Char
src/Data/TypedEncoding/Common/Class/Validate.hs view
@@ -35,16 +35,21 @@ -- | Recovery errors are expected unless Recovery allows Identity instance+--+-- @since 0.1.0.0 class RecreateErr f where recoveryErr :: RecreateEx -> f a instance RecreateErr (Either RecreateEx) where recoveryErr = Left +-- |+-- @since 0.2.1.0 asRecreateErr_ :: (RecreateErr f, Applicative f, Show err, KnownSymbol x) => Proxy x -> Either err a -> f a asRecreateErr_ p (Left err) = recoveryErr $ RecreateEx p err asRecreateErr_ _ (Right r) = pure r -+-- |+-- @since 0.1.0.0 asRecreateErr :: forall x f err a . (RecreateErr f, Applicative f, Show err, KnownSymbol x) => Either err a -> f a asRecreateErr = asRecreateErr_ (Proxy :: Proxy x)
src/Data/TypedEncoding/Common/Types/CheckedEnc.hs view
@@ -35,23 +35,36 @@ -- @CheckedEnc@ is untyped version of 'Data.TypedEncoding.Common.Types.Enc.Enc'. -- @CheckedEnc@ contains verified encoded data, encoding is visible -- at the value level only.-data CheckedEnc conf str = UnsafeMkCheckedEnc [EncAnn] conf str+--+-- @since 0.2.0.0 +data CheckedEnc conf str = UnsafeMkCheckedEnc [EncAnn] conf str -- ^ @since 0.3.0.0+ -- Constructor renamed from previous versions+ deriving (Show, Eq) +-- |+-- @since 0.2.0.0 unsafeCheckedEnc:: [EncAnn] -> c -> s -> CheckedEnc c s unsafeCheckedEnc = UnsafeMkCheckedEnc +-- |+-- @since 0.2.0.0 getCheckedPayload :: CheckedEnc conf str -> str getCheckedPayload = snd . getCheckedEncPayload +-- |+-- @since 0.2.0.0 getCheckedEncPayload :: CheckedEnc conf str -> ([EncAnn], str) getCheckedEncPayload (UnsafeMkCheckedEnc t _ s) = (t,s) +-- |+-- @since 0.2.0.0 toCheckedEnc :: forall xs c str . (SymbolList xs) => Enc xs c str -> CheckedEnc c str toCheckedEnc (UnsafeMkEnc p c s) = UnsafeMkCheckedEnc (symbolVals @ xs) c s -+-- |+-- @since 0.2.0.0 fromCheckedEnc :: forall xs c str . SymbolList xs => CheckedEnc c str -> Maybe (Enc xs c str) fromCheckedEnc (UnsafeMkCheckedEnc xs c s) = let p = Proxy :: Proxy xs
src/Data/TypedEncoding/Common/Types/Common.hs view
@@ -22,10 +22,19 @@ -- | Represents value level (single) annotation.+-- @since 0.2.0.0 type EncAnn = String +-- | +-- Contraint for "r-" annotations.+--+-- @since 0.3.0.0 type Restriction s = (KnownSymbol s, IsR s ~ 'True) +-- | +-- Contraint for algorithm name.+--+-- @since 0.3.0.0 type Algorithm nm alg = AlgNm nm ~ alg @@ -42,10 +51,12 @@ -- ... -- = "r-ban" --+-- @since 0.3.0.0 type family AlgNm (encnm :: Symbol) :: Symbol where AlgNm encnm = TakeUntil encnm ":" -+-- |+-- @since 0.3.0.0 type family AlgNmMap (nms :: [Symbol]) :: [Symbol] where AlgNmMap '[] = '[] AlgNmMap (x ': xs) = AlgNm x ': AlgNmMap xs@@ -58,10 +69,13 @@ -- >>> :kind! IsR "do-UPPER" -- ... -- = (TypeError ... +--+-- @since 0.2.1.0 type family IsR (s :: Symbol) :: Bool where IsR s = AcceptEq ('Text "Not restriction encoding " ':<>: ShowType s ) (CmpSymbol "r-" (Take 2 s)) -+-- |+-- @since 0.2.1.0 type family IsROrEmpty (s :: Symbol) :: Bool where IsROrEmpty "" = True IsROrEmpty x = IsR x
src/Data/TypedEncoding/Common/Types/Decoding.hs view
@@ -27,7 +27,8 @@ -- Similar to 'Data.TypedEncoding.Common.Types.Enc.Encoding' -- -- Used to create instances of decoding.-+--+-- @since 0.3.0.0 data Decoding f (nm :: Symbol) (alg :: Symbol) conf str where -- | Consider this constructor as private or use it with care --@@ -40,16 +41,22 @@ UnsafeMkDecoding :: Proxy nm -> (forall (xs :: [Symbol]) . Enc (nm ': xs) conf str -> f (Enc xs conf str)) -> Decoding f nm alg conf str -- | Type safe smart constructor--- (See also 'Data.TypedEncoding.Common.Types.Enc._mkEncoding') +-- (See also 'Data.TypedEncoding.Common.Types.Enc._mkEncoding') +--+-- @since 0.3.0.0 mkDecoding :: forall f (nm :: Symbol) conf str . (forall (xs :: [Symbol]) . Enc (nm ': xs) conf str -> f (Enc xs conf str)) -> Decoding f nm (AlgNm nm) conf str mkDecoding = UnsafeMkDecoding Proxy +-- |+-- @since 0.3.0.0 runDecoding :: forall alg nm f xs conf str . Decoding f nm alg conf str -> Enc (nm ': xs) conf str -> f (Enc xs conf str) runDecoding (UnsafeMkDecoding _ fn) = fn -- | Same as 'runDecoding" but compiler figures out algorithm name -- -- Using it can slowdown compilation+--+-- @since 0.3.0.0 _runDecoding :: forall nm f xs conf str alg . (AlgNm nm ~ alg) => Decoding f nm alg conf str -> Enc (nm ': xs) conf str -> f (Enc xs conf str) _runDecoding = runDecoding @(AlgNm nm) @@ -58,12 +65,16 @@ -- -- Similarly to 'Data.TypedEncoding.Common.Types.Enc.Encodings' can be used with a typeclass -- 'Data.TypedDecoding.Internal.Class.Decode.DecodeAll'+--+-- @since 0.3.0.0 data Decodings f (nms :: [Symbol]) (algs :: [Symbol]) conf str where -- | constructor is to be treated as Unsafe to Encode and Decode instance implementations -- particular encoding instances may expose smart constructors for limited data types ZeroD :: Decodings f '[] '[] conf str ConsD :: Decoding f nm alg conf str -> Decodings f nms algs conf str -> Decodings f (nm ': nms) (alg ': algs) conf str +-- |+-- @since 0.3.0.0 runDecodings :: forall algs nms f c str . (Monad f) => Decodings f nms algs c str -> Enc nms c str -> f (Enc ('[]::[Symbol]) c str) runDecodings ZeroD enc0 = pure enc0 runDecodings (ConsD fn xs) enc = @@ -72,5 +83,7 @@ -- | At possibly big compilation cost, have compiler figure out algorithm names.+--+-- @since 0.3.0.0 _runDecodings :: forall nms f c str algs . (Monad f, algs ~ AlgNmMap nms) => Decodings f nms algs c str -> Enc nms c str -> f (Enc ('[]::[Symbol]) c str) _runDecodings = runDecodings @(AlgNmMap nms)
src/Data/TypedEncoding/Common/Types/Enc.hs view
@@ -55,6 +55,8 @@ UnsafeMkEnc :: Proxy nms -> conf -> str -> Enc nms conf str deriving (Show, Eq) +-- TODO should Enc be a Functor in conf?+ -- | -- >>> let disptest = UnsafeMkEnc Proxy () "hello" :: Enc '["TEST"] () T.Text -- >>> displ disptest
src/Data/TypedEncoding/Common/Types/Exceptions.hs view
@@ -41,30 +41,40 @@ -- | Represents errors in encoding+-- @since 0.1.0.0 data EncodeEx where EncodeEx:: (Show a, KnownSymbol x) => Proxy x -> a -> EncodeEx instance Show EncodeEx where show (EncodeEx prxy a) = "(EncodeEx \"" ++ symbolVal prxy ++ "\" (" ++ show a ++ "))" +-- |+-- @since 0.2.2.0 asEncodeEx :: (Show a, KnownSymbol x) => Proxy x -> Either a b -> Either EncodeEx b asEncodeEx p = either (Left . EncodeEx p) Right -- | Useful when manually recreating using recovery+-- @since 0.2.2.0 encToRecrEx :: EncodeEx -> RecreateEx encToRecrEx (EncodeEx p a) = RecreateEx p a +-- |+-- @since 0.2.1.0 mergeEncodeEx :: KnownSymbol x => Proxy x -> EncodeEx -> Maybe EncodeEx -> EncodeEx mergeEncodeEx _ ex Nothing = ex mergeEncodeEx p (EncodeEx _ a) (Just (EncodeEx _ b)) = EncodeEx p $ "Errors: " ++ show (a,b) +-- |+-- @since 0.2.1.0 emptyEncErr :: KnownSymbol x => Proxy x -> EncodeEx emptyEncErr p = EncodeEx p ("unexpected" :: String) -- | Type safety over encodings makes decoding process safe. -- However failures are still possible due to bugs or unsafe payload modifications. -- UnexpectedDecodeEx represents such errors.+--+-- @since 0.1.0.0 data UnexpectedDecodeEx where UnexpectedDecodeEx :: (Show a, KnownSymbol x) => Proxy x -> a -> UnexpectedDecodeEx @@ -74,6 +84,8 @@ -- * Base combinators that rely on types defined here +-- |+-- @since 0.2.1.0 mergeErrs :: err -> (err -> Maybe err -> err) -> Either err a -> Either err b -> Either err c mergeErrs _ fn (Left er1) (Left er2) = Left (fn er1 $ Just er2) mergeErrs _ fn (Left er1) _ = Left (fn er1 Nothing)
src/Data/TypedEncoding/Common/Types/SomeAnnotation.hs view
@@ -15,14 +15,19 @@ import Data.Proxy import GHC.TypeLits -+-- |+-- @since 0.2.0.0 data SomeAnnotation where MkSomeAnnotation :: SymbolList xs => Proxy xs -> SomeAnnotation +-- |+-- @since 0.2.0.0 withSomeAnnotation :: SomeAnnotation -> (forall xs . SymbolList xs => Proxy xs -> r) -> r withSomeAnnotation (MkSomeAnnotation p) fn = fn p --- folds over SomeSymbol list using withSomeSymbol and proxyCons++-- | folds over SomeSymbol list using withSomeSymbol and proxyCons+-- @since 0.2.0.0 someAnnValue :: [EncAnn] -> SomeAnnotation someAnnValue xs = foldr (fn . someSymbolVal) (MkSomeAnnotation (Proxy :: Proxy '[])) xs@@ -30,5 +35,7 @@ somesymbs = map someSymbolVal xs fn ss (MkSomeAnnotation pxs) = withSomeSymbol ss (\px -> MkSomeAnnotation (px `proxyCons` pxs)) +-- |+-- @since 0.2.0.0 proxyCons :: forall (x :: Symbol) (xs :: [Symbol]) . Proxy x -> Proxy xs -> Proxy (x ': xs) proxyCons _ _ = Proxy
src/Data/TypedEncoding/Common/Types/SomeEnc.hs view
@@ -1,11 +1,5 @@ {-# LANGUAGE GADTs #-} {-# LANGUAGE ScopedTypeVariables #-}--- {-# LANGUAGE PolyKinds #-}--- {-# LANGUAGE DataKinds #-}--- {-# LANGUAGE TypeOperators #-}--- {-# LANGUAGE FlexibleInstances #-}--- {-# LANGUAGE StandaloneDeriving #-}--- {-# LANGUAGE TypeApplications #-} {-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE RankNTypes #-} @@ -29,12 +23,18 @@ -- | Existentially quantified quantified @Enc@ -- effectively isomorphic to 'CheckedEnc'+--+-- @since 0.2.0.0 data SomeEnc conf str where MkSomeEnc :: SymbolList xs => Enc xs conf str -> SomeEnc conf str- ++-- |+-- @since 0.2.0.0 withSomeEnc :: SomeEnc conf str -> (forall xs . SymbolList xs => Enc xs conf str -> r) -> r withSomeEnc (MkSomeEnc enc) f = f enc +-- |+-- @since 0.2.0.0 toSome :: SymbolList xs => Enc xs conf str -> SomeEnc conf str toSome = MkSomeEnc @@ -42,6 +42,8 @@ -- >>> let enctest = unsafeSetPayload () "hello" :: Enc '["TEST"] () T.Text -- >>> someToChecked . MkSomeEnc $ enctest -- UnsafeMkCheckedEnc ["TEST"] () "hello"+-- +-- @since 0.2.0.0 someToChecked :: SomeEnc conf str -> CheckedEnc conf str someToChecked se = withSomeEnc se toCheckedEnc @@ -49,6 +51,8 @@ -- >>> let tst = unsafeCheckedEnc ["TEST"] () "test" -- >>> displ $ checkedToSome tst -- "Some (Enc '[TEST] () (String test))"+-- +-- @since 0.2.0.0 s checkedToSome :: CheckedEnc conf str -> SomeEnc conf str checkedToSome (UnsafeMkCheckedEnc xs c s) = withSomeAnnotation (someAnnValue xs) (\p -> MkSomeEnc (UnsafeMkEnc p c s))
src/Data/TypedEncoding/Common/Types/UncheckedEnc.hs view
@@ -30,14 +30,22 @@ -- @CheckedEnc@ it can contain payloads that have invalid encoding. -- -- See 'Data.TypedEncoding.Combinators.Validate.check'+-- +-- @since 0.2.0.0 data UncheckedEnc c str = MkUncheckedEnc [EncAnn] c str deriving (Show, Eq) +-- |+-- @since 0.2.0.0 toUncheckedEnc :: [EncAnn] -> c -> str -> UncheckedEnc c str toUncheckedEnc = MkUncheckedEnc +-- |+-- @since 0.2.0.0 getUncheckedEncAnn :: UncheckedEnc c str -> [EncAnn] getUncheckedEncAnn (MkUncheckedEnc ann _ _) = ann +-- |+-- @since 0.2.0.0 verifyAnn :: forall xs c str . SymbolList xs => UncheckedEnc c str -> Either String (UncheckedEnc c str) verifyAnn x@(MkUncheckedEnc xs _ _) = let p = Proxy :: Proxy xs
src/Data/TypedEncoding/Common/Types/Unsafe.hs view
@@ -4,6 +4,8 @@ {-# LANGUAGE TypeOperators #-} {-# LANGUAGE FlexibleInstances #-} +-- |+-- Unsafe ops inside encoding module Data.TypedEncoding.Common.Types.Unsafe where import Data.Proxy@@ -12,8 +14,12 @@ -- | Allows to operate within Enc. These are considered unsafe. -- keeping the same list of encodings +--+-- @since 0.1.0.0 newtype Unsafe enc conf str = Unsafe {runUnsafe :: Enc enc conf str} deriving (Show) +-- |+-- @since 0.1.0. withUnsafe :: (Unsafe e c s1 -> Unsafe e c s2) -> Enc e c s1 -> Enc e c s2 withUnsafe f enc = runUnsafe . f $ Unsafe enc
src/Data/TypedEncoding/Common/Types/Validation.hs view
@@ -39,11 +39,15 @@ -- For "enc-" encodings this will typically be decoding step. -- -- For "r-" encodings this will typically be encoding step.+--+-- @since 0.3.0.0 data Validation f (nm :: Symbol) (alg :: Symbol) conf str where UnsafeMkValidation :: Proxy nm -> (forall (xs :: [Symbol]) . Enc (nm ': xs) conf str -> f (Enc xs conf str)) -> Validation f nm alg conf str -- | Type safe smart constructor -- adding the type family @(AlgNm nm)@ restriction to UnsafeMkValidation slows down compilation, especially in tests. +--+-- @since 0.3.0.0 mkValidation :: forall f (nm :: Symbol) conf str . (forall (xs :: [Symbol]) . Enc (nm ': xs) conf str -> f (Enc xs conf str)) -> Validation f nm (AlgNm nm) conf str mkValidation = UnsafeMkValidation Proxy @@ -53,6 +57,8 @@ -- | Same as 'runValidation" but compiler figures out algorithm name -- -- Using it can slowdown compilation+--+-- @since 0.3.0.0 _runValidation :: forall nm f xs conf str alg . (AlgNm nm ~ alg) => Validation f nm alg conf str -> Enc (nm ': xs) conf str -> f (Enc xs conf str) _runValidation = runValidation @(AlgNm nm) @@ -61,6 +67,8 @@ -- -- Similarly to 'Validation' it can be used with a typeclass -- 'Data.TypedValidation.Internal.Class.Encode.EncodeAll'+--+-- @since 0.3.0.0 data Validations f (nms :: [Symbol]) (algs :: [Symbol]) conf str where -- | constructor is to be treated as Unsafe to Encode and Decode instance implementations -- particular encoding instances may expose smart constructors for limited data types@@ -69,6 +77,8 @@ -- | This basically puts payload in decoded state. -- More useful combinators are in "Data.TypedEncoding.Combinators.Validate"+--+-- @since 0.3.0.0 runValidationChecks :: forall algs nms f c str . (Monad f) => Validations f nms algs c str -> Enc nms c str -> f (Enc ('[]::[Symbol]) c str) runValidationChecks ZeroV enc0 = pure enc0 runValidationChecks (ConsV fn xs) enc =
src/Data/TypedEncoding/Common/Util/TypeLits.hs view
@@ -34,40 +34,60 @@ -- $setup -- >>> :set -XScopedTypeVariables -XTypeFamilies -XKindSignatures -XDataKinds +-- !+-- @since 0.2.1.0 type family AcceptEq (msg :: ErrorMessage) (c :: Ordering) :: Bool where AcceptEq _ EQ = True AcceptEq msg _ = TypeError msg +-- !+-- @since 0.2.1.0 type family And (b1 :: Bool) (b2 :: Bool) :: Bool where And 'True 'True = 'True And _ _ = 'False +-- !+-- @since 0.2.1.0 type family Or (b1 :: Bool) (b2 :: Bool) :: Bool where Or 'False 'False = 'False Or _ _ = 'True +-- !+-- @since 0.2.1.0 type family Repeat (n :: Nat) (s :: Symbol) :: Symbol where Repeat 0 s = "" Repeat n s = AppendSymbol s (Repeat (n - 1) s) +-- !+-- @since 0.2.1.0 type family Fst (s :: (k,h)) :: k where Fst ('(,) a _) = a type family Dupl (s :: k) :: (k,k) where Dupl a = '(,) a a --- | :kind! Concat (LDrop 6 (ToList "bool: \"r-ban:ff-ff\" | \"r-ban:ffff\""))+-- | +-- >>> :kind! Concat (LDrop 6 (ToList "bool: \"r-ban:ff-ff\" | \"r-ban:ffff\""))+-- ...+-- = "\"r-ban:ff-ff\" | \"r-ban:ffff\""+-- +-- @since 0.2.1.0 type family Concat (s :: [Symbol]) :: Symbol where Concat '[] = "" Concat (x ': xs) = AppendSymbol x (Concat xs) -+-- !+-- @since 0.2.1.0 type family Drop (n :: Nat) (s :: Symbol) :: Symbol where Drop n s = Concat (LDrop n (ToList s)) -- TODO create TypeList.List module ? --- | :kind! LDrop 6 (ToList "bool: \"r-ban:ff-ff\" | \"r-ban:ffff\"")+-- :kind! LDrop 6 (ToList "bool: \"r-ban:ff-ff\" | \"r-ban:ffff\"")++-- | +-- +-- @since 0.2.1.0 type family LDrop (n :: Nat) (s :: [k]) :: [k] where LDrop 0 s = s LDrop n '[] = '[]@@ -81,21 +101,36 @@ -- Drop n s v = Concat (LDrop n (ToList s)) -- | --- :kind! Take 3 "123456"+-- >>> :kind! Take 3 "123456"+-- ...+-- = "123"+-- +-- @since 0.2.1.0 type family Take (n :: Nat) (s :: Symbol) :: Symbol where Take n s = Concat (LTake n (ToList s)) --- | :kind! LTake 3 (ToList "123456")+-- :kind! LTake 3 (ToList "123456")++-- | +-- +-- @since 0.2.1.0 type family LTake (n :: Nat) (s :: [k]) :: [k] where LTake 0 s = '[] LTake n '[] = '[] LTake n (x ': xs) = x ': LTake (n - 1) xs -- --- :kind! TakeUntil "findme:blah" ":"+-- >>> kind! TakeUntil "findme:blah" ":"+-- ...+-- = "findme"+--+-- @since 0.2.1.0 type family TakeUntil (s :: Symbol) (stop :: Symbol) :: Symbol where TakeUntil s stop = Concat (LTakeUntil (ToList s) stop) +-- | +-- +-- @since 0.2.1.0 type family LTakeUntil (s :: [Symbol]) (stop :: Symbol) :: [Symbol] where LTakeUntil '[] _ = '[] LTakeUntil (x ': xs) stop = LTakeUntilHelper (x ': LTakeUntil xs stop) (CmpSymbol x stop)@@ -105,10 +140,15 @@ LTakeUntilHelper (x ': xs) 'EQ = '[] LTakeUntilHelper (x ': xs) _ = (x ': xs) -+-- | +-- +-- @since 0.2.1.0 type family Length (s :: Symbol) :: Nat where Length x = LLengh (ToList x) +-- | +-- +-- @since 0.2.1.0 type family LLengh (s :: [k]) :: Nat where LLengh '[] = 0 LLengh (x ': xs) = 1 + LLengh xs@@ -118,6 +158,8 @@ -- >>> :kind! LLast '["1","2","3"] -- ... -- = "3"+--+-- @since 0.2.2.0 type family LLast (s :: [Symbol]) :: Symbol where LLast '[] = TypeError ('Text "Empty Symbol list not allowed") LLast '[x] = x@@ -125,16 +167,22 @@ -- |--- Concat (Snoc '["1","2","3"] "4") +-- >>> :kind! Concat (Snoc '["1","2","3"] "4") -- ... -- = "1234"+--+-- @since 0.2.2.0 type family Snoc (s :: [k]) (t :: k) :: [k] where Snoc '[] x = '[x] Snoc (x ': xs) y = x ': Snoc xs y -- |--- :kind! UnSnoc '["1","2","3"] +-- :kind! UnSnoc '["1","2","3"] +-- ...+-- = '( (':) Symbol "1" ((':) Symbol "2" ('[] Symbol)), "3")+--+-- @since 0.2.2.0 type family UnSnoc (s :: [k]) :: ([k], k) where UnSnoc '[] = TypeError ('Text "Empty list, no last element") UnSnoc '[x] = '(,) '[] x
src/Data/TypedEncoding/Conv/ByteString/Char8.hs view
@@ -22,6 +22,8 @@ -- -- Because of how @ByteString.Char8.pack@ works, the first encoding (last in the list) must restrict character set to a subset of @ASCII@. --+-- Currently this uses (an over-conservative) @"r-ASCII"@ superset constraint, in the future, this could be relaxed to a superset of /ASCII/, e.g. /r-CHAR8/ when one is in place.+-- -- >>> :t pack (undefined :: Enc '["r-bar", "r-foo"] () String) -- ... -- ... error:@@ -39,3 +41,5 @@ -- See 'pack' unpack :: (Knds.LLast xs ~ t, IsSuperset "r-ASCII" t ~ 'True) => Enc xs c B8.ByteString -> Enc xs c String unpack = unsafeChangePayload B8.unpack ++-- TODO consider adding "r-CHAR8"
src/Data/TypedEncoding/Instances/Do/Sample.hs view
@@ -22,7 +22,8 @@ import Data.TypedEncoding.Instances.Support import Data.TypedEncoding.Instances.Support.Unsafe -+-- |+-- @since 0.3.0.0 instance Applicative f => Encode f "do-UPPER" "do-UPPER" c T.Text where encoding = _implEncodingP T.toUpper @@ -35,30 +36,39 @@ else Left $ "Found not upper case chars " ++ T.unpack b) ) - instance Applicative f => Encode f "do-UPPER" "do-UPPER" c TL.Text where encoding = _implEncodingP TL.toUpper -+-- |+-- @since 0.3.0.0 instance Applicative f => Encode f "do-lower" "do-lower" c T.Text where encoding = _implEncodingP T.toLower instance Applicative f => Encode f "do-lower" "do-lower" c TL.Text where encoding = _implEncodingP TL.toLower +-- |+-- @since 0.3.0.0 instance Applicative f => Encode f "do-Title" "do-Title" c T.Text where encoding = _implEncodingP T.toTitle instance Applicative f => Encode f "do-Title" "do-Title" c TL.Text where encoding = _implEncodingP TL.toTitle +-- |+-- @since 0.3.0.0 instance Applicative f => Encode f "do-reverse" "do-reverse" c T.Text where encoding = _implEncodingP T.reverse instance Applicative f => Encode f "do-reverse" "do-reverse" c TL.Text where encoding = _implEncodingP TL.reverse +-- |+-- @since 0.1.0.0 newtype SizeLimit = SizeLimit {unSizeLimit :: Int} deriving (Eq, Show)++-- |+-- @since 0.3.0.0 instance (HasA SizeLimit c, Applicative f) => Encode f "do-size-limit" "do-size-limit" c T.Text where encoding = _implEncodingConfP (T.take . unSizeLimit . has @ SizeLimit) instance (HasA SizeLimit c, Applicative f) => Encode f "do-size-limit" "do-size-limit" c B.ByteString where
src/Data/TypedEncoding/Instances/Enc/Base64.hs view
@@ -7,6 +7,8 @@ {-# LANGUAGE TypeFamilies #-} -- | Defines /Base64/ encoding+--+-- @since 0.1.0.0 module Data.TypedEncoding.Instances.Enc.Base64 where import Data.TypedEncoding@@ -35,9 +37,13 @@ -- * Conversions ----------------- +-- |+-- @since 0.1.0.0 acceptLenientS :: Enc ("enc-B64-len" ': ys) c B.ByteString -> Enc ("enc-B64" ': ys) c B.ByteString acceptLenientS = withUnsafeCoerce (B64.encode . B64.decodeLenient) +-- |+-- @since 0.1.0.0 acceptLenientL :: Enc ("enc-B64-len" ': ys) c BL.ByteString -> Enc ("enc-B64" ': ys) c BL.ByteString acceptLenientL = withUnsafeCoerce (BL64.encode . BL64.decodeLenient) @@ -47,7 +53,12 @@ -- >>> let tstB64 = encodeAll . toEncoding () $ "Hello World" :: Enc '["enc-B64"] () B.ByteString -- >>> displ (flattenAs tstB64 :: Enc '["r-ASCII"] () B.ByteString) -- "Enc '[r-ASCII] () (ByteString SGVsbG8gV29ybGQ=)"+--+-- @since 0.1.0.0 instance FlattenAs "r-ASCII" "enc-B64-nontext" where++-- |+-- @since 0.1.0.0 instance FlattenAs "r-ASCII" "enc-B64" where -- |@@ -69,20 +80,30 @@ -- * Encoders +-- |+-- @since 0.3.0.0 instance Applicative f => Encode f "enc-B64" "enc-B64" c B.ByteString where encoding = encB64B +-- |+-- @since 0.3.0.0 encB64B :: Applicative f => Encoding f "enc-B64" "enc-B64" c B.ByteString encB64B = _implEncodingP B64.encode +-- |+-- @since 0.3.0.0 instance Applicative f => Encode f "enc-B64" "enc-B64" c BL.ByteString where encoding = encB64BL +-- |+-- @since 0.3.0.0 encB64BL :: Applicative f => Encoding f "enc-B64" "enc-B64" c BL.ByteString encB64BL = _implEncodingP BL64.encode -- | This instance will likely be removed in future versions (performance concerns)+--+-- @since 0.3.0.0 instance Applicative f => Encode f "enc-B64" "enc-B64" c T.Text where encoding = endB64T @@ -92,6 +113,8 @@ -- * Decoders +-- |+-- @since 0.3.0.0 instance (UnexpectedDecodeErr f, Applicative f) => Decode f "enc-B64" "enc-B64" c B.ByteString where decoding = decB64B @@ -100,12 +123,18 @@ -- It is a well known encoding and hackers will have no problem -- making undetectable changes, but error handling at this stage -- could verify that email was corrupted.+--+-- @since 0.3.0.0 decB64B :: (UnexpectedDecodeErr f, Applicative f) => Decoding f "enc-B64" "enc-B64" c B.ByteString decB64B = _implDecodingF (asUnexpected @"enc-B64" . B64.decode) +-- |+-- @since 0.3.0.0 instance (UnexpectedDecodeErr f, Applicative f) => Decode f "enc-B64" "enc-B64" c BL.ByteString where decoding = decB64BL +-- |+-- @since 0.3.0.0 decB64BL :: (UnexpectedDecodeErr f, Applicative f) => Decoding f "enc-B64" "enc-B64" c BL.ByteString decB64BL = _implDecodingF (asUnexpected @"enc-B64" . BL64.decode) @@ -113,17 +142,25 @@ -- Kept for now but performance issues -- | WARNING (performance)+--+-- @since 0.3.0.0 instance (UnexpectedDecodeErr f, Applicative f) => Decode f "enc-B64" "enc-B64" c T.Text where decoding = decB64T +-- |+-- @since 0.3.0.0 decB64T :: (UnexpectedDecodeErr f, Applicative f) => Decoding f "enc-B64" "enc-B64" c T.Text decB64T = _implDecodingF (asUnexpected @"enc-B64" . fmap TE.decodeUtf8 . B64.decode . TE.encodeUtf8) {-# WARNING decB64T "This method was not optimized for performance." #-} -- | WARNING (performance)+--+-- @since 0.3.0.0 instance (UnexpectedDecodeErr f, Applicative f) => Decode f "enc-B64" "enc-B64" c TL.Text where decoding = decB64TL +-- |+-- @since 0.3.0.0 decB64TL :: (UnexpectedDecodeErr f, Applicative f) => Decoding f "enc-B64" "enc-B64" c TL.Text decB64TL = _implDecodingF (asUnexpected @"enc-B64" . fmap TEL.decodeUtf8 . BL64.decode . TEL.encodeUtf8) {-# WARNING decB64TL "This method was not optimized for performance." #-}@@ -131,23 +168,35 @@ -- * Validation +-- |+-- @since 0.3.0.0 instance (RecreateErr f, Applicative f) => Validate f "enc-B64" "enc-B64" c B.ByteString where validation = validFromDec decB64B +-- |+-- @since 0.3.0.0 instance (RecreateErr f, Applicative f) => Validate f "enc-B64" "enc-B64" c BL.ByteString where validation = validFromDec decB64BL +-- |+-- @since 0.3.0.0 instance (RecreateErr f, Applicative f) => Validate f "enc-B64" "enc-B64" c T.Text where validation = validFromDec decB64T +-- |+-- @since 0.3.0.0 instance (RecreateErr f, Applicative f) => Validate f "enc-B64" "enc-B64" c TL.Text where validation = validFromDec decB64TL -- | Lenient decoding does not fail+-- +-- @since 0.3.0.0 instance Applicative f => Validate f "enc-B64-len" "enc-B64-len" c B.ByteString where validation = mkValidation $ implTranP id -- | Lenient decoding does not fail+-- +-- @since 0.3.0.0 instance Applicative f => Validate f "enc-B64-len" "enc-B64-len" c BL.ByteString where validation = mkValidation $ implTranP id
src/Data/TypedEncoding/Instances/Restriction/ASCII.hs view
@@ -19,6 +19,8 @@ -- -- >>> encodeFAll . toEncoding () $ "\194\160" :: Either EncodeEx (Enc '["r-ASCII"] () T.Text) -- Left (EncodeEx "r-ASCII" (NonAsciiChar '\194'))+--+-- @since 0.1.0.0 module Data.TypedEncoding.Instances.Restriction.ASCII where import Data.TypedEncoding.Instances.Support
src/Data/TypedEncoding/Instances/Restriction/Bool.hs view
@@ -27,7 +27,8 @@ -- @ -- -- Expected behavior is described next to the corresponding combinator.-+--+-- @since 0.2.2.0 module Data.TypedEncoding.Instances.Restriction.Bool where
src/Data/TypedEncoding/Instances/Restriction/Misc.hs view
@@ -9,6 +9,10 @@ {-# LANGUAGE ScopedTypeVariables #-} -- | Common /restriction/ "r-" instances+--+-- Before v0.3 @Data.TypedEncoding.Instances.Restriction.Common@+--+-- @since 0.2.0.0 module Data.TypedEncoding.Instances.Restriction.Misc where import Data.Word
src/Data/TypedEncoding/Instances/Restriction/UTF8.hs view
@@ -1,16 +1,18 @@ {-# LANGUAGE DataKinds #-}-{-# LANGUAGE KindSignatures #-}+--{-# LANGUAGE KindSignatures #-} {-# LANGUAGE PolyKinds #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE OverloadedStrings #-}+--{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE PartialTypeSignatures #-}-{-# LANGUAGE TypeApplications #-}+--{-# LANGUAGE TypeApplications #-} -- | 'UTF-8' encoding+--+-- @since 0.1.0.0 module Data.TypedEncoding.Instances.Restriction.UTF8 where import Data.TypedEncoding.Instances.Support@@ -59,9 +61,18 @@ -- -- Following test uses 'verEncoding' helper that checks that bytes are encoded as Right iff they are valid UTF8 bytes ----- prop> \(b :: B.ByteString) -> verEncoding b (fmap (fromEncoding . decodeAll . proxiedId (Proxy :: Proxy (Enc '["r-UTF8"] _ _))) . (encodeFAll :: _ -> Either EncodeEx _). toEncoding () $ b)+-- >>> :{ +-- quickCheck $ \(b :: B.ByteString) -> verEncoding b $ fmap (+-- fromEncoding +-- . decodeAll @'["r-UTF8"]+-- ) . encodeFAll @'["r-UTF8"] @(Either EncodeEx)+-- . toEncoding () $ b+-- :}+-- +++ OK, passed 100 tests.+ instance Encode (Either EncodeEx) "r-UTF8" "r-UTF8" c B.ByteString where encoding = encUTF8B+ instance Encode (Either EncodeEx) "r-UTF8" "r-UTF8" c BL.ByteString where encoding = encUTF8BL :: Encoding (Either EncodeEx) "r-UTF8" "r-UTF8" c BL.ByteString
src/Data/TypedEncoding/Instances/Support/Common.hs view
@@ -25,12 +25,18 @@ -- * Decoding -- | Universal decoding for all "r-" types+--+-- @since 0.3.0.0 decAnyR :: forall r f c str . (Restriction r, Applicative f) => Decoding f r r c str decAnyR = decAnyR' @r @r +-- |+-- @since 0.3.0.0 decAnyR' :: forall alg r f c str . (Restriction r, Applicative f) => Decoding f r alg c str decAnyR' = UnsafeMkDecoding Proxy (implTranP id) +-- |+-- @since 0.3.0.0 decAnyR_ :: forall r f c str alg . (Restriction r, Algorithm r alg, Applicative f) => Decoding f r alg c str decAnyR_ = mkDecoding $ implTranP id
src/Data/TypedEncoding/Instances/Support/Decode.hs view
@@ -9,6 +9,8 @@ {-# LANGUAGE FlexibleContexts #-} -- | v0.2 style decoding combinators+-- +-- @since 0.3.0.0 module Data.TypedEncoding.Instances.Support.Decode where import Data.TypedEncoding.Instances.Support.Unsafe
src/Data/TypedEncoding/Instances/Support/Encode.hs view
@@ -8,7 +8,9 @@ {-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE FlexibleContexts #-} -+-- | v0.2 style encoding combinators+-- +-- @since 0.3.0.0 module Data.TypedEncoding.Instances.Support.Encode where import Data.TypedEncoding.Instances.Support.Unsafe
src/Data/TypedEncoding/Instances/Support/Helpers.hs view
@@ -32,24 +32,32 @@ -- | allows to fold payload in Enc to create another Enc, assumes homogeneous input encodings. -- This yields not a type safe code, better implementation code should use fixed size -- dependently typed @Vect n@ or some @HList@ like foldable.+--+-- @since 0.2.0.0 foldEnc :: forall (xs2 :: [Symbol]) (xs1 :: [Symbol]) f c s1 s2 . (Foldable f, Functor f) => c -> (s1 -> s2 -> s2) -> s2 -> f (Enc xs1 c s1) -> Enc xs2 c s2 foldEnc c f sinit = unsafeSetPayload c . foldr f sinit . fmap getPayload -- | Similar to 'foldEnc', assumes that destination payload has @IsString@ instance and uses @""@ as base case. +--+-- @since 0.2.0.0 foldEncStr :: forall (xs2 :: [Symbol]) (xs1 :: [Symbol]) f c s1 s2 . (Foldable f, Functor f, IsString s2) => c -> (s1 -> s2 -> s2) -> f (Enc xs1 c s1) -> Enc xs2 c s2 foldEncStr c f = foldEnc c f "" -- | Similar to 'foldEnc', works with untyped 'CheckedEnc'+--+-- @since 0.2.0.0 foldCheckedEnc :: forall (xs2 :: [Symbol]) f c s1 s2 . (Foldable f, Functor f) => c -> ([EncAnn] -> s1 -> s2 -> s2) -> s2 -> f (CheckedEnc c s1) -> Enc xs2 c s2 foldCheckedEnc c f sinit = unsafeSetPayload c . foldr (uncurry f) sinit . fmap getCheckedEncPayload -- | Similar to 'foldEncStr', works with untyped 'CheckedEnc'+--+-- @since 0.2.0.0 foldCheckedEncStr :: forall (xs2 :: [Symbol]) f c s1 s2 . (Foldable f, Functor f, IsString s2) => c -> ([EncAnn] -> s1 -> s2 -> s2) -> f (CheckedEnc c s1) -> Enc xs2 c s2 foldCheckedEncStr c f = foldCheckedEnc c f "" @@ -57,6 +65,8 @@ -- * Composite encoding: Recreate and Encode helpers -- | Splits composite payload into homogenious chunks+--+-- @since 0.2.0.0 splitPayload :: forall (xs2 :: [Symbol]) (xs1 :: [Symbol]) c s1 s2 . (s1 -> [s2]) -> Enc xs1 c s1 @@ -64,6 +74,8 @@ splitPayload f (UnsafeMkEnc _ c s1) = map (UnsafeMkEnc Proxy c) (f s1) -- | Untyped version of 'splitPayload'+--+-- @since 0.2.0.0 splitSomePayload :: forall c s1 s2 . ([EncAnn] -> s1 -> [([EncAnn], s2)]) -> CheckedEnc c s1 @@ -83,6 +95,8 @@ -- -- >>> verifyWithRead @Word8 "Word8-decimal" (T.pack "123") -- Right "123"+--+-- @since 0.2.0.0 verifyWithRead :: forall a str . (IsStringR str, Read a, Show a) => String -> str -> Either String str verifyWithRead msg x = let s = toString x@@ -96,6 +110,8 @@ -- | Convenience function for checking if @str@ decodes without error -- using @enc@ encoding markers and decoders that can pick decoder based -- on that marker+--+-- @since 0.3.0.0 verifyDynEnc :: forall s str err1 err2 enc a. (KnownSymbol s, Show err1, Show err2) => Proxy s -- ^ proxy defining encoding annotation -> (Proxy s -> Either err1 enc) -- ^ finds encoding marker @enc@ for given annotation or fails
src/Data/TypedEncoding/Instances/Support/Unsafe.hs view
@@ -17,19 +17,28 @@ import Data.TypedEncoding.Combinators.Unsafe -+-- |+-- @since 0.1.0.0 implTranF :: Functor f => (str -> f str) -> Enc enc1 conf str -> f (Enc enc2 conf str) implTranF f = implTranF' (const f) +-- |+-- @since 0.1.0.0 implTranF' :: Functor f => (conf -> str -> f str) -> Enc enc1 conf str -> f (Enc enc2 conf str) implTranF' f (UnsafeMkEnc _ conf str) = UnsafeMkEnc Proxy conf <$> f conf str +-- |+-- @since 0.1.0.0 implTranP :: Applicative f => (str -> str) -> Enc enc1 conf str -> f (Enc enc2 conf str) implTranP f = implTranF' (\c -> pure . f) +-- |+-- @since 0.1.0.0 implTranP' :: Applicative f => (conf -> str -> str) -> Enc enc1 conf str -> f (Enc enc2 conf str) implTranP' f = implTranF' (\c -> pure . f c) +-- |+-- @since 0.2.1.0 implChangeAnn :: Functor f => (Enc enc1 conf str -> f (Enc enc2a conf str)) -> Enc enc1 conf str -> f (Enc enc2b conf str) implChangeAnn fn = fmap (withUnsafeCoerce id) . fn
src/Data/TypedEncoding/Instances/Support/Validate.hs view
@@ -25,9 +25,13 @@ -- * Validation +-- |+-- @since 0.3.0.0 validFromDec :: forall nm f c str . (KnownSymbol nm, RecreateErr f, Applicative f) => Decoding (Either UnexpectedDecodeEx) nm nm c str -> Validation f nm nm c str validFromDec = validFromDec' @nm @nm +-- |+-- @since 0.3.0.0 validFromDec' :: forall alg nm f c str . (KnownSymbol nm, RecreateErr f, Applicative f) => Decoding (Either UnexpectedDecodeEx) nm alg c str -> Validation f nm alg c str validFromDec' (UnsafeMkDecoding p fn) = UnsafeMkValidation p (decAsRecreateErr . fn) where @@ -35,15 +39,19 @@ decAsRecreateErr (Left (UnexpectedDecodeEx p err)) = recoveryErr $ RecreateEx p err decAsRecreateErr (Right r) = pure r -+-- |+-- @since 0.3.0.0 validR :: forall nm f c str . (Restriction nm, KnownSymbol nm, RecreateErr f, Applicative f) => Encoding (Either EncodeEx) nm nm c str -> Validation f nm nm c str validR = validFromEnc' @nm @nm -- | Can cause slow compilation if used+-- +-- @since 0.3.0.0 validR' :: forall nm f c str alg . (Restriction nm, Algorithm nm alg, KnownSymbol nm, RecreateErr f, Applicative f) => Encoding (Either EncodeEx) nm alg c str -> Validation f nm alg c str validR' = validFromEnc' @alg @nm -+-- |+-- @since 0.3.0.0 validFromEnc' :: forall alg nm f c str . (KnownSymbol nm, RecreateErr f, Applicative f) => Encoding (Either EncodeEx) nm alg c str -> Validation f nm alg c str validFromEnc' (UnsafeMkEncoding p fn) = UnsafeMkValidation p (encAsRecreateErr . rfn) where
src/Examples/TypedEncoding/Conversions.hs view
@@ -38,7 +38,7 @@ -- EncodeF SomeErr (Enc xs () Text) (Enc ("enc-B64" ': xs) () Text) -- @ -- --- Then @typed-encoding@ expects @pack@ @encodeF@ to commute (if encoding instances exist):+-- Then /typed-encoding/ expects @pack@ @encodeF@ to commute (if encoding instances exist): -- -- @ -- str -- EncT.pack --> txt@@ -102,7 +102,7 @@ helloAsciiT = EncTe.decodeUtf8 helloAsciiB -- ^ -- We use a tween function of the popular 'Data.Text.Encoding.decodeUtf8' --- from the @test@ package.+-- from the /text/ package. -- -- Notice the encoding annotation is preserved. --@@ -128,15 +128,18 @@ -- ... -- -- this does not compile. And it should not. @pack@ from "Data.ByteString.Char8" is error prone.--- It is not an injection as it only considers first 7 bits of information from each 'Char'. --- I doubt that there are any code examples of its intentional use on a String that is not ASCII. --- --- @EncB8.pack@ will not compile unless the encoding is ASCII restricted, this works:+-- It is not an injection as it only considers first 8 bits of information from each 'Char'. +-- I doubt that there are any code examples of its intentional use on a String that has chars @> \'\255\'@.+--+-- Current version of pack @EncB8.pack@ will not compile unless the encoding is ASCII restricted (@< \'\128\'@).+-- This works: -- -- >>> fmap (displ . EncB8.pack) . encodeFAll @'["r-ASCII"] @(Either EncodeEx) $ helloZero -- Right "Enc '[r-ASCII] () (ByteString Hello)" -- -- And the result is a @ByteString@ with bonus annotation describing its content.+--+-- Future versions are likely to relax this restriction to a more permissive "r-" annotation that allows for any char @<= \'\255\'@ helloRestricted :: Either EncodeEx (Enc '["r-ban:zzzzz"] () B.ByteString)
src/Examples/TypedEncoding/DiySignEncoding.hs view
@@ -102,15 +102,19 @@ -- Right (UnsafeMkEnc Proxy () "11:Hello World") --- | Because encoding function is pure we can create instance of EncodeF --- that is polymorphic in effect @f@. This is done using 'EnT.implTranP' combinator.+-- | Because encoding function is pure we can create instance of 'Encode' +-- that is polymorphic in effect @f@. +--+-- This is done using 'EnT.implTranP' combinator. instance Applicative f => Encode f "my-sign" "my-sign" c T.Text where encoding = EnT._implEncodingP encodeSign -- | Decoding allows effectful @f@ to allow for troubleshooting and unsafe payload changes. -- -- Implementation simply uses 'EnT.implDecodingF' combinator on the 'asUnexpected' composed with decoding function.+-- -- 'UnexpectedDecodeErr' has Identity instance allowing for decoding that assumes errors are not possible.+-- -- For debugging purposes or when unsafe changes to "my-sign" @Error UnexpectedDecodeEx@ instance can be used. instance (UnexpectedDecodeErr f, Applicative f) => Decode f "my-sign" "my-sign" c T.Text where decoding = decMySign @@ -119,6 +123,7 @@ decMySign = EnT.implDecodingF (asUnexpected @"my-sign" . decodeSign) -- | Recreation allows effectful @f@ to check for tampering with data.+-- -- Implementation simply uses 'EnT.validFromDec' combinator on the recovery function. instance (RecreateErr f, Applicative f) => Validate f "my-sign" "my-sign" c T.Text where validation = EnT.validFromDec decMySign
src/Examples/TypedEncoding/Overview.hs view
@@ -68,7 +68,7 @@ -- >>> fmap displ . runEncodings' @'["enc-B64","enc-B64"] @'["enc-B64","enc-B64"] @Identity encodings . toEncoding () $ ("Hello World" :: B.ByteString) -- Identity "Enc '[enc-B64,enc-B64] () (ByteString U0dWc2JHOGdWMjl5YkdRPQ==)" ----- This is how @typed-encoding@ works, the "Data.TypedEncoding.Common.Class.Encode.EncodeAll"+-- This is how /typed-encoding/ works, the "Data.TypedEncoding.Common.Class.Encode.EncodeAll" -- constraint can be used to get access to list to encodings required by the symbol annotation. -- 'runEncodings'' executes all the necessary transformations. --
typed-encoding.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: f053eb403362652b43e8d0680f5e3a36c5eff26bb2f32fe383f0ab4612ba3c0f+-- hash: b3491bbd06ee3c10f1a7f4c04cd6ab96fe78edacd8d4e8023e47e303ce1b12b0 name: typed-encoding-version: 0.3.0.0+version: 0.3.0.1 synopsis: Type safe string transformations description: See README.md in the project github repository. category: Data, Text