{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TypeSynonymInstances #-} {-# LANGUAGE FlexibleInstances #-} module Celtchar.Novel.Structure where import Data.Yaml import GHC.Generics data Language = French | English deriving (Generic) data Document = Document FilePath deriving (Generic, Show) instance FromJSON Document where parseJSON v = Document <$> parseJSON v data Chapter = Chapter { chapterTitle :: Maybe String , documents :: [Document] } deriving (Generic, Show) instance FromJSON Chapter where parseJSON (Object v) = Chapter <$> v .:? "title" <*> v .: "documents" data Part = Part { partTitle :: String , chapters :: [Chapter] } deriving (Generic, Show) instance FromJSON Part where parseJSON (Object v) = Part <$> v .: "title" <*> v .: "chapters" data Manuscript = Manuscript [Part] deriving (Generic, Show) instance FromJSON Manuscript where parseJSON v = Manuscript <$> parseJSON v instance FromJSON Language where parseJSON (String "english") = pure English parseJSON (String "french") = pure French parseJSON _ = fail "unknown language" instance Show Language where show English = "english" show French = "french" data Novel = Novel { author :: String , language :: Language , novelTitle :: String , manuscript :: Manuscript } deriving (Generic, Show) instance FromJSON Novel where parseJSON (Object v) = Novel <$> v .: "author" <*> v .: "language" <*> v .: "title" <*> v .: "manuscript" getNovelStructure :: FilePath -> IO (Maybe Novel) getNovelStructure = decodeFile