|
@@ -1,54 +1,80 @@
|
|
|
{-# LANGUAGE RankNTypes #-}
|
|
|
{-# LANGUAGE LambdaCase #-}
|
|
|
+{-# LANGUAGE DeriveFunctor #-}
|
|
|
|
|
|
-module Codec.ActivityStream.LensInternal where
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+module Codec.ActivityStream.LensInternal
|
|
|
+ ( get
|
|
|
+ , set
|
|
|
+ , Lens'
|
|
|
+ , makeLens
|
|
|
+ , makeAesonLensMb
|
|
|
+ , makeAesonLens
|
|
|
+ ) where
|
|
|
|
|
|
import Data.Aeson as Aeson
|
|
|
import qualified Data.HashMap.Strict as HM
|
|
|
import Data.Maybe (fromJust)
|
|
|
import Data.Text (Text)
|
|
|
|
|
|
-newtype Const a b = Const { fromConst :: a }
|
|
|
-instance Functor (Const a) where fmap f (Const x) = Const x
|
|
|
-
|
|
|
|
|
|
-newtype Id a = Id { fromId :: a }
|
|
|
-instance Functor Id where fmap f (Id x) = Id (f x)
|
|
|
+newtype C a b = C { fromC :: a } deriving (Functor)
|
|
|
+newtype I a = I { fromI :: a } deriving (Functor)
|
|
|
|
|
|
+
|
|
|
+
|
|
|
type Lens' a b = forall f. Functor f => (b -> f b) -> (a -> f a)
|
|
|
|
|
|
get :: Lens' a b -> a -> b
|
|
|
-get lens a = fromConst (lens Const a)
|
|
|
+get lens a = fromC (lens C a)
|
|
|
|
|
|
set :: Lens' a b -> b -> a -> a
|
|
|
-set lens x a = fromId (lens (const Id x) a)
|
|
|
+set lens x a = fromI (lens (const I x) a)
|
|
|
|
|
|
makeLens :: (a -> b) -> (b -> a -> a) -> Lens' a b
|
|
|
makeLens get set f a = (`set` a) `fmap` f (get a)
|
|
|
|
|
|
+
|
|
|
+
|
|
|
fromJSON' :: FromJSON a => Aeson.Value -> Maybe a
|
|
|
fromJSON' v = case fromJSON v of
|
|
|
Success a -> Just a
|
|
|
Error _ -> Nothing
|
|
|
|
|
|
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
makeAesonLensMb :: (FromJSON v, ToJSON v)
|
|
|
=> Text -> Lens' c Aeson.Object -> Lens' c (Maybe v)
|
|
|
-makeAesonLensMb key fromObj = fromObj . lens
|
|
|
- where lens = makeLens
|
|
|
- (\ o -> HM.lookup key o >>= fromJSON')
|
|
|
- (\case Just v -> HM.insert key (toJSON v)
|
|
|
- Nothing -> HM.delete key)
|
|
|
+makeAesonLensMb key fromObj = fromObj . makeLens g s
|
|
|
+ where g o = HM.lookup key o >>= fromJSON'
|
|
|
+ s (Just v) o = HM.insert key (toJSON v) o
|
|
|
+ s Nothing o = HM.delete key o
|
|
|
|
|
|
|
|
|
+
|
|
|
+
|
|
|
makeAesonLens :: (FromJSON v, ToJSON v)
|
|
|
=> Text -> Lens' c Aeson.Object -> Lens' c v
|
|
|
-makeAesonLens key fromObj = fromObj . lens
|
|
|
- where lens = makeLens
|
|
|
- (\ o -> fromJust (HM.lookup key o >>= fromJSON'))
|
|
|
- (\ v o -> HM.insert key (toJSON v) o)
|
|
|
+makeAesonLens key fromObj = fromObj . makeLens g s
|
|
|
+ where g o = fromJust (HM.lookup key o >>= fromJSON')
|
|
|
+ s v o = HM.insert key (toJSON v) o
|