{- Copyright (c) Meta Platforms, Inc. and affiliates. All rights reserved. This source code is licensed under the BSD-style license found in the LICENSE file in the root directory of this source tree. -} module Glean.RTS.Foreign.Stacked ( Stacked , stacked ) where import Control.Exception (bracket) import Data.Text import Foreign.C.String import Foreign.Ptr import Util.FFI import Glean.RTS.Foreign.Define (Define(..), CanDefine(..)) import Glean.RTS.Foreign.Lookup (Lookup(..), CanLookup(..)) -- | An `a` stacked on top of a base 'CanLookup'. data Stacked a = forall base. CanLookup base => Stacked base a Text -- | Stack a value on top of a base 'CanLookup' stacked :: (CanLookup base, CanLookup a) => base -> a -> Stacked a stacked base l = Stacked base l name where name = lookupName base <> ";" <> lookupName l instance CanLookup a => CanLookup (Stacked a) where lookupName (Stacked _ _ name) = name withLookup (Stacked base added _) f = withLookup base $ \p_base -> withLookup added $ \p_added -> bracket (invoke $ glean_stacked_lookup_new p_base p_added) glean_lookup_free f instance CanDefine a => CanDefine (Stacked a) where withDefine (Stacked base added _) f = withLookup base $ \p_base -> withDefine added $ \p_added -> bracket (invoke $ glean_stacked_define_new p_base p_added) glean_stacked_define_free f foreign import ccall unsafe glean_stacked_lookup_new :: Ptr Lookup -> Ptr Lookup -> Ptr (Ptr Lookup) -> IO CString foreign import ccall unsafe glean_lookup_free :: Ptr Lookup -> IO () foreign import ccall unsafe glean_stacked_define_new :: Ptr Lookup -> Define -> Ptr Define -> IO CString foreign import ccall unsafe glean_stacked_define_free :: Define -> IO ()