bolty-0.2.0.0: src/Database/Bolty/AccessMode.hs
-- | Access mode for Bolt transactions and routing.
--
-- The Bolt protocol carries a @mode@ field on BEGIN and RUN messages whose
-- only valid values are @"r"@ (read) and @"w"@ (write). This module hides
-- that wire shape behind a sum type so consumers can't construct invalid
-- modes, and so the read\/write distinction reads as data at use sites
-- (cluster routing, transaction primitives, session management).
--
-- The 'PackStream' instance is the single point where the wire encoding
-- lives: 'ReadAccess' \<-\> @"r"@, 'WriteAccess' \<-\> @"w"@.
module Database.Bolty.AccessMode
( AccessMode(..)
) where
import Data.Kind (Type)
import Data.PackStream (PackStream(..), Ps(..), Result(..), withString)
import GHC.Generics (Generic)
-- | Whether a transaction (or session connection) is intended for reading
-- or writing. The value flows to two distinct layers:
--
-- * Cluster routing (Session\/Routing layer): 'ReadAccess' picks a follower,
-- 'WriteAccess' picks the leader. No-op on non-clustered connections.
-- * Per-transaction enforcement (BEGIN\/RUN @mode@): 'ReadAccess' instructs
-- the server to reject write attempts upfront (Neo4j 5+); 'WriteAccess'
-- is the default and allows writes.
type AccessMode :: Type
data AccessMode = ReadAccess | WriteAccess
deriving stock (Show, Eq, Ord, Enum, Bounded, Generic)
-- | Wire format: a single-character PackStream string, @"r"@ or @"w"@.
-- @fromPs@ rejects any other string to preserve the invariant on decode.
instance PackStream AccessMode where
toPs ReadAccess = PsString "r"
toPs WriteAccess = PsString "w"
fromPs = withString "AccessMode" $ \t -> case t of
"r" -> Success ReadAccess
"w" -> Success WriteAccess
_ -> Error ("expected mode \"r\" or \"w\", got: " <> t)