module AWS.Secrets.Reader
(
SecretReader (..),
bind,
text,
string,
scientific,
boundedInteger,
)
where
import AWS.Secrets.Key (SecretKey, getSecretKeyText)
import Control.Applicative (Applicative, pure)
import qualified Data.Aeson as JSON
import qualified Data.Aeson.Key as JSON.Key
import Data.Function (($), (.))
import Data.Functor (Functor, fmap)
import Data.Functor.Compose (Compose (..))
import qualified Data.Aeson.KeyMap as KeyMap
import Data.Maybe (Maybe (..), maybe)
import Data.Scientific (Scientific)
import qualified Data.Scientific as Scientific
import Data.Semigroup ((<>))
import Data.Sequence (Seq)
import Data.String (String)
import Data.Text (Text)
import qualified Data.Text as Text
import Data.Validation (Validation (..), bindValidation)
import Prelude (Bounded, Integral)
newtype SecretReader a = SecretReader
{ forall a. SecretReader a -> Object -> Validation (Seq Text) a
apply :: JSON.Object -> Validation (Seq Text) a
}
deriving
((forall a b. (a -> b) -> SecretReader a -> SecretReader b)
-> (forall a b. a -> SecretReader b -> SecretReader a)
-> Functor SecretReader
forall a b. a -> SecretReader b -> SecretReader a
forall a b. (a -> b) -> SecretReader a -> SecretReader b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
$cfmap :: forall a b. (a -> b) -> SecretReader a -> SecretReader b
fmap :: forall a b. (a -> b) -> SecretReader a -> SecretReader b
$c<$ :: forall a b. a -> SecretReader b -> SecretReader a
<$ :: forall a b. a -> SecretReader b -> SecretReader a
Functor, Functor SecretReader
Functor SecretReader =>
(forall a. a -> SecretReader a)
-> (forall a b.
SecretReader (a -> b) -> SecretReader a -> SecretReader b)
-> (forall a b c.
(a -> b -> c)
-> SecretReader a -> SecretReader b -> SecretReader c)
-> (forall a b. SecretReader a -> SecretReader b -> SecretReader b)
-> (forall a b. SecretReader a -> SecretReader b -> SecretReader a)
-> Applicative SecretReader
forall a. a -> SecretReader a
forall a b. SecretReader a -> SecretReader b -> SecretReader a
forall a b. SecretReader a -> SecretReader b -> SecretReader b
forall a b.
SecretReader (a -> b) -> SecretReader a -> SecretReader b
forall a b c.
(a -> b -> c) -> SecretReader a -> SecretReader b -> SecretReader c
forall (f :: * -> *).
Functor f =>
(forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
$cpure :: forall a. a -> SecretReader a
pure :: forall a. a -> SecretReader a
$c<*> :: forall a b.
SecretReader (a -> b) -> SecretReader a -> SecretReader b
<*> :: forall a b.
SecretReader (a -> b) -> SecretReader a -> SecretReader b
$cliftA2 :: forall a b c.
(a -> b -> c) -> SecretReader a -> SecretReader b -> SecretReader c
liftA2 :: forall a b c.
(a -> b -> c) -> SecretReader a -> SecretReader b -> SecretReader c
$c*> :: forall a b. SecretReader a -> SecretReader b -> SecretReader b
*> :: forall a b. SecretReader a -> SecretReader b -> SecretReader b
$c<* :: forall a b. SecretReader a -> SecretReader b -> SecretReader a
<* :: forall a b. SecretReader a -> SecretReader b -> SecretReader a
Applicative)
via Compose ((->) JSON.Object) (Validation (Seq Text))
bind :: SecretReader a -> (a -> SecretReader b) -> SecretReader b
bind :: forall a b.
SecretReader a -> (a -> SecretReader b) -> SecretReader b
bind (SecretReader Object -> Validation (Seq Text) a
f) a -> SecretReader b
g = (Object -> Validation (Seq Text) b) -> SecretReader b
forall a. (Object -> Validation (Seq Text) a) -> SecretReader a
SecretReader \Object
o ->
Object -> Validation (Seq Text) a
f Object
o Validation (Seq Text) a
-> (a -> Validation (Seq Text) b) -> Validation (Seq Text) b
forall e a b.
Validation e a -> (a -> Validation e b) -> Validation e b
`bindValidation` (((Object -> Validation (Seq Text) b)
-> Object -> Validation (Seq Text) b
forall a b. (a -> b) -> a -> b
$ Object
o) ((Object -> Validation (Seq Text) b) -> Validation (Seq Text) b)
-> (a -> Object -> Validation (Seq Text) b)
-> a
-> Validation (Seq Text) b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SecretReader b -> Object -> Validation (Seq Text) b
forall a. SecretReader a -> Object -> Validation (Seq Text) a
apply (SecretReader b -> Object -> Validation (Seq Text) b)
-> (a -> SecretReader b) -> a -> Object -> Validation (Seq Text) b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> SecretReader b
g)
text :: SecretKey -> SecretReader Text
text :: SecretKey -> SecretReader Text
text SecretKey
k = (Object -> Validation (Seq Text) Text) -> SecretReader Text
forall a. (Object -> Validation (Seq Text) a) -> SecretReader a
SecretReader \Object
o ->
Seq Text -> Maybe Value -> Validation (Seq Text) Value
forall a. Seq Text -> Maybe a -> Validation (Seq Text) a
orFail [Text
"Missing: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> SecretKey -> Text
getSecretKeyText SecretKey
k] (Key -> Object -> Maybe Value
forall v. Key -> KeyMap v -> Maybe v
KeyMap.lookup (SecretKey -> Key
key SecretKey
k) Object
o)
Validation (Seq Text) Value
-> (Value -> Validation (Seq Text) Text)
-> Validation (Seq Text) Text
forall e a b.
Validation e a -> (a -> Validation e b) -> Validation e b
`bindValidation` \Value
txt -> Seq Text -> Maybe Text -> Validation (Seq Text) Text
forall a. Seq Text -> Maybe a -> Validation (Seq Text) a
orFail [Text
"Not a string: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> SecretKey -> Text
getSecretKeyText SecretKey
k] (Value -> Maybe Text
castJsonString Value
txt)
string :: SecretKey -> SecretReader String
string :: SecretKey -> SecretReader String
string = (Text -> String) -> SecretReader Text -> SecretReader String
forall a b. (a -> b) -> SecretReader a -> SecretReader b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Text -> String
Text.unpack (SecretReader Text -> SecretReader String)
-> (SecretKey -> SecretReader Text)
-> SecretKey
-> SecretReader String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SecretKey -> SecretReader Text
text
scientific :: SecretKey -> SecretReader Scientific
scientific :: SecretKey -> SecretReader Scientific
scientific SecretKey
k = (Object -> Validation (Seq Text) Scientific)
-> SecretReader Scientific
forall a. (Object -> Validation (Seq Text) a) -> SecretReader a
SecretReader \Object
o ->
Seq Text -> Maybe Value -> Validation (Seq Text) Value
forall a. Seq Text -> Maybe a -> Validation (Seq Text) a
orFail [Text
"Missing: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> SecretKey -> Text
getSecretKeyText SecretKey
k] (Key -> Object -> Maybe Value
forall v. Key -> KeyMap v -> Maybe v
KeyMap.lookup (SecretKey -> Key
key SecretKey
k) Object
o)
Validation (Seq Text) Value
-> (Value -> Validation (Seq Text) Scientific)
-> Validation (Seq Text) Scientific
forall e a b.
Validation e a -> (a -> Validation e b) -> Validation e b
`bindValidation` \Value
txt -> Seq Text -> Maybe Scientific -> Validation (Seq Text) Scientific
forall a. Seq Text -> Maybe a -> Validation (Seq Text) a
orFail [Text
"Not a string: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> SecretKey -> Text
getSecretKeyText SecretKey
k] (Value -> Maybe Scientific
castJsonNumber Value
txt)
boundedInteger :: (Integral i, Bounded i) => SecretKey -> SecretReader i
boundedInteger :: forall i. (Integral i, Bounded i) => SecretKey -> SecretReader i
boundedInteger SecretKey
k =
SecretKey -> SecretReader Scientific
scientific SecretKey
k SecretReader Scientific
-> (Scientific -> SecretReader i) -> SecretReader i
forall a b.
SecretReader a -> (a -> SecretReader b) -> SecretReader b
`bind` \Scientific
s -> (Object -> Validation (Seq Text) i) -> SecretReader i
forall a. (Object -> Validation (Seq Text) a) -> SecretReader a
SecretReader \Object
_ -> case Scientific -> Maybe i
forall i. (Integral i, Bounded i) => Scientific -> Maybe i
Scientific.toBoundedInteger Scientific
s of
Maybe i
Nothing -> Seq Text -> Validation (Seq Text) i
forall err a. err -> Validation err a
Failure [Text
"Not an integer or not within bounds: " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> SecretKey -> Text
getSecretKeyText SecretKey
k]
Just i
i -> i -> Validation (Seq Text) i
forall a. a -> Validation (Seq Text) a
forall (f :: * -> *) a. Applicative f => a -> f a
pure i
i
key :: SecretKey -> JSON.Key
key :: SecretKey -> Key
key = Text -> Key
JSON.Key.fromText (Text -> Key) -> (SecretKey -> Text) -> SecretKey -> Key
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SecretKey -> Text
getSecretKeyText
castJsonString :: JSON.Value -> Maybe Text
castJsonString :: Value -> Maybe Text
castJsonString = \case JSON.String Text
x -> Text -> Maybe Text
forall a. a -> Maybe a
Just Text
x; Value
_ -> Maybe Text
forall a. Maybe a
Nothing
castJsonNumber :: JSON.Value -> Maybe Scientific
castJsonNumber :: Value -> Maybe Scientific
castJsonNumber = \case JSON.Number Scientific
x -> Scientific -> Maybe Scientific
forall a. a -> Maybe a
Just Scientific
x; Value
_ -> Maybe Scientific
forall a. Maybe a
Nothing
orFail :: Seq Text -> Maybe a -> Validation (Seq Text) a
orFail :: forall a. Seq Text -> Maybe a -> Validation (Seq Text) a
orFail Seq Text
err = Validation (Seq Text) a
-> (a -> Validation (Seq Text) a)
-> Maybe a
-> Validation (Seq Text) a
forall b a. b -> (a -> b) -> Maybe a -> b
maybe (Seq Text -> Validation (Seq Text) a
forall err a. err -> Validation err a
Failure Seq Text
err) a -> Validation (Seq Text) a
forall err a. a -> Validation err a
Success