packages feed

typed-encoding 0.3.0.0 → 0.3.0.1

raw patch · 44 files changed

+416/−74 lines, 44 files

Files

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