From 95d50b25c990e8c945ce2507b16ff3c8b039d286 Mon Sep 17 00:00:00 2001 From: Rutger Broekhoff Date: Mon, 25 Aug 2025 19:48:19 +0200 Subject: OCaml --- app/Data/Iban.hs | 48 ------------------------------------------------ 1 file changed, 48 deletions(-) delete mode 100644 app/Data/Iban.hs (limited to 'app/Data/Iban.hs') diff --git a/app/Data/Iban.hs b/app/Data/Iban.hs deleted file mode 100644 index d9566b9..0000000 --- a/app/Data/Iban.hs +++ /dev/null @@ -1,48 +0,0 @@ -module Data.Iban (Iban, mkIban, toText) where - -import Control.Applicative ((<|>)) -import Data.Attoparsec.Text as AP -import Data.Char - ( digitToInt, - isAscii, - isDigit, - ord, - toUpper, - ) -import Data.Text qualified as T - -newtype Iban = Iban T.Text deriving (Show, Eq) - -mkIban :: T.Text -> Either String Iban -mkIban t = validateIban t >> return (Iban t) - -validateIban :: T.Text -> Either String () -validateIban = AP.parseOnly $ do - countryCode <- AP.count 2 AP.letter - checkDigits <- AP.count 2 AP.digit - chars <- AP.many1 (AP.letter <|> AP.digit) - endOfInput - if length chars < 30 - then - if valid countryCode checkDigits chars - then return () - else fail $ "IBAN checksum does not match (" ++ countryCode ++ checkDigits ++ chars ++ ")" - else fail "IBAN has more than 34 characters" - where - letterToInt c = ord (toUpper c) - ord 'A' + 10 - charsToInteger = - foldl' - ( \acc -> \case - d - | isDigit d -> acc * 10 + toInteger (digitToInt d) - | isAscii d -> acc * 100 + toInteger (letterToInt d) - | otherwise -> error "unreachable" - ) - 0 - ibanToInteger countryCode checkDigits chars = - charsToInteger chars * 1000000 + charsToInteger countryCode * 100 + charsToInteger checkDigits - valid countryCode checkDigits chars = - ibanToInteger countryCode checkDigits chars `mod` 97 == 1 - -toText :: Iban -> T.Text -toText (Iban t) = t -- cgit v1.2.3