content: -- | 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
  