99 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Haskell
		
	
	
	
	
	
			
		
		
	
	
			99 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Haskell
		
	
	
	
	
	
| {- This Source Code Form is subject to the terms of the Mozilla Public License,
 | |
|    v. 2.0. If a copy of the MPL was not distributed with this file, You can
 | |
|    obtain one at https://mozilla.org/MPL/2.0/. -}
 | |
| 
 | |
| -- | Transformers and exceptions.
 | |
| module SlackBuilder.Trans
 | |
|     ( SlackBuilderException(..)
 | |
|     , SlackBuilderT(..)
 | |
|     , relativeToRepository
 | |
|     ) where
 | |
| 
 | |
| import Control.Monad.Trans.Reader (ReaderT(..), asks)
 | |
| import Data.ByteString (ByteString)
 | |
| import Data.Text (Text)
 | |
| import qualified Data.Text as Text
 | |
| import SlackBuilder.Config
 | |
| import Control.Monad.IO.Class (MonadIO(..))
 | |
| import Control.Monad.Catch (MonadCatch(..), MonadThrow(..))
 | |
| import Control.Exception (Exception(..))
 | |
| import System.FilePath ((</>))
 | |
| import Text.URI (URI)
 | |
| import qualified Text.URI as URI
 | |
| import qualified Codec.Compression.Lzma as Lzma
 | |
| import Text.Megaparsec (ParseErrorBundle(..), errorBundlePretty)
 | |
| import Conduit (Void)
 | |
| 
 | |
| data SlackBuilderException
 | |
|     = UpdaterNotFound Text
 | |
|     | UnsupportedUrlType URI
 | |
|     | LzmaDecompressionFailed Lzma.LzmaRet
 | |
|     | MalformedInfoFile (ParseErrorBundle ByteString Void)
 | |
|     deriving Show
 | |
| 
 | |
| instance Exception SlackBuilderException
 | |
|   where
 | |
|     displayException (UpdaterNotFound updateName) = Text.unpack
 | |
|         $ Text.concat ["Requested package \"", updateName, "\" was not found"]
 | |
|     displayException (UnsupportedUrlType givenURI) = Text.unpack
 | |
|         $ "Only https URLs are supported, got: " <> URI.render givenURI
 | |
|     displayException (LzmaDecompressionFailed Lzma.LzmaRetOK) =
 | |
|         "Operation completed successfully"
 | |
|     displayException (LzmaDecompressionFailed Lzma.LzmaRetStreamEnd) =
 | |
|         "End of stream was reached"
 | |
|     displayException (LzmaDecompressionFailed Lzma.LzmaRetUnsupportedCheck) =
 | |
|         "Cannot calculate the integrity check"
 | |
|     displayException (LzmaDecompressionFailed Lzma.LzmaRetGetCheck) =
 | |
|         "Integrity check type is now available"
 | |
|     displayException (LzmaDecompressionFailed Lzma.LzmaRetMemError) =
 | |
|         "Cannot allocate memory"
 | |
|     displayException (LzmaDecompressionFailed Lzma.LzmaRetMemlimitError) =
 | |
|         "Memory usage limit was reached"
 | |
|     displayException (LzmaDecompressionFailed Lzma.LzmaRetFormatError) =
 | |
|         "File format not recognized"
 | |
|     displayException (LzmaDecompressionFailed Lzma.LzmaRetOptionsError) =
 | |
|         "Invalid or unsupported options"
 | |
|     displayException (LzmaDecompressionFailed Lzma.LzmaRetDataError) =
 | |
|         "Data is corrupt"
 | |
|     displayException (LzmaDecompressionFailed Lzma.LzmaRetBufError) =
 | |
|         "No progress is possible"
 | |
|     displayException (LzmaDecompressionFailed Lzma.LzmaRetProgError) =
 | |
|         "Programming error"
 | |
|     displayException (MalformedInfoFile errorBundle) =
 | |
|         errorBundlePretty errorBundle
 | |
|  
 | |
| newtype SlackBuilderT a = SlackBuilderT
 | |
|     { runSlackBuilderT :: ReaderT Settings IO a
 | |
|     }
 | |
| 
 | |
| relativeToRepository :: FilePath -> SlackBuilderT FilePath
 | |
| relativeToRepository filePath =
 | |
|     (</> filePath) <$> SlackBuilderT (asks repository)
 | |
| 
 | |
| instance Functor SlackBuilderT
 | |
|   where
 | |
|     fmap f (SlackBuilderT slackBuilderT) = SlackBuilderT $ f <$> slackBuilderT
 | |
| 
 | |
| instance Applicative SlackBuilderT
 | |
|   where
 | |
|     pure = SlackBuilderT . pure
 | |
|     (SlackBuilderT f) <*> (SlackBuilderT x) = SlackBuilderT $ f <*> x
 | |
| 
 | |
| instance Monad SlackBuilderT
 | |
|   where
 | |
|     return = pure
 | |
|     (SlackBuilderT x) >>= f = SlackBuilderT $ x >>= runSlackBuilderT . f
 | |
| 
 | |
| instance MonadIO SlackBuilderT
 | |
|   where
 | |
|     liftIO = SlackBuilderT . liftIO
 | |
| 
 | |
| instance MonadThrow SlackBuilderT
 | |
|   where
 | |
|     throwM = SlackBuilderT . throwM
 | |
| 
 | |
| instance MonadCatch SlackBuilderT
 | |
|   where
 | |
|     catch (SlackBuilderT action) handler =
 | |
|         SlackBuilderT $ catch action $ runSlackBuilderT . handler
 |