haskell_todo_app/app/Main.hs

115 lines
3.5 KiB
Haskell
Raw Normal View History

2024-05-25 20:07:02 +02:00
{-# LANGUAGE OverloadedStrings #-}
2024-05-25 22:36:59 +02:00
module Main(main, parseTask, serializeTask, getPriority, comparePriority, TaskMap) where
2024-05-25 20:07:02 +02:00
import System.IO
import System.Directory
2024-05-25 22:36:59 +02:00
import Data.Text (Text, pack, unpack, isInfixOf, lines, unlines, strip)
2024-05-25 20:07:02 +02:00
import qualified Data.Text.IO as TIO
2024-05-25 22:36:59 +02:00
import qualified Data.ByteString as BS
import qualified Data.ByteString.Char8 as BSC
2024-05-25 20:07:02 +02:00
import Control.Monad (when)
import Data.List (sortBy)
import Data.Ord (comparing)
import Data.Char (isAlpha)
2024-05-25 21:09:43 +02:00
import qualified Data.Map as Map
import Data.Function (on)
2024-05-25 20:07:02 +02:00
todoFile :: FilePath
todoFile = "todo.txt"
2024-05-25 21:09:43 +02:00
type TaskMap = Map.Map Int Text
2024-05-25 20:07:02 +02:00
main :: IO ()
main = do
putStrLn "Welcome to the Haskell Todo App"
putStrLn "1. Display tasks"
putStrLn "2. Add task"
putStrLn "3. Filter tasks by tag"
putStrLn "4. Sort tasks by priority"
putStrLn "5. Exit"
putStr "Choose an option: "
hFlush stdout
option <- getLine
case option of
"1" -> displayTasks
"2" -> addTask
"3" -> filterTasksByTag
"4" -> sortTasksByPriority
"5" -> putStrLn "Goodbye!"
_ -> putStrLn "Invalid option" >> main
displayTasks :: IO ()
displayTasks = do
exists <- doesFileExist todoFile
if exists
then do
2024-05-25 22:36:59 +02:00
contents <- BSC.readFile todoFile
let taskMap = parseTask (pack (BSC.unpack contents))
2024-05-25 20:07:02 +02:00
putStrLn "Tasks:"
2024-05-25 21:09:43 +02:00
mapM_ (putStrLn . showTask) (Map.toList taskMap)
2024-05-25 20:07:02 +02:00
else putStrLn "No tasks found."
main
addTask :: IO ()
addTask = do
putStr "Enter the task: "
hFlush stdout
task <- getLine
2024-05-25 21:09:43 +02:00
exists <- doesFileExist todoFile
if exists
then do
2024-05-25 22:36:59 +02:00
contents <- BSC.readFile todoFile
let taskMap = parseTask (pack (BSC.unpack contents))
2024-05-25 21:09:43 +02:00
newId = if Map.null taskMap then 1 else fst (Map.findMax taskMap) + 1
newTaskMap = Map.insert newId (pack task) taskMap
2024-05-25 22:36:59 +02:00
BSC.writeFile todoFile (BSC.pack (unpack (serializeTask newTaskMap)))
else BSC.writeFile todoFile (BSC.pack (task <> "\n"))
2024-05-25 20:07:02 +02:00
putStrLn "Task added."
main
filterTasksByTag :: IO ()
filterTasksByTag = do
2024-05-25 21:09:43 +02:00
putStr "Enter the tag to filter by (e.g., +GarageSale): "
2024-05-25 20:07:02 +02:00
hFlush stdout
tag <- getLine
exists <- doesFileExist todoFile
if exists
then do
contents <- TIO.readFile todoFile
2024-05-25 22:26:37 +02:00
let taskMap = parseTask contents
2024-05-25 21:09:43 +02:00
filteredTasks = Map.filter (isInfixOf (pack tag)) taskMap
2024-05-25 20:07:02 +02:00
putStrLn "Filtered tasks:"
2024-05-25 21:09:43 +02:00
mapM_ (putStrLn . showTask) (Map.toList filteredTasks)
2024-05-25 20:07:02 +02:00
else putStrLn "No tasks found."
main
sortTasksByPriority :: IO ()
sortTasksByPriority = do
exists <- doesFileExist todoFile
if exists
then do
contents <- TIO.readFile todoFile
2024-05-25 22:26:37 +02:00
let taskMap = parseTask contents
2024-05-25 21:09:43 +02:00
sortedTasks = sortBy (comparePriority `on` snd) (Map.toList taskMap)
2024-05-25 20:07:02 +02:00
putStrLn "Sorted tasks by priority:"
2024-05-25 21:09:43 +02:00
mapM_ (putStrLn . showTask) sortedTasks
2024-05-25 20:07:02 +02:00
else putStrLn "No tasks found."
main
comparePriority :: Text -> Text -> Ordering
comparePriority t1 t2 = comparing getPriority t1 t2
getPriority :: Text -> Maybe Char
2024-05-25 21:09:43 +02:00
getPriority t = case unpack (strip t) of
2024-05-25 20:07:02 +02:00
('(':p:')':_) | isAlpha p -> Just p
2024-05-25 21:09:43 +02:00
_ -> Nothing
2024-05-25 22:26:37 +02:00
parseTask :: Text -> TaskMap
parseTask = Map.fromList . zip [1..] . Data.Text.lines
2024-05-25 21:09:43 +02:00
2024-05-25 22:26:37 +02:00
serializeTask :: TaskMap -> Text
serializeTask = Data.Text.unlines . map snd . Map.toList
2024-05-25 21:09:43 +02:00
showTask :: (Int, Text) -> String
showTask (_, task) = unpack task