-- | Miscellaneous helper functions that don't fit anywhere else module Data.QRCodes.Utils (preserveUpper, resolveUpper, swapWord, liftEither) where import qualified Data.ByteString.Char8 as BS import Data.Char (toLower, toUpper) import Data.List (intercalate) import Data.List.Split (splitOn) import Data.Word (Word8) replace :: String -> String -> String -> String replace ndl target haystack = intercalate target $ splitOn ndl haystack -- | function applied to byteStrings before saving to QR code so that uppercase/lowercase signatures can be preserverd preserveUpper :: BS.ByteString -> BS.ByteString preserveUpper = lift pU where pU = (>>= (\c -> if c `elem` ['A'..'Z'] then toLower c : "!" else return c)) -- | resolve coded string to string with uppercase resolveUpper :: BS.ByteString -> BS.ByteString resolveUpper = lift rU where rU = foldr ((.) . (\s -> replace (s : "!") ((pure . toUpper) s))) id ['a'..'z'] -- | given a function on strings, make it act on byteStrings lift :: (String -> String) -> (BS.ByteString -> BS.ByteString) lift f = BS.pack . f . BS.unpack -- | helper function to lift Either values to IO in our case liftEither :: (Show b, Monad m) => (t -> m a) -> Either b t -> m a liftEither = either (error . show) swapWord :: Word8 -> Word8 swapWord 1 = 0 swapWord 0 = 1