user-management/app/Main.hs
2024-05-25 20:14:01 +02:00

112 lines
4.7 KiB
Haskell

module Main where
import UserManager
import Control.Exception
import Text.Printf
import Data.ByteString.Char8 (ByteString)
import qualified Data.ByteString.Char8 as B
import qualified Data.Map as Map
-- Main entry point of the program
main :: IO ()
main = do
putStrLn "Welcome to User Management Console!" -- display a message to the user
initializeDB -- initialize the database
mainMenu -- start the main menu
-- Main menu of the program
mainMenu :: IO ()
mainMenu = do
putStrLn "1. Add User" -- display the options to the user
putStrLn "2. List Users"
putStrLn "3. Find User"
putStrLn "4. Delete User"
putStrLn "5. (DEBUG) Generate and Add Users"
putStrLn "6. Exit"
putStrLn "Choose an option: " -- ask the user to choose an option
option <- getLine
case option of
"1" -> addUserHandler -- handle the option chosen by the user
"2" -> maplistUsersHandler
"3" -> findUserHandler
"4" -> deleteUserHandler
"5" -> do
putStrLn "Enter the number of users to generate and add: "
numUsers <- readLn :: IO Int
generateAndAddUsers numUsers
putStrLn $ "Generated and added " ++ show numUsers ++ " users"
mainMenu
"6" -> putStrLn "Exiting..." -- exit the program
_ -> putStrLn "Invalid option" >> mainMenu
formatUser :: User -> ByteString
formatUser user = B.pack $ printf "Name: %s Email: %s Password: %s" (userName user) (userEmail user) (userPassword user)
-- Handle the addition of a user
addUserHandler :: IO ()
addUserHandler = do
putStrLn "Enter user name: " -- ask the user for a name
name <- getLine
putStrLn "Enter user email: " -- ask the user for an email
email <- getLine
putStrLn "Enter user password: " -- ask the user for a password
password <- getLine
addUser name email password `catch` handler -- add the user to the database, handling any errors
mainMenu
-- Handle the listing of all users
listUsersHandler :: IO ()
listUsersHandler = do
putStrLn ""
users <- listUsers -- get the list of all users from the database
let numberedUsers :: [(Int, User)]
numberedUsers = zipWith (\n user -> (n, user)) [1..] users -- add numbering to the users
formattedUsers = map (\(n, user) -> printf "%3d. %-15s %-20s %s" n (userName user) (userEmail user) (userPassword user)) numberedUsers -- format each user as a table row
tableHeader = "No. Name Email Password" -- create the table header
putStrLn tableHeader -- print the table header
putStrLn $ replicate (length tableHeader) '-' -- print a line of dashes under the header
mapM_ putStrLn formattedUsers -- print each user as a table row
putStrLn ""
mainMenu
-- Handle the listing of all users using Data.Map
maplistUsersHandler :: IO ()
maplistUsersHandler = do
putStrLn ""
users <- listUsers -- get the list of all users from the database
let userMap = Map.fromList $ map (\user -> (userName user, user)) users -- create a map with user names as keys
numberedUsers :: [(Int, (UserName, User))]
numberedUsers = zipWith (\n (name, user) -> (n, (name, user))) [1..] (Map.toList userMap) -- add numbering to the users
formattedUsers = map (\(n, (name, user)) -> printf "%3d. %-15s %-20s %s" n name (userEmail user) (userPassword user)) numberedUsers -- format each user as a table row
tableHeader = "No. Name Email Password" -- create the table header
putStrLn tableHeader -- print the table header
putStrLn $ replicate (length tableHeader) '-' -- print a line of dashes under the header
mapM_ putStrLn formattedUsers -- print each user as a table row
putStrLn ""
mainMenu
-- Handle the finding of a user
findUserHandler :: IO ()
findUserHandler = do
putStrLn "Enter user name or email to find: " -- ask the user for a name or email to search for
searchTerm <- getLine
users <- findUsers searchTerm -- search the database for users matching the search term
case users of
[] -> putStrLn "User not found"
_ -> mapM_ (putStrLn . B.unpack . formatUser) users -- print the users to the console using the formatted string
mainMenu
-- Handle the deletion of a user
deleteUserHandler :: IO ()
deleteUserHandler = do
putStrLn "Enter user name to delete: " -- ask the user for a name to delete
name <- getLine
deleteUser name `catch` handler -- delete the user from the database, handling any errors
mainMenu
-- Handle any exceptions that are thrown by the program
handler :: SomeException -> IO ()
handler ex = putStrLn $ "An error occurred: " ++ show ex