summaryrefslogtreecommitdiff
path: root/src/DPut.hs
diff options
context:
space:
mode:
Diffstat (limited to 'src/DPut.hs')
-rw-r--r--src/DPut.hs55
1 files changed, 24 insertions, 31 deletions
diff --git a/src/DPut.hs b/src/DPut.hs
index 6fd69040..38e532d0 100644
--- a/src/DPut.hs
+++ b/src/DPut.hs
@@ -1,3 +1,5 @@
1{-# LANGUAGE ConstraintKinds #-}
2{-# LANGUAGE ScopedTypeVariables #-}
1module DPut where 3module DPut where
2 4
3import Control.Monad.IO.Class 5import Control.Monad.IO.Class
@@ -10,26 +12,10 @@ import qualified Data.ByteString.Char8 as B
10import qualified Data.Text as T 12import qualified Data.Text as T
11import qualified Data.Text.Encoding as T 13import qualified Data.Text.Encoding as T
12import Debug.Trace 14import Debug.Trace
15import Data.Typeable
16import Data.Dynamic
13 17
14-- | Debug Tags, add more as needed, but ensure XAnnounce is always first, XMisc last 18type IsDebugTag t = (Eq t, Ord t, Show t, Read t, Enum t, Bounded t,Typeable t)
15data DebugTag
16 = XAnnounce
17 | XBitTorrent
18 | XDHT
19 | XLan
20 | XMan
21 | XNetCrypto
22 | XNetCryptoOut
23 | XOnion
24 | XRoutes
25 | XPing
26 | XRefresh
27 | XJabber
28 | XMisc
29 | XNodeinfoSearch
30 | XUnexpected -- Used only for special anomalous errors that we didn't expect to happen.
31 | XUnused -- Never commit code that uses XUnused.
32 deriving (Eq, Ord, Show, Read, Enum, Bounded)
33 19
34appName :: String 20appName :: String
35appName = "toxmpp" 21appName = "toxmpp"
@@ -37,43 +23,50 @@ appName = "toxmpp"
37(<.>) :: String -> String -> String 23(<.>) :: String -> String -> String
38a <.> b = a ++ "." ++ b 24a <.> b = a ++ "." ++ b
39 25
40dput :: MonadIO m => DebugTag -> String -> m () 26dput :: (MonadIO m, IsDebugTag tag) => tag -> String -> m ()
41dput tag msg = liftIO $ debugM (appName <.> show tag) msg 27dput tag msg = liftIO $ debugM (appName <.> show tag) msg
42 28
43dputB :: MonadIO m => DebugTag -> B.ByteString -> m () 29dputB :: (MonadIO m, IsDebugTag tag) => tag -> B.ByteString -> m ()
44dputB tag msg = liftIO $ debugM (appName <.> show tag) (T.unpack . T.decodeUtf8 $ msg) 30dputB tag msg = liftIO $ debugM (appName <.> show tag) (T.unpack . T.decodeUtf8 $ msg)
45 31
46{-# NOINLINE verbosityMap #-} 32{-# NOINLINE verbosityMap #-}
47verbosityMap :: IORef (Map.Map DebugTag Bool) 33verbosityMap :: IORef (Map.Map TypeRep Dynamic)
48verbosityMap = unsafePerformIO $ newIORef (Map.empty) 34verbosityMap = unsafePerformIO $ newIORef (Map.empty)
49 35
50-- | Trace version of 'dput' works in arbitrary monad, using unsafePerformIO. 36-- | Trace version of 'dput' works in arbitrary monad, using unsafePerformIO.
51tput :: Applicative m => DebugTag -> String -> m () 37tput :: (Applicative m, IsDebugTag tag) => tag -> String -> m ()
52tput tag msg = 38tput tag msg =
53 let mp = unsafePerformIO $ readIORef verbosityMap 39 let mp = unsafePerformIO $ readIORef verbosityMap
54 in if fromMaybe True (Map.lookup tag mp) 40 in if maybe True (fromMaybe True . Map.lookup tag . flip fromDyn Map.empty) (Map.lookup (typeOf tag) mp)
55 then trace msg (pure ()) 41 then trace msg (pure ())
56 else pure () 42 else pure ()
57 43
58-- | like 'trace' but parameterized with 'DebugTag' 44-- | like 'trace' but parameterized with 'DebugTag'
59dtrace :: DebugTag -> String -> a -> a 45dtrace :: forall a tag. IsDebugTag tag => tag -> String -> a -> a
60dtrace tag msg result = let mp = unsafePerformIO $ readIORef verbosityMap 46dtrace tag msg result = let mp = unsafePerformIO $ readIORef verbosityMap
61 in if fromMaybe True (Map.lookup tag mp) 47 mp' :: Map.Map tag Bool
48 mp' = maybe Map.empty (flip fromDyn Map.empty) (Map.lookup (typeOf tag) mp)
49 in if fromMaybe True (Map.lookup tag mp')
62 then trace msg result 50 then trace msg result
63 else result 51 else result
64 52
65setTagLevel :: Priority -> DebugTag -> IO () 53setTagLevel :: forall tag. IsDebugTag tag => Priority -> tag -> IO ()
66setTagLevel level tag = do 54setTagLevel level tag = do
67 updateGlobalLogger (appName <.> show tag) (setLevel level) 55 updateGlobalLogger (appName <.> show tag) (setLevel level)
68 modifyIORef verbosityMap (Map.insert tag (level <= DEBUG)) 56 modifyIORef verbosityMap $ \mpByType -> do
57 case Map.lookup (typeOf tag) mpByType of
58 Nothing -> Map.insert (typeOf tag) (toDyn $ Map.fromList [(tag,(level <= DEBUG))]) mpByType
59 Just dyn -> let mpByTag :: Map.Map tag Bool
60 mpByTag = fromDyn dyn Map.empty
61 in Map.insert (typeOf tag) (toDyn $ Map.insert tag (level <= DEBUG) mpByTag) mpByType
69 62
70setQuiet :: DebugTag -> IO () 63setQuiet :: forall tag. IsDebugTag tag => tag -> IO ()
71setQuiet = setTagLevel WARNING 64setQuiet = setTagLevel WARNING
72 65
73setVerbose :: DebugTag -> IO () 66setVerbose :: forall tag. IsDebugTag tag => tag -> IO ()
74setVerbose = setTagLevel DEBUG 67setVerbose = setTagLevel DEBUG
75 68
76getVerbose :: DebugTag -> IO Bool 69getVerbose :: forall tag. IsDebugTag tag => tag -> IO Bool
77getVerbose tag = do 70getVerbose tag = do
78 logger <- getLogger (appName <.> show tag) 71 logger <- getLogger (appName <.> show tag)
79 case getLevel logger of 72 case getLevel logger of