-- | Miscellaneous helper functions that don't fit anywhere else module Data.QRCodes.Utils 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 = concatMap (\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 life 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