hmt-0.16: Music/Theory/DB/JSON.hs
-- | JSON string association database.
-- JSON objects do no allow multiple keys.
-- Here multiple keys are read & written as arrays.
module Music.Theory.DB.JSON where
import qualified Data.Aeson as A {- aeson -}
import qualified Data.ByteString.Lazy as B {- bytestring -}
import qualified Data.Map as M {- containers -}
import qualified Music.Theory.DB.Common as DB
-- | Load 'DB' from 'FilePath'.
db_load_utf8 :: FilePath -> IO DB.DB'
db_load_utf8 fn = do
b <- B.readFile fn
case A.decode b of
Just m ->
let f = DB.record_uncollate .
map (fmap maybe_list_to_list) .
M.toList
in return (map f m)
Nothing -> return []
-- | Store 'DB' to 'FilePath'.
--
-- > let fn = "/home/rohan/ut/www-spr/data/db.js"
-- > db <- db_load_utf8 fn
-- > length db == 1334
-- > db_store_utf8 "/tmp/sp.js" db
db_store_utf8 :: FilePath -> DB.DB' -> IO ()
db_store_utf8 fn db = do
let db' = let f = map (fmap list_to_maybe_list) . DB.record_collate
in map f db
b = A.encode (map M.fromList db')
B.writeFile fn b
-- * Maybe List of String
data Maybe_List_Of_String = S String | L [String] deriving (Eq,Show)
maybe_list_to_list :: Maybe_List_Of_String -> [String]
maybe_list_to_list m =
case m of
S s -> [s]
L l -> l
list_to_maybe_list :: [String] -> Maybe_List_Of_String
list_to_maybe_list l =
case l of
[s] -> S s
_ -> L l
-- > A.toJSON (S "x")
-- > A.toJSON (L ["x","y"])
instance A.ToJSON Maybe_List_Of_String where
toJSON (S s) = A.toJSON s
toJSON (L l) = A.toJSON l
-- > :set -XOverloadedStrings
-- > A.decode "\"x\"" :: Maybe Maybe_List_Of_String
-- > A.decode "[\"x\",\"y\"]" :: Maybe Maybe_List_Of_String
instance A.FromJSON Maybe_List_Of_String where
parseJSON v =
case v of
A.String _ -> fmap S (A.parseJSON v)
A.Array _ -> fmap L (A.parseJSON v)
_ -> error "parseJSON: Maybe_List_String"