{-# LANGUAGE DerivingStrategies         #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE NamedFieldPuns             #-}
{-# LANGUAGE OverloadedLists            #-}
{-# LANGUAGE OverloadedStrings          #-}
module Auth.Biscuit.Symbols
  ( Symbols
  , BlockSymbols
  , ReverseSymbols
  , SymbolRef (..)
  , PublicKeyRef (..)
  , getSymbol
  , getPublicKey'
  , addSymbols
  , addFromBlock
  , registerNewSymbols
  , registerNewPublicKeys
  , forgetSymbols
  , reverseSymbols
  , getSymbolList
  , getPkList
  , getPkTable
  , getSymbolCode
  , getPublicKeyCode
  , newSymbolTable
  ) where

import           Auth.Biscuit.Crypto (PublicKey)
import           Data.Int            (Int64)
import           Data.List           ((\\))
import           Data.Map            (Map, elems, (!?))
import qualified Data.Map            as Map
import           Data.Set            (Set, difference, union)
import qualified Data.Set            as Set
import           Data.Text           (Text)

import           Auth.Biscuit.Utils  (maybeToRight)

newtype SymbolRef = SymbolRef { SymbolRef -> Int64
getSymbolRef :: Int64 }
  deriving stock (SymbolRef -> SymbolRef -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SymbolRef -> SymbolRef -> Bool
$c/= :: SymbolRef -> SymbolRef -> Bool
== :: SymbolRef -> SymbolRef -> Bool
$c== :: SymbolRef -> SymbolRef -> Bool
Eq, Eq SymbolRef
SymbolRef -> SymbolRef -> Bool
SymbolRef -> SymbolRef -> Ordering
SymbolRef -> SymbolRef -> SymbolRef
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: SymbolRef -> SymbolRef -> SymbolRef
$cmin :: SymbolRef -> SymbolRef -> SymbolRef
max :: SymbolRef -> SymbolRef -> SymbolRef
$cmax :: SymbolRef -> SymbolRef -> SymbolRef
>= :: SymbolRef -> SymbolRef -> Bool
$c>= :: SymbolRef -> SymbolRef -> Bool
> :: SymbolRef -> SymbolRef -> Bool
$c> :: SymbolRef -> SymbolRef -> Bool
<= :: SymbolRef -> SymbolRef -> Bool
$c<= :: SymbolRef -> SymbolRef -> Bool
< :: SymbolRef -> SymbolRef -> Bool
$c< :: SymbolRef -> SymbolRef -> Bool
compare :: SymbolRef -> SymbolRef -> Ordering
$ccompare :: SymbolRef -> SymbolRef -> Ordering
Ord)
  deriving newtype (Int -> SymbolRef
SymbolRef -> Int
SymbolRef -> [SymbolRef]
SymbolRef -> SymbolRef
SymbolRef -> SymbolRef -> [SymbolRef]
SymbolRef -> SymbolRef -> SymbolRef -> [SymbolRef]
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: SymbolRef -> SymbolRef -> SymbolRef -> [SymbolRef]
$cenumFromThenTo :: SymbolRef -> SymbolRef -> SymbolRef -> [SymbolRef]
enumFromTo :: SymbolRef -> SymbolRef -> [SymbolRef]
$cenumFromTo :: SymbolRef -> SymbolRef -> [SymbolRef]
enumFromThen :: SymbolRef -> SymbolRef -> [SymbolRef]
$cenumFromThen :: SymbolRef -> SymbolRef -> [SymbolRef]
enumFrom :: SymbolRef -> [SymbolRef]
$cenumFrom :: SymbolRef -> [SymbolRef]
fromEnum :: SymbolRef -> Int
$cfromEnum :: SymbolRef -> Int
toEnum :: Int -> SymbolRef
$ctoEnum :: Int -> SymbolRef
pred :: SymbolRef -> SymbolRef
$cpred :: SymbolRef -> SymbolRef
succ :: SymbolRef -> SymbolRef
$csucc :: SymbolRef -> SymbolRef
Enum)

instance Show SymbolRef where
  show :: SymbolRef -> String
show = (String
"#" forall a. Semigroup a => a -> a -> a
<>) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> String
show forall b c a. (b -> c) -> (a -> b) -> a -> c
. SymbolRef -> Int64
getSymbolRef

newtype PublicKeyRef = PublicKeyRef { PublicKeyRef -> Int64
getPublicKeyRef :: Int64 }
  deriving stock (PublicKeyRef -> PublicKeyRef -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PublicKeyRef -> PublicKeyRef -> Bool
$c/= :: PublicKeyRef -> PublicKeyRef -> Bool
== :: PublicKeyRef -> PublicKeyRef -> Bool
$c== :: PublicKeyRef -> PublicKeyRef -> Bool
Eq, Eq PublicKeyRef
PublicKeyRef -> PublicKeyRef -> Bool
PublicKeyRef -> PublicKeyRef -> Ordering
PublicKeyRef -> PublicKeyRef -> PublicKeyRef
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: PublicKeyRef -> PublicKeyRef -> PublicKeyRef
$cmin :: PublicKeyRef -> PublicKeyRef -> PublicKeyRef
max :: PublicKeyRef -> PublicKeyRef -> PublicKeyRef
$cmax :: PublicKeyRef -> PublicKeyRef -> PublicKeyRef
>= :: PublicKeyRef -> PublicKeyRef -> Bool
$c>= :: PublicKeyRef -> PublicKeyRef -> Bool
> :: PublicKeyRef -> PublicKeyRef -> Bool
$c> :: PublicKeyRef -> PublicKeyRef -> Bool
<= :: PublicKeyRef -> PublicKeyRef -> Bool
$c<= :: PublicKeyRef -> PublicKeyRef -> Bool
< :: PublicKeyRef -> PublicKeyRef -> Bool
$c< :: PublicKeyRef -> PublicKeyRef -> Bool
compare :: PublicKeyRef -> PublicKeyRef -> Ordering
$ccompare :: PublicKeyRef -> PublicKeyRef -> Ordering
Ord)
  deriving newtype (Int -> PublicKeyRef
PublicKeyRef -> Int
PublicKeyRef -> [PublicKeyRef]
PublicKeyRef -> PublicKeyRef
PublicKeyRef -> PublicKeyRef -> [PublicKeyRef]
PublicKeyRef -> PublicKeyRef -> PublicKeyRef -> [PublicKeyRef]
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: PublicKeyRef -> PublicKeyRef -> PublicKeyRef -> [PublicKeyRef]
$cenumFromThenTo :: PublicKeyRef -> PublicKeyRef -> PublicKeyRef -> [PublicKeyRef]
enumFromTo :: PublicKeyRef -> PublicKeyRef -> [PublicKeyRef]
$cenumFromTo :: PublicKeyRef -> PublicKeyRef -> [PublicKeyRef]
enumFromThen :: PublicKeyRef -> PublicKeyRef -> [PublicKeyRef]
$cenumFromThen :: PublicKeyRef -> PublicKeyRef -> [PublicKeyRef]
enumFrom :: PublicKeyRef -> [PublicKeyRef]
$cenumFrom :: PublicKeyRef -> [PublicKeyRef]
fromEnum :: PublicKeyRef -> Int
$cfromEnum :: PublicKeyRef -> Int
toEnum :: Int -> PublicKeyRef
$ctoEnum :: Int -> PublicKeyRef
pred :: PublicKeyRef -> PublicKeyRef
$cpred :: PublicKeyRef -> PublicKeyRef
succ :: PublicKeyRef -> PublicKeyRef
$csucc :: PublicKeyRef -> PublicKeyRef
Enum)

instance Show PublicKeyRef where
  show :: PublicKeyRef -> String
show = (String
"#" forall a. Semigroup a => a -> a -> a
<>) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Show a => a -> String
show forall b c a. (b -> c) -> (a -> b) -> a -> c
. PublicKeyRef -> Int64
getPublicKeyRef

data Symbols = Symbols
  { Symbols -> Map SymbolRef Text
symbols    :: Map SymbolRef Text
  , Symbols -> Map PublicKeyRef PublicKey
publicKeys :: Map PublicKeyRef PublicKey
  } deriving stock (Symbols -> Symbols -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Symbols -> Symbols -> Bool
$c/= :: Symbols -> Symbols -> Bool
== :: Symbols -> Symbols -> Bool
$c== :: Symbols -> Symbols -> Bool
Eq, Int -> Symbols -> ShowS
[Symbols] -> ShowS
Symbols -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Symbols] -> ShowS
$cshowList :: [Symbols] -> ShowS
show :: Symbols -> String
$cshow :: Symbols -> String
showsPrec :: Int -> Symbols -> ShowS
$cshowsPrec :: Int -> Symbols -> ShowS
Show)

data BlockSymbols = BlockSymbols
  { BlockSymbols -> Map SymbolRef Text
blockSymbols    :: Map SymbolRef Text
  , BlockSymbols -> Map PublicKeyRef PublicKey
blockPublicKeys :: Map PublicKeyRef PublicKey
  } deriving stock (BlockSymbols -> BlockSymbols -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: BlockSymbols -> BlockSymbols -> Bool
$c/= :: BlockSymbols -> BlockSymbols -> Bool
== :: BlockSymbols -> BlockSymbols -> Bool
$c== :: BlockSymbols -> BlockSymbols -> Bool
Eq, Int -> BlockSymbols -> ShowS
[BlockSymbols] -> ShowS
BlockSymbols -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [BlockSymbols] -> ShowS
$cshowList :: [BlockSymbols] -> ShowS
show :: BlockSymbols -> String
$cshow :: BlockSymbols -> String
showsPrec :: Int -> BlockSymbols -> ShowS
$cshowsPrec :: Int -> BlockSymbols -> ShowS
Show)

instance Semigroup BlockSymbols where
  BlockSymbols
b <> :: BlockSymbols -> BlockSymbols -> BlockSymbols
<> BlockSymbols
b' = BlockSymbols
              { blockSymbols :: Map SymbolRef Text
blockSymbols = BlockSymbols -> Map SymbolRef Text
blockSymbols BlockSymbols
b forall a. Semigroup a => a -> a -> a
<> BlockSymbols -> Map SymbolRef Text
blockSymbols BlockSymbols
b'
              , blockPublicKeys :: Map PublicKeyRef PublicKey
blockPublicKeys = BlockSymbols -> Map PublicKeyRef PublicKey
blockPublicKeys BlockSymbols
b forall a. Semigroup a => a -> a -> a
<> BlockSymbols -> Map PublicKeyRef PublicKey
blockPublicKeys BlockSymbols
b'
              }

data ReverseSymbols = ReverseSymbols
  { ReverseSymbols -> Map Text SymbolRef
reverseSymbolMap    :: Map Text SymbolRef
  , ReverseSymbols -> Map PublicKey PublicKeyRef
reversePublicKeyMap :: Map PublicKey PublicKeyRef
  }
  deriving stock (ReverseSymbols -> ReverseSymbols -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ReverseSymbols -> ReverseSymbols -> Bool
$c/= :: ReverseSymbols -> ReverseSymbols -> Bool
== :: ReverseSymbols -> ReverseSymbols -> Bool
$c== :: ReverseSymbols -> ReverseSymbols -> Bool
Eq, Int -> ReverseSymbols -> ShowS
[ReverseSymbols] -> ShowS
ReverseSymbols -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ReverseSymbols] -> ShowS
$cshowList :: [ReverseSymbols] -> ShowS
show :: ReverseSymbols -> String
$cshow :: ReverseSymbols -> String
showsPrec :: Int -> ReverseSymbols -> ShowS
$cshowsPrec :: Int -> ReverseSymbols -> ShowS
Show)

instance Semigroup ReverseSymbols where
  ReverseSymbols
b <> :: ReverseSymbols -> ReverseSymbols -> ReverseSymbols
<> ReverseSymbols
b' = ReverseSymbols
              { reverseSymbolMap :: Map Text SymbolRef
reverseSymbolMap = ReverseSymbols -> Map Text SymbolRef
reverseSymbolMap ReverseSymbols
b forall a. Semigroup a => a -> a -> a
<> ReverseSymbols -> Map Text SymbolRef
reverseSymbolMap ReverseSymbols
b'
              , reversePublicKeyMap :: Map PublicKey PublicKeyRef
reversePublicKeyMap = ReverseSymbols -> Map PublicKey PublicKeyRef
reversePublicKeyMap ReverseSymbols
b forall a. Semigroup a => a -> a -> a
<> ReverseSymbols -> Map PublicKey PublicKeyRef
reversePublicKeyMap ReverseSymbols
b'
              }

getNextOffset :: Symbols -> SymbolRef
getNextOffset :: Symbols -> SymbolRef
getNextOffset (Symbols Map SymbolRef Text
m Map PublicKeyRef PublicKey
_) =
  Int64 -> SymbolRef
SymbolRef forall a b. (a -> b) -> a -> b
$ forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ Int
1024 forall a. Num a => a -> a -> a
+ (forall k a. Map k a -> Int
Map.size Map SymbolRef Text
m forall a. Num a => a -> a -> a
- forall k a. Map k a -> Int
Map.size Map SymbolRef Text
commonSymbols)

getNextPublicKeyOffset :: Symbols -> PublicKeyRef
getNextPublicKeyOffset :: Symbols -> PublicKeyRef
getNextPublicKeyOffset (Symbols Map SymbolRef Text
_ Map PublicKeyRef PublicKey
m) =
  Int64 -> PublicKeyRef
PublicKeyRef forall a b. (a -> b) -> a -> b
$ forall a b. (Integral a, Num b) => a -> b
fromIntegral forall a b. (a -> b) -> a -> b
$ forall k a. Map k a -> Int
Map.size Map PublicKeyRef PublicKey
m

getSymbol :: Symbols -> SymbolRef -> Either String Text
getSymbol :: Symbols -> SymbolRef -> Either String Text
getSymbol (Symbols Map SymbolRef Text
m Map PublicKeyRef PublicKey
_) SymbolRef
i =
  forall b a. b -> Maybe a -> Either b a
maybeToRight (String
"Missing symbol at id " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show SymbolRef
i) forall a b. (a -> b) -> a -> b
$ Map SymbolRef Text
m forall k a. Ord k => Map k a -> k -> Maybe a
!? SymbolRef
i

getPublicKey' :: Symbols -> PublicKeyRef -> Either String PublicKey
getPublicKey' :: Symbols -> PublicKeyRef -> Either String PublicKey
getPublicKey' (Symbols Map SymbolRef Text
_ Map PublicKeyRef PublicKey
m) PublicKeyRef
i =
  forall b a. b -> Maybe a -> Either b a
maybeToRight (String
"Missing symbol at id " forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show PublicKeyRef
i) forall a b. (a -> b) -> a -> b
$ Map PublicKeyRef PublicKey
m forall k a. Ord k => Map k a -> k -> Maybe a
!? PublicKeyRef
i

-- | Given already existing symbols and a set of symbols used in a block,
-- compute the symbol table carried by this specific block
addSymbols :: Symbols -> Set Text -> Set PublicKey -> BlockSymbols
addSymbols :: Symbols -> Set Text -> Set PublicKey -> BlockSymbols
addSymbols s :: Symbols
s@(Symbols Map SymbolRef Text
sm Map PublicKeyRef PublicKey
pkm) Set Text
bSymbols Set PublicKey
pks =
  let existingSymbols :: Set Text
existingSymbols = forall a. Ord a => [a] -> Set a
Set.fromList (forall k a. Map k a -> [a]
elems Map SymbolRef Text
commonSymbols) forall a. Ord a => Set a -> Set a -> Set a
`union` forall a. Ord a => [a] -> Set a
Set.fromList (forall k a. Map k a -> [a]
elems Map SymbolRef Text
sm)
      newSymbols :: [Text]
newSymbols = forall a. Set a -> [a]
Set.toList forall a b. (a -> b) -> a -> b
$ Set Text
bSymbols forall a. Ord a => Set a -> Set a -> Set a
`difference` Set Text
existingSymbols
      starting :: SymbolRef
starting = Symbols -> SymbolRef
getNextOffset Symbols
s
      existingPks :: Set PublicKey
existingPks = forall a. Ord a => [a] -> Set a
Set.fromList (forall k a. Map k a -> [a]
elems Map PublicKeyRef PublicKey
pkm)
      newPks :: [PublicKey]
newPks = forall a. Set a -> [a]
Set.toList forall a b. (a -> b) -> a -> b
$ Set PublicKey
pks forall a. Ord a => Set a -> Set a -> Set a
`difference` Set PublicKey
existingPks
      startingPk :: PublicKeyRef
startingPk = Symbols -> PublicKeyRef
getNextPublicKeyOffset Symbols
s
   in BlockSymbols
        { blockSymbols :: Map SymbolRef Text
blockSymbols = forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList (forall a b. [a] -> [b] -> [(a, b)]
zip [SymbolRef
starting..] [Text]
newSymbols)
        , blockPublicKeys :: Map PublicKeyRef PublicKey
blockPublicKeys = forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList (forall a b. [a] -> [b] -> [(a, b)]
zip [PublicKeyRef
startingPk..] [PublicKey]
newPks)
        }

getSymbolList :: BlockSymbols -> [Text]
getSymbolList :: BlockSymbols -> [Text]
getSymbolList (BlockSymbols Map SymbolRef Text
m Map PublicKeyRef PublicKey
_) = forall k a. Map k a -> [a]
Map.elems Map SymbolRef Text
m

getPkList :: BlockSymbols -> [PublicKey]
getPkList :: BlockSymbols -> [PublicKey]
getPkList (BlockSymbols Map SymbolRef Text
_ Map PublicKeyRef PublicKey
m) = forall k a. Map k a -> [a]
Map.elems Map PublicKeyRef PublicKey
m

getPkTable :: Symbols -> [PublicKey]
getPkTable :: Symbols -> [PublicKey]
getPkTable (Symbols Map SymbolRef Text
_ Map PublicKeyRef PublicKey
m) = forall k a. Map k a -> [a]
Map.elems Map PublicKeyRef PublicKey
m

newSymbolTable :: Symbols
newSymbolTable :: Symbols
newSymbolTable = Map SymbolRef Text -> Map PublicKeyRef PublicKey -> Symbols
Symbols Map SymbolRef Text
commonSymbols forall k a. Map k a
Map.empty

-- | Given the symbol table of a protobuf block, update the provided symbol table
addFromBlock :: Symbols -> BlockSymbols -> Symbols
addFromBlock :: Symbols -> BlockSymbols -> Symbols
addFromBlock (Symbols Map SymbolRef Text
sm Map PublicKeyRef PublicKey
pkm) (BlockSymbols Map SymbolRef Text
bsm Map PublicKeyRef PublicKey
bpkm) =
   Symbols
     { symbols :: Map SymbolRef Text
symbols = Map SymbolRef Text
sm forall a. Semigroup a => a -> a -> a
<> Map SymbolRef Text
bsm
     , publicKeys :: Map PublicKeyRef PublicKey
publicKeys = Map PublicKeyRef PublicKey
pkm forall a. Semigroup a => a -> a -> a
<> Map PublicKeyRef PublicKey
bpkm
     }

registerNewSymbols :: [Text] -> Symbols -> Symbols
registerNewSymbols :: [Text] -> Symbols -> Symbols
registerNewSymbols [Text]
newSymbols s :: Symbols
s@Symbols{Map SymbolRef Text
symbols :: Map SymbolRef Text
symbols :: Symbols -> Map SymbolRef Text
symbols} =
  let newSymbolsMap :: Map SymbolRef Text
newSymbolsMap = forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList forall a b. (a -> b) -> a -> b
$ forall a b. [a] -> [b] -> [(a, b)]
zip [Symbols -> SymbolRef
getNextOffset Symbols
s..] [Text]
newSymbols
   in Symbols
s { symbols :: Map SymbolRef Text
symbols = Map SymbolRef Text
symbols forall a. Semigroup a => a -> a -> a
<> Map SymbolRef Text
newSymbolsMap }

registerNewPublicKeys :: [PublicKey] -> Symbols -> Symbols
registerNewPublicKeys :: [PublicKey] -> Symbols -> Symbols
registerNewPublicKeys [PublicKey]
newPks s :: Symbols
s@Symbols{Map PublicKeyRef PublicKey
publicKeys :: Map PublicKeyRef PublicKey
publicKeys :: Symbols -> Map PublicKeyRef PublicKey
publicKeys} =
  let newPkMap :: Map PublicKeyRef PublicKey
newPkMap = forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList forall a b. (a -> b) -> a -> b
$ forall a b. [a] -> [b] -> [(a, b)]
zip [Symbols -> PublicKeyRef
getNextPublicKeyOffset Symbols
s..] ([PublicKey]
newPks forall a. Eq a => [a] -> [a] -> [a]
\\ forall k a. Map k a -> [a]
elems Map PublicKeyRef PublicKey
publicKeys)
   in Symbols
s { publicKeys :: Map PublicKeyRef PublicKey
publicKeys = Map PublicKeyRef PublicKey
publicKeys forall a. Semigroup a => a -> a -> a
<> Map PublicKeyRef PublicKey
newPkMap }

forgetSymbols :: Symbols -> Symbols
forgetSymbols :: Symbols -> Symbols
forgetSymbols Symbols
s = Symbols
s { symbols :: Map SymbolRef Text
symbols = Map SymbolRef Text
commonSymbols }

-- | Reverse a symbol table
reverseSymbols :: Symbols -> ReverseSymbols
reverseSymbols :: Symbols -> ReverseSymbols
reverseSymbols (Symbols Map SymbolRef Text
sm Map PublicKeyRef PublicKey
pkm) =
  let swap :: (b, a) -> (a, b)
swap (b
a,a
b) = (a
b,b
a)
      reverseMap :: (Ord a, Ord b) => Map a b -> Map b a
      reverseMap :: forall a b. (Ord a, Ord b) => Map a b -> Map b a
reverseMap = forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall {b} {a}. (b, a) -> (a, b)
swap forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall k a. Map k a -> [(k, a)]
Map.toList
   in ReverseSymbols
       { reverseSymbolMap :: Map Text SymbolRef
reverseSymbolMap = forall a b. (Ord a, Ord b) => Map a b -> Map b a
reverseMap Map SymbolRef Text
sm
       , reversePublicKeyMap :: Map PublicKey PublicKeyRef
reversePublicKeyMap = forall a b. (Ord a, Ord b) => Map a b -> Map b a
reverseMap Map PublicKeyRef PublicKey
pkm
       }

-- | Given a reverse symbol table (symbol refs indexed by their textual
-- representation), turn textual representations into symbol refs.
-- This function is partial, the reverse table is guaranteed to
-- contain the expected textual symbols.
getSymbolCode :: ReverseSymbols -> Text -> SymbolRef
getSymbolCode :: ReverseSymbols -> Text -> SymbolRef
getSymbolCode (ReverseSymbols Map Text SymbolRef
rm Map PublicKey PublicKeyRef
_) Text
t = Map Text SymbolRef
rm forall k a. Ord k => Map k a -> k -> a
Map.! Text
t

getPublicKeyCode :: ReverseSymbols -> PublicKey -> Int64
getPublicKeyCode :: ReverseSymbols -> PublicKey -> Int64
getPublicKeyCode (ReverseSymbols Map Text SymbolRef
_ Map PublicKey PublicKeyRef
rm) PublicKey
t = PublicKeyRef -> Int64
getPublicKeyRef forall a b. (a -> b) -> a -> b
$ Map PublicKey PublicKeyRef
rm forall k a. Ord k => Map k a -> k -> a
Map.! PublicKey
t

-- | The common symbols defined in the biscuit spec
commonSymbols :: Map SymbolRef Text
commonSymbols :: Map SymbolRef Text
commonSymbols = forall k a. Ord k => [(k, a)] -> Map k a
Map.fromList forall a b. (a -> b) -> a -> b
$ forall a b. [a] -> [b] -> [(a, b)]
zip [Int64 -> SymbolRef
SymbolRef Int64
0..]
  [ Text
"read"
  , Text
"write"
  , Text
"resource"
  , Text
"operation"
  , Text
"right"
  , Text
"time"
  , Text
"role"
  , Text
"owner"
  , Text
"tenant"
  , Text
"namespace"
  , Text
"user"
  , Text
"team"
  , Text
"service"
  , Text
"admin"
  , Text
"email"
  , Text
"group"
  , Text
"member"
  , Text
"ip_address"
  , Text
"client"
  , Text
"client_ip"
  , Text
"domain"
  , Text
"path"
  , Text
"version"
  , Text
"cluster"
  , Text
"node"
  , Text
"hostname"
  , Text
"nonce"
  , Text
"query"
  ]