Class.hs 13 KB

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