112 lines
4.7 KiB
Haskell
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
|
||
|
|