idris-learning/chapter4/DataStore.idr
2021-08-17 21:39:45 +02:00

69 lines
2.7 KiB
Idris

module Main
import Data.Vect
data DataStore : Type where
MkData : (size : Nat) -> (items : Vect size String) -> DataStore
size : DataStore -> Nat
size (MkData size items) = size
items : (store : DataStore) -> Vect (size store) String
items (MkData size items) = items
addToStore : DataStore -> String -> DataStore
addToStore (MkData size items) newitem = MkData _ (addToData items)
where
addToData : Vect old String -> Vect (S old) String
addToData [] = [newitem]
addToData (x :: xs) = x :: addToData xs
search : DataStore -> String -> List String
search store query = let predicate = isInfixOf query
allItems = toList (items store) in -- can't be bothered to work with dependant pairs
filter predicate allItems
data Command = Add String
| Get Integer
| Size
| Search String
| Quit
parseCommand : (cmd : String) -> (args : String) -> Maybe Command
parseCommand "add" args = Just (Add args)
parseCommand "get" val = case all isDigit (unpack val) of
True => Just (Get (cast val))
False => Nothing
parseCommand "quit" args = Just Quit
parseCommand "size" args = Just Size
parseCommand "search" args = Just (Search args)
parseCommand _ _ = Nothing
parse : (input : String) -> Maybe Command
parse input = case span (/= ' ') input of
(cmd, args) => parseCommand cmd (ltrim args)
getEntry : (pos : Integer) -> (store : DataStore) -> Maybe (String, DataStore)
getEntry pos store = let store_items = items store in
case integerToFin pos (size store) of
Nothing => Just ("Out of range\n", store)
Just idx => Just (index idx store_items ++ "\n", store)
processInput : DataStore -> String -> Maybe (String, DataStore)
processInput store inp = case parse inp of
Nothing => Just ("invalid command\n", store)
Just (Add item) =>
Just ("ID " ++ show (size store) ++ "\n", addToStore store item)
Just (Get pos) => getEntry pos store
Just Size => Just ("Size: " ++ show (size store) ++ "\n", store)
Just (Search query) => case (search store query) of
[] => Just ("Item Not Found\n", store)
items => Just (show items ++ "\n", store)
Just Quit => Nothing
main : IO ()
main = replWith (MkData _ []) "Command: " processInput