module BibDB where

import Text.ParserCombinators.Parsec (parseFromFile)
import TypedBibData
import Config
import Control.Monad

------------
-- DB


loadBibliography :: InitFile -> IO (Either String [Entry])
loadBibliography InitFile
cfg = String -> IO (Either String [Entry])
loadBibliographyFrom (InitFile -> String
bibfile InitFile
cfg)

loadBibliographyFrom :: String -> IO (Either String [Entry])
loadBibliographyFrom String
fileName = do
  String -> IO ()
putStrLn (String
"Loading " String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
fileName)
  Either ParseError (Either String [Entry])
mBib <- ([T] -> Either String [Entry])
-> Either ParseError [T]
-> Either ParseError (Either String [Entry])
forall a b. (a -> b) -> Either ParseError a -> Either ParseError b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap [T] -> Either String [Entry]
bibToForest (Either ParseError [T]
 -> Either ParseError (Either String [Entry]))
-> IO (Either ParseError [T])
-> IO (Either ParseError (Either String [Entry]))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser [T] -> String -> IO (Either ParseError [T])
forall a. Parser a -> String -> IO (Either ParseError a)
parseFromFile Parser [T]
parseBib String
fileName
  case Either String (Either String [Entry]) -> Either String [Entry]
forall (m :: * -> *) a. Monad m => m (m a) -> m a
join ((ParseError -> Either String (Either String [Entry]))
-> (Either String [Entry] -> Either String (Either String [Entry]))
-> Either ParseError (Either String [Entry])
-> Either String (Either String [Entry])
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (String -> Either String (Either String [Entry])
forall a b. a -> Either a b
Left (String -> Either String (Either String [Entry]))
-> (ParseError -> String)
-> ParseError
-> Either String (Either String [Entry])
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParseError -> String
forall a. Show a => a -> String
show) Either String [Entry] -> Either String (Either String [Entry])
forall a b. b -> Either a b
Right (Either ParseError (Either String [Entry])
 -> Either String (Either String [Entry]))
-> Either ParseError (Either String [Entry])
-> Either String (Either String [Entry])
forall a b. (a -> b) -> a -> b
$ Either ParseError (Either String [Entry])
mBib) of
    Left String
err -> Either String [Entry] -> IO (Either String [Entry])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return (String -> Either String [Entry]
forall a b. a -> Either a b
Left String
err)
    Right [Entry]
bib -> do String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ Int -> String
forall a. Show a => a -> String
show ([Entry] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length ([Entry] -> Int) -> [Entry] -> Int
forall a b. (a -> b) -> a -> b
$ [Entry]
bib) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" entries loaded."
                    Either String [Entry] -> IO (Either String [Entry])
forall a. a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return ([Entry] -> Either String [Entry]
forall a b. b -> Either a b
Right [Entry]
bib)

formatBib :: [Entry] -> [Char]
formatBib :: [Entry] -> String
formatBib = (T -> String) -> [T] -> String
forall (t :: * -> *) a b. Foldable t => (a -> [b]) -> t a -> [b]
concatMap T -> String
formatEntry ([T] -> String) -> ([Entry] -> [T]) -> [Entry] -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Entry -> T) -> [Entry] -> [T]
forall a b. (a -> b) -> [a] -> [b]
map Entry -> T
treeToEntry

saveBibliography :: InitFile -> [Entry] -> IO ()
saveBibliography :: InitFile -> [Entry] -> IO ()
saveBibliography InitFile
cfg [Entry]
bib = do
  let formatted :: String
formatted = [Entry] -> String
formatBib [Entry]
bib
  String -> String -> IO ()
writeFile (InitFile -> String
bibfile InitFile
cfg) String
formatted 
  String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ Int -> String
forall a. Show a => a -> String
show ([Entry] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Entry]
bib) String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" entries saved to " String -> String -> String
forall a. [a] -> [a] -> [a]
++ (InitFile -> String
bibfile InitFile
cfg)