Class.hs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. {-# LANGUAGE OverloadedStrings #-}
  2. {-# LANGUAGE OverloadedLists #-}
  3. {-# LANGUAGE TypeSynonymInstances #-}
  4. {-# LANGUAGE FlexibleInstances #-}
  5. {-# LANGUAGE FlexibleContexts #-}
  6. {-# LANGUAGE TypeOperators #-}
  7. {-# LANGUAGE ScopedTypeVariables #-}
  8. {-# LANGUAGE DefaultSignatures #-}
  9. {-# LANGUAGE DataKinds #-}
  10. {-# LANGUAGE GADTs #-}
  11. module Data.Adnot.Class where
  12. import Control.Monad ((>=>))
  13. import Data.Adnot.Parse
  14. import Data.Adnot.Type
  15. import Data.Adnot.Emit
  16. import Data.Adnot.Parse
  17. import Data.Int
  18. import Data.Word
  19. import qualified Data.ByteString as BS
  20. import qualified Data.ByteString.Lazy as BSL
  21. import qualified Data.Foldable as F
  22. import qualified Data.List.NonEmpty as NE
  23. import qualified Data.Map.Lazy as ML
  24. import qualified Data.Map.Strict as MS
  25. import qualified Data.Sequence as Seq
  26. import qualified Data.Text as T
  27. import qualified Data.Text.Lazy as TL
  28. import qualified Data.Vector as V
  29. import GHC.Generics
  30. import GHC.TypeLits (KnownSymbol)
  31. encode :: ToAdnot a => a -> BSL.ByteString
  32. encode = encodeValue . toAdnot
  33. class GenToAdnot f where
  34. genToAdnot :: f p -> Value
  35. instance (GenToAdnot l, GenToAdnot r) => GenToAdnot (l :+: r) where
  36. genToAdnot (L1 x) = genToAdnot x
  37. genToAdnot (R1 y) = genToAdnot y
  38. instance ToAdnot x => GenToAdnot (K1 i x) where
  39. genToAdnot (K1 x) = toAdnot x
  40. instance (GatherSequence f, Constructor name) => GenToAdnot (C1 name f) where
  41. genToAdnot (M1 x) = Sum (T.pack (conName c)) (V.fromList (gatherSequence x))
  42. where c :: M1 c name f ()
  43. c = undefined
  44. instance (GenToAdnot f) => GenToAdnot (S1 name f) where
  45. genToAdnot (M1 x) = genToAdnot x
  46. instance (GenToAdnot f) => GenToAdnot (D1 name f) where
  47. genToAdnot (M1 x) = genToAdnot x
  48. instance (GatherSequence l, GatherSequence r) => GenToAdnot (l :*: r) where
  49. genToAdnot x = List (V.fromList (gatherSequence x))
  50. class GatherRecord f where
  51. gatherRecord :: f p -> [(T.Text, Value)]
  52. instance (GatherRecord l, GatherRecord r) => GatherRecord (l :*: r) where
  53. gatherRecord (x :*: y) = gatherRecord x ++ gatherRecord y
  54. instance (GenToAdnot f, Selector name) => GatherRecord (S1 name f) where
  55. gatherRecord (M1 x) = [(T.pack (selName s), genToAdnot x)]
  56. where s :: S1 name f ()
  57. s = undefined
  58. instance GatherRecord U1 where
  59. gatherRecord U1 = []
  60. class GatherSequence f where
  61. gatherSequence :: f p -> [Value]
  62. instance GatherSequence U1 where
  63. gatherSequence U1 = []
  64. instance (GatherSequence l, GatherSequence r) => GatherSequence (l :*: r) where
  65. gatherSequence (x :*: y) = gatherSequence x ++ gatherSequence y
  66. instance ToAdnot x => GatherSequence (K1 i x) where
  67. gatherSequence (K1 x) = [toAdnot x]
  68. instance GenToAdnot f => GatherSequence (S1 name f) where
  69. gatherSequence (M1 x) = [genToAdnot x]
  70. instance GenToAdnot f => GatherSequence (D1 name f) where
  71. gatherSequence (M1 x) = [genToAdnot x]
  72. instance GenToAdnot U1 where
  73. genToAdnot U1 = List []
  74. genericToAdnot :: (GenToAdnot (Rep t), Generic t) => t -> Value
  75. genericToAdnot x = genToAdnot (from x)
  76. class ToAdnot a where
  77. toAdnot :: a -> Value
  78. default toAdnot :: (Generic a, GenToAdnot (Rep a)) => a -> Value
  79. toAdnot = genericToAdnot
  80. -- Integral types
  81. instance ToAdnot Int where
  82. toAdnot n = Integer (fromIntegral n)
  83. instance ToAdnot Integer where
  84. toAdnot n = Integer n
  85. instance ToAdnot Int8 where
  86. toAdnot n = Integer (fromIntegral n)
  87. instance ToAdnot Int16 where
  88. toAdnot n = Integer (fromIntegral n)
  89. instance ToAdnot Int32 where
  90. toAdnot n = Integer (fromIntegral n)
  91. instance ToAdnot Int64 where
  92. toAdnot n = Integer (fromIntegral n)
  93. instance ToAdnot Word where
  94. toAdnot n = Integer (fromIntegral n)
  95. instance ToAdnot Word8 where
  96. toAdnot n = Integer (fromIntegral n)
  97. instance ToAdnot Word16 where
  98. toAdnot n = Integer (fromIntegral n)
  99. instance ToAdnot Word32 where
  100. toAdnot n = Integer (fromIntegral n)
  101. instance ToAdnot Word64 where
  102. toAdnot n = Integer (fromIntegral n)
  103. -- Rational/Floating types
  104. instance ToAdnot Double where
  105. toAdnot d = Double d
  106. instance ToAdnot Float where
  107. toAdnot d = Double (fromRational (toRational d))
  108. -- String types
  109. instance {-# INCOHERENT #-} ToAdnot String where
  110. toAdnot s = String (T.pack s)
  111. instance ToAdnot T.Text where
  112. toAdnot s = String s
  113. instance ToAdnot TL.Text where
  114. toAdnot s = String (TL.toStrict s)
  115. instance ToAdnot Char where
  116. toAdnot c = String (T.singleton c)
  117. -- List types
  118. instance ToAdnot a => ToAdnot [a] where
  119. toAdnot ls = List (fmap toAdnot (V.fromList ls))
  120. instance ToAdnot a => ToAdnot (V.Vector a) where
  121. toAdnot ls = List (fmap toAdnot ls)
  122. instance ToAdnot a => ToAdnot (Seq.Seq a) where
  123. toAdnot ls = List (V.fromList (F.toList (fmap toAdnot ls)))
  124. instance ToAdnot a => ToAdnot (NE.NonEmpty a) where
  125. toAdnot ls = List (V.fromList (F.toList (fmap toAdnot ls)))
  126. -- Mapping types
  127. instance ToAdnot a => ToAdnot (MS.Map T.Text a) where
  128. toAdnot ls = Product (fmap toAdnot ls)
  129. product :: [(T.Text, Value)] -> Value
  130. product = Product . MS.fromList
  131. (.=) :: ToAdnot t => T.Text -> t -> (T.Text, Value)
  132. key .= val = (key, toAdnot val)
  133. -- * Tuples
  134. instance ToAdnot () where
  135. toAdnot () = List []
  136. instance (ToAdnot a, ToAdnot b) => ToAdnot (a, b) where
  137. toAdnot (a, b) = List [toAdnot a, toAdnot b]
  138. instance (ToAdnot a, ToAdnot b, ToAdnot c) => ToAdnot (a, b, c) where
  139. toAdnot (a, b, c) = List [toAdnot a, toAdnot b, toAdnot c]
  140. instance (ToAdnot a, ToAdnot b, ToAdnot c, ToAdnot d)
  141. => ToAdnot (a, b, c, d) where
  142. toAdnot (a, b, c, d) = List [toAdnot a, toAdnot b, toAdnot c, toAdnot d]
  143. -- Common Haskell algebraic data types
  144. instance ToAdnot a => ToAdnot (Maybe a) where
  145. toAdnot Nothing = Sum "Nothing" []
  146. toAdnot (Just x) = Sum "Just" [toAdnot x]
  147. instance (ToAdnot a, ToAdnot b) => ToAdnot (Either a b) where
  148. toAdnot (Left x) = Sum "Left" [toAdnot x]
  149. toAdnot (Right y) = Sum "Right" [toAdnot y]
  150. instance ToAdnot Bool where
  151. toAdnot True = String "True"
  152. toAdnot False = String "False"
  153. -- Parsing
  154. decode :: FromAdnot a => BS.ByteString -> Either String a
  155. decode = decodeValue >=> parseAdnot
  156. type ParseError = String
  157. type Parser a = Either ParseError a
  158. niceType :: Value -> String
  159. niceType Sum {} = "sum"
  160. niceType Product {} = "product"
  161. niceType List {} = "list"
  162. niceType Integer {} = "integer"
  163. niceType Double {} = "double"
  164. niceType String {} = "string"
  165. withSum :: String -> (T.Text -> Array -> Parser a) -> Value -> Parser a
  166. withSum n k val = case val of
  167. Sum t as -> k t as
  168. _ -> Left ("Expected sum in " ++ n)
  169. withSumNamed :: String -> T.Text -> (Array -> Parser a) -> Value -> Parser a
  170. withSumNamed n tag k val = case val of
  171. Sum t as
  172. | tag == t -> k as
  173. | otherwise -> Left $ unwords
  174. [ "Expected tag", T.unpack tag, "in", n, "but found", T.unpack t ]
  175. _ -> Left ("Expected sum in " ++ n)
  176. withProduct :: String -> (Product -> Parser a) -> Value -> Parser a
  177. withProduct n k val = case val of
  178. Product ps -> k ps
  179. _ -> Left ("Expected product in " ++ n)
  180. withList :: String -> (Array -> Parser a) -> Value -> Parser a
  181. withList n k val = case val of
  182. List ls -> k ls
  183. _ -> Left ("Expected list in " ++ n)
  184. withInteger :: String -> (Integer -> Parser a) -> Value -> Parser a
  185. withInteger n k val = case val of
  186. Integer i -> k i
  187. _ -> Left ("Expected integer in " ++ n)
  188. withDouble :: String -> (Double -> Parser a) -> Value -> Parser a
  189. withDouble n k val = case val of
  190. Double d -> k d
  191. Integer i -> k (fromIntegral i)
  192. _ -> Left ("Expected double in " ++ n)
  193. withSymbol :: String -> (T.Text -> Parser a) -> Value -> Parser a
  194. withSymbol n k val = case val of
  195. Symbol s -> k s
  196. _ -> Left ("Expected symbol in " ++ n)
  197. withString :: String -> (T.Text -> Parser a) -> Value -> Parser a
  198. withString n k val = case val of
  199. String s -> k s
  200. _ -> Left ("Expected string in " ++ n)
  201. (.:) :: FromAdnot a => Product -> T.Text -> Parser a
  202. map .: key = case MS.lookup key map of
  203. Just x -> parseAdnot x
  204. Nothing -> Left ("Missing key " ++ show key)
  205. (.:?) :: FromAdnot a => Product -> T.Text -> Parser (Maybe a)
  206. map .:? key = case MS.lookup key map of
  207. Just x -> Just <$> parseAdnot x
  208. Nothing -> return Nothing
  209. (.!=) :: Parser (Maybe a) -> a -> Parser a
  210. c .!= r = fmap (maybe r id) c
  211. class FromAdnot a where
  212. parseAdnot :: Value -> Parser a
  213. instance FromAdnot Value where
  214. parseAdnot = return
  215. -- Integer Types
  216. instance FromAdnot Int where
  217. parseAdnot = withInteger "Int" (return . fromIntegral)
  218. instance FromAdnot Integer where
  219. parseAdnot = withInteger "Int" return
  220. instance FromAdnot Int8 where
  221. parseAdnot = withInteger "Int8" (return . fromIntegral)
  222. instance FromAdnot Int16 where
  223. parseAdnot = withInteger "Int16" (return . fromIntegral)
  224. instance FromAdnot Int32 where
  225. parseAdnot = withInteger "Int32" (return . fromIntegral)
  226. instance FromAdnot Int64 where
  227. parseAdnot = withInteger "Int64" (return . fromIntegral)
  228. instance FromAdnot Word where
  229. parseAdnot = withInteger "Word" (return . fromIntegral)
  230. instance FromAdnot Word8 where
  231. parseAdnot = withInteger "Word8" (return . fromIntegral)
  232. instance FromAdnot Word16 where
  233. parseAdnot = withInteger "Word16" (return . fromIntegral)
  234. instance FromAdnot Word32 where
  235. parseAdnot = withInteger "Word32" (return . fromIntegral)
  236. instance FromAdnot Word64 where
  237. parseAdnot = withInteger "Word64" (return . fromIntegral)
  238. -- Rational/Floating types
  239. instance FromAdnot Double where
  240. parseAdnot = withDouble "Double" return
  241. instance FromAdnot Float where
  242. parseAdnot =
  243. withDouble "Float" (return . fromRational . toRational)
  244. -- String types
  245. instance {-# INCOHERENT #-} FromAdnot String where
  246. parseAdnot = withString "String" (return . T.unpack)
  247. instance FromAdnot T.Text where
  248. parseAdnot = withString "Text" return
  249. instance FromAdnot TL.Text where
  250. parseAdnot = withString "Text" (return . TL.fromStrict)
  251. instance FromAdnot Char where
  252. parseAdnot = withString "Char" $ \s -> case T.uncons s of
  253. Just (c, "") -> return c
  254. _ -> Left "Expected a single-element string"
  255. -- List types
  256. instance FromAdnot a => FromAdnot [a] where
  257. parseAdnot = withList "List" $ \ls ->
  258. F.toList <$> mapM parseAdnot ls
  259. instance FromAdnot a => FromAdnot (V.Vector a) where
  260. parseAdnot = withList "Vector" $ \ls ->
  261. mapM parseAdnot ls
  262. instance FromAdnot a => FromAdnot (Seq.Seq a) where
  263. parseAdnot = withList "Seq" $ \ls ->
  264. Seq.fromList . F.toList <$> mapM parseAdnot ls
  265. instance FromAdnot a => FromAdnot (NE.NonEmpty a) where
  266. parseAdnot = withList "NonEmpty" $ \ls -> do
  267. lst <- mapM parseAdnot ls
  268. case F.toList lst of
  269. [] -> Left "Expected non-empty sequence"
  270. (x:xs) -> Right (x NE.:| xs)
  271. -- Mapping types
  272. instance FromAdnot a => FromAdnot (MS.Map T.Text a) where
  273. parseAdnot = withProduct "Map" $ \ms -> do
  274. lst <- mapM parseAdnot ms
  275. return (MS.fromList (F.toList lst))
  276. -- Tuples
  277. instance FromAdnot () where
  278. parseAdnot = withList "()" $ \ls ->
  279. case ls of
  280. [] -> return ()
  281. _ -> Left "Expected empty list"
  282. instance (FromAdnot a, FromAdnot b) => FromAdnot (a, b) where
  283. parseAdnot = withList "(a, b)" $ \ls ->
  284. case ls of
  285. [a, b] -> (,) <$> parseAdnot a <*> parseAdnot b
  286. _ -> Left "Expected two-element list"
  287. instance (FromAdnot a, FromAdnot b, FromAdnot c) => FromAdnot (a, b, c) where
  288. parseAdnot = withList "(a, b, c)" $ \ls ->
  289. case ls of
  290. [a, b, c] -> (,,) <$> parseAdnot a <*> parseAdnot b <*> parseAdnot c
  291. _ -> Left "Expected three-element list"
  292. instance (FromAdnot a, FromAdnot b, FromAdnot c, FromAdnot d)
  293. => FromAdnot (a, b, c, d) where
  294. parseAdnot = withList "(a, b, c, d)" $ \ls ->
  295. case ls of
  296. [a, b, c, d] -> (,,,) <$> parseAdnot a <*> parseAdnot b
  297. <*> parseAdnot c <*> parseAdnot d
  298. _ -> Left "Expected four-element list"
  299. -- Common Haskell algebraic data types
  300. instance FromAdnot a => FromAdnot (Maybe a) where
  301. parseAdnot = withSum "Maybe" go
  302. where go "Nothing" [] = return Nothing
  303. go "Just" [x] = Just <$> parseAdnot x
  304. go _ _ = Left "Invalid Maybe"
  305. instance (FromAdnot a, FromAdnot b) => FromAdnot (Either a b) where
  306. parseAdnot = withSum "Either" go
  307. where go "Left" [x] = Left <$> parseAdnot x
  308. go "Right" [x] = Right <$> parseAdnot x
  309. go _ _ = Left "Invalid Either"
  310. instance FromAdnot Bool where
  311. parseAdnot = withSymbol "Bool" go
  312. where go "True" = return True
  313. go "False" = return False
  314. go _ = Left "Invalid Bool"