packages feed

tasklite-core-0.3.0.0: source/Base32.hs

-- | Adapted from https://hackage.haskell.org/package/crockford
module Base32 (decode) where

import Data.Char as C (Char, toUpper)
import Data.Text as T (Text, unpack)
import Protolude (
  Applicative (pure),
  Integral,
  Maybe (..),
  Traversable (mapM),
  ($),
 )

import Data.ULID.Digits (unDigits)


{-|
Decodes a Crockford-encoded `String` into an integer, if possible.
Returns `Nothing` if the string is not a valid Crockford-encoded value.
-}
decode :: (Integral i) => Text -> Maybe i
decode base32text = do
  numbers <- mapM decodeChar $ T.unpack base32text
  pure $ unDigits 32 numbers


decodeChar :: (Integral i) => Char -> Maybe i
decodeChar c = case C.toUpper c of
  '0' -> Just 0
  'O' -> Just 0
  '1' -> Just 1
  'I' -> Just 1
  'L' -> Just 1
  '2' -> Just 2
  '3' -> Just 3
  '4' -> Just 4
  '5' -> Just 5
  '6' -> Just 6
  '7' -> Just 7
  '8' -> Just 8
  '9' -> Just 9
  'A' -> Just 10
  'B' -> Just 11
  'C' -> Just 12
  'D' -> Just 13
  'E' -> Just 14
  'F' -> Just 15
  'G' -> Just 16
  'H' -> Just 17
  'J' -> Just 18
  'K' -> Just 19
  'M' -> Just 20
  'N' -> Just 21
  'P' -> Just 22
  'Q' -> Just 23
  'R' -> Just 24
  'S' -> Just 25
  'T' -> Just 26
  'V' -> Just 27
  'W' -> Just 28
  'X' -> Just 29
  'Y' -> Just 30
  'Z' -> Just 31
  _ -> Nothing