@@ -13,6 +13,9 @@ module Test.WebApi.StateModel
1313 , DSum (.. )
1414 , Val (.. )
1515 , ClientRequestVal (.. )
16+ , WebApiGlobalStateModel (.. )
17+ , successCall
18+ , successCallWith
1619 , mkWebApiAction
1720 , getOpIdFromRequest
1821 , getSuccessOut
@@ -52,7 +55,7 @@ import System.IO.Unsafe
5255import qualified Unsafe.Coerce as Unsafe
5356import qualified GHC.Base as Unsafe (Any )
5457import qualified Record
55- -- import Data.Reflection
58+ import Data.Reflection
5659
5760type WebApiActionCxt (apps :: [Type ]) (meth :: Type ) (app :: Type ) (r :: k ) =
5861 ( ToParam 'PathParam (PathParam meth (app :// r ))
@@ -186,28 +189,28 @@ resolveRequest lkp ClientRequestVal {query, form, header, path, file, body} =
186189 body <- Just $ resolveVal lkp body
187190 Just $ ClientRequest {query, form, header, path, file, body}
188191
189- data WebApiAction (apps :: [Type ]) (a :: Type ) where
192+ data WebApiAction s (apps :: [Type ]) (a :: Type ) where
190193 SuccessCall :: WebApiActionCxt apps meth app r
191194 => ClientRequestVal meth (app :// r )
192- -> SuccessApiModel apps meth (app :// r ) res
195+ -> SuccessApiModel s apps meth (app :// r ) res
193196 -> ModifyClientCookies
194197 -> (ApiSuccess meth (app :// r ) -> Either ResultError res )
195- -> WebApiAction apps res
198+ -> WebApiAction s apps res
196199 ErrorCall :: WebApiActionCxt apps meth app r
197200 => ClientRequest meth (app :// r )
198- -> WebApiAction apps (ApiErr meth (app :// r ))
201+ -> WebApiAction s apps (ApiErr meth (app :// r ))
199202 SomeExceptionCall :: WebApiActionCxt apps meth app r
200203 => ClientRequest meth (app :// r )
201- -> WebApiAction apps (SomeException )
204+ -> WebApiAction s apps (SomeException )
202205
203- instance Show (WebApiAction apps a ) where
206+ instance Show (WebApiAction s apps a ) where
204207 show = \ case
205208 SuccessCall creq _ _ _ -> show . getOpIdFromRequest $ creq
206209 ErrorCall creq -> show . unsafePerformIO . toWaiRequest . fromClientRequest $ creq
207210 SomeExceptionCall creq -> show . unsafePerformIO . toWaiRequest . fromClientRequest $ creq
208211
209212-- TODO: Revisit
210- instance Eq (WebApiAction apps a ) where
213+ instance Eq (WebApiAction s apps a ) where
211214 (==) (SuccessCall creq1 _ _ _) = \ case
212215 SuccessCall creq2 _ _ _ -> (getOpIdFromRequest $ creq1) == (getOpIdFromRequest $ creq2)
213216 _ -> False
@@ -218,7 +221,7 @@ instance Eq (WebApiAction apps a) where
218221 SomeExceptionCall creq2 -> (show . unsafePerformIO . toWaiRequest . fromClientRequest $ creq1) == (show . unsafePerformIO . toWaiRequest . fromClientRequest $ creq2)
219222 _ -> False
220223
221- instance HasVariables (WebApiAction apps a ) where
224+ instance HasVariables (WebApiAction s apps a ) where
222225 getAllVariables = \ case
223226 SuccessCall creq _ _ _ -> getAllVariables creq
224227
@@ -275,19 +278,19 @@ instance Monoid NamedEntityKeyed where
275278newtype Trail = Trail [Text ]
276279 deriving newtype (Show , Eq , Ord , Read )
277280
278- data ApiState (apps :: [Type ]) = ApiState
281+ data ApiState (s :: Type ) ( apps :: [Type ]) = ApiState
279282 { apiState :: M. Map TypeRep Unsafe. Any
280283 , namedEntityTyped :: NamedEntityTyped
281284 , namedEntityKeyed :: NamedEntityKeyed
282285 }
283286
284- instance Show (ApiState apps ) where
287+ instance Show (ApiState s apps ) where
285288 show (ApiState {apiState}) = " undefined" -- showTaggedPrec p $DMap.dmap
286289
287- instance Eq (ApiState apps ) where
290+ instance Eq (ApiState s apps ) where
288291 s1 == s2 = undefined
289292
290- modifyApiState :: forall app apps stTag . (Typeable app , AppIsElem app apps ) => DSum (stTag apps app ) Proxy -> (DSum (stTag apps app ) Identity -> DSum (stTag apps app ) Identity ) -> ApiState apps -> ApiState apps
293+ modifyApiState :: forall app apps stTag s . (Typeable app , AppIsElem app apps ) => DSum (stTag apps app ) Proxy -> (DSum (stTag apps app ) Identity -> DSum (stTag apps app ) Identity ) -> ApiState s apps -> ApiState s apps
291294modifyApiState ctor@ (tag :=> _) f (ApiState {apiState = stMap, namedEntityTyped}) = case M. lookup (typeRep (getAppProxy' ctor)) stMap of
292295 Nothing -> undefined
293296 Just anyv -> case f (tag :=> (Identity $ castToTagVal tag anyv)) of
@@ -302,7 +305,7 @@ modifyApiState ctor@(tag :=> _) f (ApiState {apiState = stMap, namedEntityTyped}
302305class HasApiState (apps1 :: [Type ]) stTag (apps :: [Type ]) where
303306 apiStateUniv :: Proxy apps1 -> (forall app . Typeable app => DSum (stTag apps app ) Proxy -> r ) -> [r ]
304307
305- initApiState :: forall apps stTag . HasApiState apps stTag apps => (forall app . Typeable app => DSum (stTag apps app ) Proxy -> DSum (stTag apps app ) Identity ) -> ApiState apps
308+ initApiState :: forall apps stTag s . HasApiState apps stTag apps => (forall app . Typeable app => DSum (stTag apps app ) Proxy -> DSum (stTag apps app ) Identity ) -> ApiState s apps
306309initApiState f = ApiState { apiState = M. fromList $ apiStateUniv (Proxy @ apps ) $ \ ctor -> case f ctor of
307310 tag :=> (Identity v) -> (typeRep (getAppProxy' ctor), Unsafe. unsafeCoerce v :: Unsafe. Any )
308311 }
@@ -312,20 +315,20 @@ getAppProxy' :: forall stTag apps app f. Typeable app => DSum (stTag apps app) f
312315getAppProxy' _ = Proxy
313316
314317
315- instance HasVariables (ApiState apps ) where
318+ instance HasVariables (ApiState s apps ) where
316319 getAllVariables = mempty
317320
318- data SuccessApiModel apps meth r a = SuccessApiModel
319- { nextState :: Maybe (Var a -> ApiState apps -> ApiState apps )
320- , failureNextState :: Maybe (ApiState apps -> ApiState apps )
321- , precondition :: Maybe (ApiState apps -> Bool )
322- , validFailingAction :: Maybe (ApiState apps -> Bool )
323- , shrinkAction :: Maybe (VarContext -> ApiState apps -> [Any (Action (ApiState apps ))])
324- , postCondition :: (ApiState apps , ApiState apps ) -> LookUp -> a -> Bool
325- , postconditionOnFailure :: (ApiState apps , ApiState apps ) -> LookUp -> Either ErrorState a -> Bool
321+ data SuccessApiModel s apps meth r a = SuccessApiModel
322+ { nextState :: Maybe (Var a -> ApiState s apps -> ApiState s apps )
323+ , failureNextState :: Maybe (ApiState s apps -> ApiState s apps )
324+ , precondition :: Maybe (ApiState s apps -> Bool )
325+ , validFailingAction :: Maybe (ApiState s apps -> Bool )
326+ , shrinkAction :: Maybe (VarContext -> ApiState s apps -> [Any (Action (ApiState s apps ))])
327+ , postCondition :: (ApiState s apps , ApiState s apps ) -> LookUp -> a -> Bool
328+ , postconditionOnFailure :: (ApiState s apps , ApiState s apps ) -> LookUp -> Either ErrorState a -> Bool
326329 }
327330
328- defSuccessApiModel :: SuccessApiModel apps meth r a
331+ defSuccessApiModel :: SuccessApiModel s apps meth r a
329332defSuccessApiModel = SuccessApiModel
330333 { nextState = Nothing
331334 , failureNextState = Nothing
@@ -334,31 +337,41 @@ defSuccessApiModel = SuccessApiModel
334337 , shrinkAction = Nothing
335338 }
336339
337- data FailureApiModel apps meth r a = FailureApiModel
338- { failureNextState :: Maybe (ApiState apps -> ApiState apps )
339- , precondition :: Maybe (ApiState apps -> Bool )
340- , validFailingAction :: Maybe (ApiState apps -> Bool )
341- , shrinkAction :: Maybe (VarContext -> ApiState apps -> [Any (Action (ApiState apps ))])
342- , postconditionOnFailure :: (ApiState apps , ApiState apps ) -> LookUp -> Either ErrorState a -> Bool
340+ data FailureApiModel s apps meth r a = FailureApiModel
341+ { failureNextState :: Maybe (ApiState s apps -> ApiState s apps )
342+ , precondition :: Maybe (ApiState s apps -> Bool )
343+ , validFailingAction :: Maybe (ApiState s apps -> Bool )
344+ , shrinkAction :: Maybe (VarContext -> ApiState s apps -> [Any (Action (ApiState s apps ))])
345+ , postconditionOnFailure :: (ApiState s apps , ApiState s apps ) -> LookUp -> Either ErrorState a -> Bool
343346 }
344347
345- mkWebApiAction :: WebApiAction apps a -> Action (ApiState apps ) a
348+ mkWebApiAction :: WebApiAction s apps a -> Action (ApiState s apps ) a
346349mkWebApiAction = coerce
347350
348351newtype ApiInitState apps = ApiInitState (M. Map TypeRep Unsafe. Any )
349352
350- instance StateModel (ApiState apps ) where
351- newtype Action (ApiState apps ) a = MkWebApiAction (WebApiAction apps a )
353+ data WebApiGlobalStateModel apps = WebApiGlobalStateModel
354+ { appAribitaryAction :: forall (s :: Type ). VarContext -> ApiState s apps -> Any (Action (ApiState s apps ))
355+ , appInitState :: ApiInitState apps
356+ , namedEntityTyped :: NamedEntityTyped
357+ , namedEntityKeyed :: NamedEntityKeyed
358+ }
359+
360+ instance (Reifies s (WebApiGlobalStateModel apps )) => StateModel (ApiState s apps ) where
361+ newtype Action (ApiState s apps ) a = MkWebApiAction (WebApiAction s apps a )
352362 deriving newtype (Show , Eq , HasVariables )
353363
354364 actionName = \ case
355365 MkWebApiAction (SuccessCall creq _ _ _) -> getOpIdFromRequest creq
356366 MkWebApiAction (ErrorCall creq) -> getOpIdFromRequest creq
357367 MkWebApiAction (SomeExceptionCall creq) -> getOpIdFromRequest creq
358368
359- arbitraryAction _varCxt _s = pure undefined
369+ arbitraryAction varCxt s = case reflect (Proxy @ s ) of
370+ WebApiGlobalStateModel {appAribitaryAction} -> pure $ appAribitaryAction @ s varCxt s
360371
361- initialState = ApiState {apiState = mempty , namedEntityTyped = mempty }
372+ initialState =
373+ let WebApiGlobalStateModel {appInitState, namedEntityTyped, namedEntityKeyed} = reflect (Proxy @ s )
374+ in ApiState {apiState = coerce appInitState, namedEntityTyped, namedEntityKeyed}
362375
363376 nextState s (MkWebApiAction act) var = case act of
364377 SuccessCall creq SuccessApiModel {nextState= nsMay} _ _ -> maybe s (\ ns -> ns var s) nsMay
@@ -417,8 +430,8 @@ instance Show SetCookieUpdate where
417430 show SetCookieUpdate {setCookieUpdateOpName} = T. unpack setCookieUpdateOpName
418431
419432
420- instance RunModel (ApiState apps ) (WebApiSessions apps ) where
421- type Error (ApiState apps ) (WebApiSessions apps ) = ErrorState
433+ instance ( Reifies s ( WebApiGlobalStateModel apps )) => RunModel (ApiState s apps ) (WebApiSessions apps ) where
434+ type Error (ApiState s apps ) (WebApiSessions apps ) = ErrorState
422435 perform _ act lkp = case act of
423436 MkWebApiAction (SuccessCall creq' model cookMod f) -> do
424437 case resolveRequest lkp creq' of
@@ -469,13 +482,25 @@ instance RunModel (ApiState apps) (WebApiSessions apps) where
469482 QC. counterexample (show err ++ " <- " ++ actionName act ++ " \n -- State: " ++ show s')
470483 . QC. tabulate " Registry size" [" Val1" , " Val2" ]
471484
472- instance DynLogicModel (ApiState apps ) where
485+ instance ( Reifies s ( WebApiGlobalStateModel apps )) => DynLogicModel (ApiState s apps ) where
473486 restricted _ = False
474487
488+ successCall :: forall meth r app apps s . WebApiActionCxt apps meth app r =>
489+ ClientRequestVal meth (app :// r )
490+ -> Action (ApiState s apps ) (ApiOut meth (app :// r ))
491+ successCall creq = mkWebApiAction $ SuccessCall creq defSuccessApiModel NoCookiesMod (Right . getSuccessOut)
492+
493+ successCallWith :: forall meth r app res apps s . (Typeable res , WebApiActionCxt apps meth app r ) =>
494+ ClientRequestVal meth (app :// r )
495+ -> ModifyClientCookies
496+ -> (ApiSuccess meth (app :// r ) -> Either ResultError res )
497+ -> Action (ApiState s apps ) res
498+ successCallWith creq cookMod f = mkWebApiAction (SuccessCall creq defSuccessApiModel cookMod f)
499+
475500-- data ShowDict a where
476501-- ShowDict :: Show a => ShowDict a
477502
478- -- showDictAction :: forall apps a. Action (ApiState apps) a -> ShowDict a
503+ -- showDictAction :: forall apps a. Action (ApiState s apps) a -> ShowDict a
479504-- showDictAction = \case
480505-- MkWebApiAction (SuccessCall {}) -> ShowDict
481506
0 commit comments