packages feed

co-log-effectful (empty) → 0.0.0.1

raw patch · 6 files changed

+295/−0 lines, 6 filesdep +QuickCheckdep +basedep +bytestring

Dependencies added: QuickCheck, base, bytestring, co-log-core, co-log-effectful, effectful, effectful-core, effectful-plugin, tasty, tasty-golden, tasty-hunit, tasty-quickcheck, text

Files

+ CHANGELOG.md view
@@ -0,0 +1,5 @@+# Revision history for placeholder++## 0.0.0.1 -- YYYY-mm-dd++* First version. Released on an unsuspecting world.
+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2023, Eldritch Cookie++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Eldritch Cookie nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ co-log-effectful.cabal view
@@ -0,0 +1,109 @@+cabal-version:   3.4++-- The cabal-version field refers to the version of the .cabal specification,+-- and can be different from the cabal-install (the tool) version and the+-- Cabal (the library) version you are using. As such, the Cabal (the library)+-- version used must be equal or greater than the version stated in this field.+-- Starting from the specification version 2.2, the cabal-version field must be+-- the first thing in the cabal file.++-- Initial package description 'placeholder' generated by+-- 'cabal init'. For further documentation, see:+--   http://haskell.org/cabal/users-guide/+--+-- The name of the package.+name:            co-log-effectful+synopsis:        effectful log effect using co-log-core+description:+  co-log-effectful provides a `Log` effect for effectful that can use `LogAction`s in the `Eff` monad++category:        library, logging, control, bsd3 ++-- The package version.+-- See the Haskell package versioning policy (PVP) for standards+-- guiding when and how versions should be incremented.+-- https://pvp.haskell.org+-- PVP summary:     +-+------- breaking API changes+--                  | | +----- non-breaking API additions+--                  | | | +--- code changes with no API change+version:         0.0.0.1+homepage:        https://github.com/eldritch-cookie/co-log-effectful+bug-reports:     https://github.com/eldritch-cookie/co-log-effectful/issues++-- The license under which the package is released.+license:         BSD-3-Clause++-- The file containing the license text.+license-file:    LICENSE++-- The package author(s).+author:          Eldritch Cookie++-- An email address to which users can send suggestions, bug reports, and patches.+maintainer:      eldritch.cookie@disroot.org++-- A copyright notice.+-- copyright:+build-type:      Simple++-- Extra doc files to be distributed with the package, such as a CHANGELOG or a README.+extra-doc-files: CHANGELOG.md+tested-with:     GHC ==9.6.6 || ==9.10.1++-- Extra source files to be distributed with the package, such as examples, or a tutorial module.+-- extra-source-files:++common deps+  ghc-options:        -Wall -fplugin=Effectful.Plugin+  build-depends:+    , base              >=4.18.2 && <5+    , bytestring        >=0.11.5 && <1+    , co-log-core       >=0.3.2  && <1+    , effectful         >=2.3.1  && <3+    , effectful-core    >=2.3.1  && <3+    , effectful-plugin  >=1.1.0  && <2+    , text              >=2.0.2  && <3++  default-extensions:+    DataKinds+    DerivingStrategies+    DerivingVia+    DuplicateRecordFields+    FunctionalDependencies+    NoCUSKs+    NoFieldSelectors+    NoStarIsType+    OverloadedLists+    OverloadedRecordDot+    OverloadedStrings+    QuantifiedConstraints+    ScopedTypeVariables+    TypeFamilyDependencies+    TypeOperators++  default-language:   GHC2021++library+  import:          deps+  exposed-modules: Effectful.Colog+  hs-source-dirs:  src++test-suite co-log-effectful-test+  import:             deps+  type:               exitcode-stdio-1.0+  hs-source-dirs:     test+  main-is:            Main.hs+  other-modules:      Effectful.CologTest+  build-depends:+    , co-log-effectful+    , QuickCheck        >=2.14.3+    , tasty             >=1.4.3+    , tasty-golden      >=2.3.5+    , tasty-hunit       >=0.10.2+    , tasty-quickcheck  >=0.10.2++  build-tool-depends: tasty-discover:tasty-discover++source-repository head+  type:     git+  location: https://github.com/eldritch-cookie/co-log-effectful
+ src/Effectful/Colog.hs view
@@ -0,0 +1,96 @@+module Effectful.Colog (+  -- * Effect+  Log,+  LogEff,+  logMsg,+  injectLog,++  -- ** Handlers+  runLogAction,+  runLogWriter,++  -- ** 'LogAction's+  tellLogEff,++  -- *** 'FileSystem' constrained+  byteStringLogEff,+  textLogEff,++  -- * Re-exports+  module Colog.Core.Action,+)+where++import Colog.Core.Action+import Data.ByteString (ByteString)+import Data.ByteString qualified as BS+import Data.Kind+import Data.Text (Text)+import Data.Text.Encoding (encodeUtf8)+import Effectful+import Effectful.Dispatch.Static+import Effectful.FileSystem (FileSystem)+import Effectful.FileSystem.IO.ByteString (hPutStr)+import Effectful.Internal.Env (Env, Relinker (..), consEnv, unconsEnv)+import Effectful.Internal.Utils (inlineBracket)+import Effectful.Writer.Static.Shared (Writer, runWriter, tell)+import System.IO (Handle)++-- | Provides the ability to log with an implicit 'LogEff'+type Log :: Type -> Effect+data Log msg m a++type instance DispatchOf (Log msg) = Static NoSideEffects+data instance StaticRep (Log msg) where+  MkLog :: forall localEs msg. !(Env localEs) -> !(LogEff localEs msg) -> StaticRep (Log msg)++-- | 'LogAction' limited to the 'Eff' monad+type LogEff es msg = LogAction (Eff es) msg++unLogEff :: forall es msg. LogEff es msg -> msg -> Env es -> IO ()+unLogEff le = unEff . unLogAction le++relinkLog :: forall msg. Relinker StaticRep (Log msg)+relinkLog = Relinker $ \relink (MkLog localEs act) -> do+  newLocalEs <- relink localEs+  pure $ MkLog newLocalEs act++-- | runs the 'Log' effect using the provided action this is the most general runner+runLogAction :: forall es msg a. LogEff es msg -> Eff (Log msg : es) a -> Eff es a+runLogAction logAct act = unsafeEff $ \env -> do+  inlineBracket+    (consEnv (MkLog env logAct) relinkLog env)+    unconsEnv+    (\es -> unEff act es)++-- | runs the 'Log' effect using 'tellLogEff' and then handles the 'Writer' effect+runLogWriter :: forall es msg a. (Monoid msg) => Eff (Log msg : es) a -> Eff es (a, msg)+runLogWriter = runWriter . runLogAction tellLogEff . inject++-- | logs a message using the implicit 'LogEff'+logMsg :: forall msg es. (Log msg :> es) => msg -> Eff es ()+logMsg message = do+  MkLog env act <- getStaticRep+  unsafeEff_ $ unLogEff act message env++-- untested++-- | converts a 'LogEff' into another compatible 'LogEff'+injectLog :: forall (xs :: [Effect]) (es :: [Effect]) a. (Subset xs es) => LogEff xs a -> LogEff es a+injectLog = hoistLogAction inject++-- | 'LogEff' that delegates to a static shared 'Writer' effect+tellLogEff :: forall es msg. (Writer msg :> es, Monoid msg) => LogEff es msg+tellLogEff = LogAction tell++-- untested++-- | 'LogEff' that writes 'Text' to a 'Handle'+textLogEff :: forall es. (FileSystem :> es) => Handle -> LogEff es Text+textLogEff hdl = LogAction $ hPutStr hdl . encodeUtf8++-- untested++-- | 'LogEff' that writes 'ByteString' to a 'Handle'+byteStringLogEff :: forall es. (FileSystem :> es) => Handle -> LogEff es ByteString+byteStringLogEff hdl = LogAction $ hPutStr hdl
+ test/Effectful/CologTest.hs view
@@ -0,0 +1,54 @@+{-# OPTIONS_GHC -Wno-orphans #-}++module Effectful.CologTest where++import Data.Text (Text, pack)++-- import Test.Tasty+import Test.Tasty.QuickCheck++-- import Test.Tasty.HUnit++import Effectful+import Effectful.Colog+import Effectful.Concurrent.Async (runConcurrent, wait, withAsync)+import Effectful.Labeled+import Effectful.Provider+import Effectful.Writer.Static.Shared (runWriter)++instance Arbitrary Text where+  arbitrary = fmap pack arbitrary++prop_tellEquals :: Text -> Property+prop_tellEquals t = runPureEff $ do+  (_, t2) <- runLogWriter $ logMsg t+  pure $ t === t2++prop_labeledLogShared :: Text -> Property+prop_labeledLogShared msg =+  property @Property+    . runPureEff+    . fmap ((msg ===) . snd)+    . runLabeled runLogWriter+    . labeled+    $ logMsg msg++prop_providerLogShared :: Text -> Property+prop_providerLogShared msg =+  property @Property+    . runPureEff+    . fmap ((=== msg) . snd)+    . runWriter @Text+    . runProvider_ (runLogAction)+    $ provideWith_ (tellLogEff)+    $ logMsg @Text msg++prop_tellConcurrent :: Text -> Text -> Property+prop_tellConcurrent m1 m2 =+  ioProperty @Property+    . runEff+    . runConcurrent+    . fmap ((=== (m1 <> m2)) . snd)+    . runWriter @Text+    . runLogAction tellLogEff+    $ logMsg m1 >> withAsync (logMsg m2) (\a -> wait a >> pure ())
+ test/Main.hs view
@@ -0,0 +1,1 @@+{-# OPTIONS_GHC -F -pgmF tasty-discover #-}