{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE ExplicitForAll #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE UndecidableSuperClasses #-}
module Data.OpenApi.Internal.AesonUtils (
AesonDefaultValue(..),
sopSwaggerGenericToJSON,
sopSwaggerGenericToEncoding,
sopSwaggerGenericToJSONWithOpts,
sopSwaggerGenericParseJSON,
HasSwaggerAesonOptions(..),
SwaggerAesonOptions,
mkSwaggerAesonOptions,
saoPrefix,
saoAdditionalPairs,
saoSubObject,
) where
import Prelude ()
import Prelude.Compat
import Control.Applicative ((<|>))
import Control.Lens (makeLenses, (^.))
import Control.Monad (unless)
import Data.Aeson (ToJSON(..), FromJSON(..), Value(..), Object, object, (.:), (.:?), (.!=), withObject, Encoding, pairs, (.=), Series)
import Data.Aeson.Types (Parser, Pair)
import Data.Char (toLower, isUpper)
import Data.Foldable (traverse_)
import Data.Text (Text)
import Generics.SOP
import qualified Data.Text as T
import qualified Data.HashMap.Strict as HM
import qualified Data.Set as Set
import qualified Data.HashMap.Strict.InsOrd as InsOrd
import qualified Data.HashSet.InsOrd as InsOrdHS
data SwaggerAesonOptions = SwaggerAesonOptions
{ SwaggerAesonOptions -> String
_saoPrefix :: String
, SwaggerAesonOptions -> [(Text, Value)]
_saoAdditionalPairs :: [(Text, Value)]
, SwaggerAesonOptions -> Maybe String
_saoSubObject :: Maybe String
}
mkSwaggerAesonOptions
:: String
-> SwaggerAesonOptions
mkSwaggerAesonOptions :: String -> SwaggerAesonOptions
mkSwaggerAesonOptions String
pfx = String -> [(Text, Value)] -> Maybe String -> SwaggerAesonOptions
SwaggerAesonOptions String
pfx [] Maybe String
forall a. Maybe a
Nothing
makeLenses ''SwaggerAesonOptions
class (Generic a, All2 AesonDefaultValue (Code a)) => HasSwaggerAesonOptions a where
swaggerAesonOptions :: Proxy a -> SwaggerAesonOptions
aesonDefaults :: Proxy a -> POP Maybe (Code a)
aesonDefaults Proxy a
_ = Proxy AesonDefaultValue
-> (forall a. AesonDefaultValue a => Maybe a) -> POP Maybe (Code a)
forall k l (h :: (k -> *) -> l -> *) (c :: k -> Constraint)
(xs :: l) (proxy :: (k -> Constraint) -> *) (f :: k -> *).
(HPure h, AllN h c xs) =>
proxy c -> (forall (a :: k). c a => f a) -> h f xs
hcpure (Proxy AesonDefaultValue
forall k (t :: k). Proxy t
Proxy :: Proxy AesonDefaultValue) forall a. AesonDefaultValue a => Maybe a
defaultValue
class AesonDefaultValue a where
defaultValue :: Maybe a
defaultValue = Maybe a
forall a. Maybe a
Nothing
instance AesonDefaultValue Text where defaultValue :: Maybe Text
defaultValue = Maybe Text
forall a. Maybe a
Nothing
instance AesonDefaultValue (Maybe a) where defaultValue :: Maybe (Maybe a)
defaultValue = Maybe a -> Maybe (Maybe a)
forall a. a -> Maybe a
Just Maybe a
forall a. Maybe a
Nothing
instance AesonDefaultValue [a] where defaultValue :: Maybe [a]
defaultValue = [a] -> Maybe [a]
forall a. a -> Maybe a
Just []
instance AesonDefaultValue (Set.Set a) where defaultValue :: Maybe (Set a)
defaultValue = Set a -> Maybe (Set a)
forall a. a -> Maybe a
Just Set a
forall a. Set a
Set.empty
instance AesonDefaultValue (InsOrdHS.InsOrdHashSet k) where defaultValue :: Maybe (InsOrdHashSet k)
defaultValue = InsOrdHashSet k -> Maybe (InsOrdHashSet k)
forall a. a -> Maybe a
Just InsOrdHashSet k
forall k. InsOrdHashSet k
InsOrdHS.empty
instance AesonDefaultValue (InsOrd.InsOrdHashMap k v) where defaultValue :: Maybe (InsOrdHashMap k v)
defaultValue = InsOrdHashMap k v -> Maybe (InsOrdHashMap k v)
forall a. a -> Maybe a
Just InsOrdHashMap k v
forall k v. InsOrdHashMap k v
InsOrd.empty
sopSwaggerGenericToJSON
:: forall a xs.
( HasDatatypeInfo a
, HasSwaggerAesonOptions a
, All2 ToJSON (Code a)
, All2 Eq (Code a)
, Code a ~ '[xs]
)
=> a
-> Value
sopSwaggerGenericToJSON :: a -> Value
sopSwaggerGenericToJSON a
x =
let ps :: [(Text, Value)]
ps = SwaggerAesonOptions
-> SOP I '[xs]
-> DatatypeInfo '[xs]
-> POP Maybe '[xs]
-> [(Text, Value)]
forall (xs :: [*]).
(All2 ToJSON '[xs], All2 Eq '[xs]) =>
SwaggerAesonOptions
-> SOP I '[xs]
-> DatatypeInfo '[xs]
-> POP Maybe '[xs]
-> [(Text, Value)]
sopSwaggerGenericToJSON' SwaggerAesonOptions
opts (a -> Rep a
forall a. Generic a => a -> Rep a
from a
x) (Proxy a -> DatatypeInfo (Code a)
forall a (proxy :: * -> *).
HasDatatypeInfo a =>
proxy a -> DatatypeInfo (Code a)
datatypeInfo Proxy a
proxy) (Proxy a -> POP Maybe (Code a)
forall a. HasSwaggerAesonOptions a => Proxy a -> POP Maybe (Code a)
aesonDefaults Proxy a
proxy)
in [(Text, Value)] -> Value
object (SwaggerAesonOptions
opts SwaggerAesonOptions
-> Getting [(Text, Value)] SwaggerAesonOptions [(Text, Value)]
-> [(Text, Value)]
forall s a. s -> Getting a s a -> a
^. Getting [(Text, Value)] SwaggerAesonOptions [(Text, Value)]
Lens' SwaggerAesonOptions [(Text, Value)]
saoAdditionalPairs [(Text, Value)] -> [(Text, Value)] -> [(Text, Value)]
forall a. [a] -> [a] -> [a]
++ [(Text, Value)]
ps)
where
proxy :: Proxy a
proxy = Proxy a
forall k (t :: k). Proxy t
Proxy :: Proxy a
opts :: SwaggerAesonOptions
opts = Proxy a -> SwaggerAesonOptions
forall a.
HasSwaggerAesonOptions a =>
Proxy a -> SwaggerAesonOptions
swaggerAesonOptions Proxy a
proxy
sopSwaggerGenericToJSONWithOpts
:: forall a xs.
( Generic a
, All2 AesonDefaultValue (Code a)
, HasDatatypeInfo a
, All2 ToJSON (Code a)
, All2 Eq (Code a)
, Code a ~ '[xs]
)
=> SwaggerAesonOptions
-> a
-> Value
sopSwaggerGenericToJSONWithOpts :: SwaggerAesonOptions -> a -> Value
sopSwaggerGenericToJSONWithOpts SwaggerAesonOptions
opts a
x =
let ps :: [(Text, Value)]
ps = SwaggerAesonOptions
-> SOP I '[xs]
-> DatatypeInfo '[xs]
-> POP Maybe '[xs]
-> [(Text, Value)]
forall (xs :: [*]).
(All2 ToJSON '[xs], All2 Eq '[xs]) =>
SwaggerAesonOptions
-> SOP I '[xs]
-> DatatypeInfo '[xs]
-> POP Maybe '[xs]
-> [(Text, Value)]
sopSwaggerGenericToJSON' SwaggerAesonOptions
opts (a -> Rep a
forall a. Generic a => a -> Rep a
from a
x) (Proxy a -> DatatypeInfo (Code a)
forall a (proxy :: * -> *).
HasDatatypeInfo a =>
proxy a -> DatatypeInfo (Code a)
datatypeInfo Proxy a
proxy) POP Maybe '[xs]
defs
in [(Text, Value)] -> Value
object (SwaggerAesonOptions
opts SwaggerAesonOptions
-> Getting [(Text, Value)] SwaggerAesonOptions [(Text, Value)]
-> [(Text, Value)]
forall s a. s -> Getting a s a -> a
^. Getting [(Text, Value)] SwaggerAesonOptions [(Text, Value)]
Lens' SwaggerAesonOptions [(Text, Value)]
saoAdditionalPairs [(Text, Value)] -> [(Text, Value)] -> [(Text, Value)]
forall a. [a] -> [a] -> [a]
++ [(Text, Value)]
ps)
where
proxy :: Proxy a
proxy = Proxy a
forall k (t :: k). Proxy t
Proxy :: Proxy a
defs :: POP Maybe '[xs]
defs = Proxy AesonDefaultValue
-> (forall a. AesonDefaultValue a => Maybe a) -> POP Maybe '[xs]
forall k l (h :: (k -> *) -> l -> *) (c :: k -> Constraint)
(xs :: l) (proxy :: (k -> Constraint) -> *) (f :: k -> *).
(HPure h, AllN h c xs) =>
proxy c -> (forall (a :: k). c a => f a) -> h f xs
hcpure (Proxy AesonDefaultValue
forall k (t :: k). Proxy t
Proxy :: Proxy AesonDefaultValue) forall a. AesonDefaultValue a => Maybe a
defaultValue
sopSwaggerGenericToJSON'
:: (All2 ToJSON '[xs], All2 Eq '[xs])
=> SwaggerAesonOptions
-> SOP I '[xs]
-> DatatypeInfo '[xs]
-> POP Maybe '[xs]
-> [Pair]
sopSwaggerGenericToJSON' :: SwaggerAesonOptions
-> SOP I '[xs]
-> DatatypeInfo '[xs]
-> POP Maybe '[xs]
-> [(Text, Value)]
sopSwaggerGenericToJSON' SwaggerAesonOptions
opts (SOP (Z NP I x
fields)) (ADT String
_ String
_ (Record String
_ NP FieldInfo x
fieldsInfo :* NP ConstructorInfo xs
Nil) POP StrictnessInfo '[xs]
_) (POP (NP Maybe x
defs :* NP (NP Maybe) xs
Nil)) =
SwaggerAesonOptions
-> NP I x -> NP FieldInfo x -> NP Maybe x -> [(Text, Value)]
forall (xs :: [*]).
(All ToJSON xs, All Eq xs) =>
SwaggerAesonOptions
-> NP I xs -> NP FieldInfo xs -> NP Maybe xs -> [(Text, Value)]
sopSwaggerGenericToJSON'' SwaggerAesonOptions
opts NP I x
fields NP FieldInfo x
NP FieldInfo x
fieldsInfo NP Maybe x
NP Maybe x
defs
sopSwaggerGenericToJSON' SwaggerAesonOptions
_ SOP I '[xs]
_ DatatypeInfo '[xs]
_ POP Maybe '[xs]
_ = String -> [(Text, Value)]
forall a. HasCallStack => String -> a
error String
"sopSwaggerGenericToJSON: unsupported type"
sopSwaggerGenericToJSON''
:: (All ToJSON xs, All Eq xs)
=> SwaggerAesonOptions
-> NP I xs
-> NP FieldInfo xs
-> NP Maybe xs
-> [Pair]
sopSwaggerGenericToJSON'' :: SwaggerAesonOptions
-> NP I xs -> NP FieldInfo xs -> NP Maybe xs -> [(Text, Value)]
sopSwaggerGenericToJSON'' (SwaggerAesonOptions String
prefix [(Text, Value)]
_ Maybe String
sub) = NP I xs -> NP FieldInfo xs -> NP Maybe xs -> [(Text, Value)]
forall (ys :: [*]).
(All ToJSON ys, All Eq ys) =>
NP I ys -> NP FieldInfo ys -> NP Maybe ys -> [(Text, Value)]
go
where
go :: (All ToJSON ys, All Eq ys) => NP I ys -> NP FieldInfo ys -> NP Maybe ys -> [Pair]
go :: NP I ys -> NP FieldInfo ys -> NP Maybe ys -> [(Text, Value)]
go NP I ys
Nil NP FieldInfo ys
Nil NP Maybe ys
Nil = []
go (I x
x :* NP I xs
xs) (FieldInfo String
name :* NP FieldInfo xs
names) (Maybe x
def :* NP Maybe xs
defs)
| String -> Maybe String
forall a. a -> Maybe a
Just String
name' Maybe String -> Maybe String -> Bool
forall a. Eq a => a -> a -> Bool
== Maybe String
sub = case Value
json of
Object Object
m -> Object -> [(Text, Value)]
forall k v. HashMap k v -> [(k, v)]
HM.toList Object
m [(Text, Value)] -> [(Text, Value)] -> [(Text, Value)]
forall a. [a] -> [a] -> [a]
++ [(Text, Value)]
rest
Value
Null -> [(Text, Value)]
rest
Value
_ -> String -> [(Text, Value)]
forall a. HasCallStack => String -> a
error (String -> [(Text, Value)]) -> String -> [(Text, Value)]
forall a b. (a -> b) -> a -> b
$ String
"sopSwaggerGenericToJSON: subjson is not an object: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Value -> String
forall a. Show a => a -> String
show Value
json
| x -> Maybe x
forall a. a -> Maybe a
Just x
x Maybe x -> Maybe x -> Bool
forall a. Eq a => a -> a -> Bool
== Maybe x
Maybe x
def =
[(Text, Value)]
rest
| Bool
otherwise =
(String -> Text
T.pack String
name', Value
json) (Text, Value) -> [(Text, Value)] -> [(Text, Value)]
forall a. a -> [a] -> [a]
: [(Text, Value)]
rest
where
json :: Value
json = x -> Value
forall a. ToJSON a => a -> Value
toJSON x
x
name' :: String
name' = String -> String
fieldNameModifier String
name
rest :: [(Text, Value)]
rest = NP I xs -> NP FieldInfo xs -> NP Maybe xs -> [(Text, Value)]
forall (ys :: [*]).
(All ToJSON ys, All Eq ys) =>
NP I ys -> NP FieldInfo ys -> NP Maybe ys -> [(Text, Value)]
go NP I xs
xs NP FieldInfo xs
NP FieldInfo xs
names NP Maybe xs
NP Maybe xs
defs
fieldNameModifier :: String -> String
fieldNameModifier = String -> String
modifier (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> String -> String
forall a. Int -> [a] -> [a]
drop Int
1
modifier :: String -> String
modifier = String -> String
lowerFirstUppers (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> String -> String
forall a. Int -> [a] -> [a]
drop (String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
prefix)
lowerFirstUppers :: String -> String
lowerFirstUppers String
s = (Char -> Char) -> String -> String
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower String
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
y
where (String
x, String
y) = (Char -> Bool) -> String -> (String, String)
forall a. (a -> Bool) -> [a] -> ([a], [a])
span Char -> Bool
isUpper String
s
sopSwaggerGenericParseJSON
:: forall a xs.
( HasDatatypeInfo a
, HasSwaggerAesonOptions a
, All2 FromJSON (Code a)
, All2 Eq (Code a)
, Code a ~ '[xs]
)
=> Value
-> Parser a
sopSwaggerGenericParseJSON :: Value -> Parser a
sopSwaggerGenericParseJSON = String -> (Object -> Parser a) -> Value -> Parser a
forall a. String -> (Object -> Parser a) -> Value -> Parser a
withObject String
"Swagger Record Object" ((Object -> Parser a) -> Value -> Parser a)
-> (Object -> Parser a) -> Value -> Parser a
forall a b. (a -> b) -> a -> b
$ \Object
obj ->
let ps :: Parser (SOP I '[xs])
ps = SwaggerAesonOptions
-> Object
-> DatatypeInfo '[xs]
-> POP Maybe '[xs]
-> Parser (SOP I '[xs])
forall (xs :: [*]).
(All2 FromJSON '[xs], All2 Eq '[xs]) =>
SwaggerAesonOptions
-> Object
-> DatatypeInfo '[xs]
-> POP Maybe '[xs]
-> Parser (SOP I '[xs])
sopSwaggerGenericParseJSON' SwaggerAesonOptions
opts Object
obj (Proxy a -> DatatypeInfo (Code a)
forall a (proxy :: * -> *).
HasDatatypeInfo a =>
proxy a -> DatatypeInfo (Code a)
datatypeInfo Proxy a
proxy) (Proxy a -> POP Maybe (Code a)
forall a. HasSwaggerAesonOptions a => Proxy a -> POP Maybe (Code a)
aesonDefaults Proxy a
proxy)
in do
((Text, Value) -> Parser ()) -> [(Text, Value)] -> Parser ()
forall (t :: * -> *) (f :: * -> *) a b.
(Foldable t, Applicative f) =>
(a -> f b) -> t a -> f ()
traverse_ (Object -> (Text, Value) -> Parser ()
parseAdditionalField Object
obj) (SwaggerAesonOptions
opts SwaggerAesonOptions
-> Getting [(Text, Value)] SwaggerAesonOptions [(Text, Value)]
-> [(Text, Value)]
forall s a. s -> Getting a s a -> a
^. Getting [(Text, Value)] SwaggerAesonOptions [(Text, Value)]
Lens' SwaggerAesonOptions [(Text, Value)]
saoAdditionalPairs)
SOP I '[xs] -> a
forall a. Generic a => Rep a -> a
to (SOP I '[xs] -> a) -> Parser (SOP I '[xs]) -> Parser a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Parser (SOP I '[xs])
ps
where
proxy :: Proxy a
proxy = Proxy a
forall k (t :: k). Proxy t
Proxy :: Proxy a
opts :: SwaggerAesonOptions
opts = Proxy a -> SwaggerAesonOptions
forall a.
HasSwaggerAesonOptions a =>
Proxy a -> SwaggerAesonOptions
swaggerAesonOptions Proxy a
proxy
parseAdditionalField :: Object -> (Text, Value) -> Parser ()
parseAdditionalField :: Object -> (Text, Value) -> Parser ()
parseAdditionalField Object
obj (Text
k, Value
v) = do
Value
v' <- Object
obj Object -> Text -> Parser Value
forall a. FromJSON a => Object -> Text -> Parser a
.: Text
k
Bool -> Parser () -> Parser ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (Value
v Value -> Value -> Bool
forall a. Eq a => a -> a -> Bool
== Value
v') (Parser () -> Parser ()) -> Parser () -> Parser ()
forall a b. (a -> b) -> a -> b
$ String -> Parser ()
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser ()) -> String -> Parser ()
forall a b. (a -> b) -> a -> b
$
String
"Additonal field don't match for key " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Text -> String
T.unpack Text
k
String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
": " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Value -> String
forall a. Show a => a -> String
show Value
v
String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
" /= " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Value -> String
forall a. Show a => a -> String
show Value
v'
sopSwaggerGenericParseJSON'
:: (All2 FromJSON '[xs], All2 Eq '[xs])
=> SwaggerAesonOptions
-> Object
-> DatatypeInfo '[xs]
-> POP Maybe '[xs]
-> Parser (SOP I '[xs])
sopSwaggerGenericParseJSON' :: SwaggerAesonOptions
-> Object
-> DatatypeInfo '[xs]
-> POP Maybe '[xs]
-> Parser (SOP I '[xs])
sopSwaggerGenericParseJSON' SwaggerAesonOptions
opts Object
obj (ADT String
_ String
_ (Record String
_ NP FieldInfo x
fieldsInfo :* NP ConstructorInfo xs
Nil) POP StrictnessInfo '[xs]
_) (POP (NP Maybe x
defs :* NP (NP Maybe) xs
Nil)) =
NS (NP I) '[x] -> SOP I '[x]
forall k (f :: k -> *) (xss :: [[k]]). NS (NP f) xss -> SOP f xss
SOP (NS (NP I) '[x] -> SOP I '[x])
-> (NP I x -> NS (NP I) '[x]) -> NP I x -> SOP I '[x]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. NP I x -> NS (NP I) '[x]
forall k (a :: k -> *) (x :: k) (xs :: [k]). a x -> NS a (x : xs)
Z (NP I x -> SOP I '[x]) -> Parser (NP I x) -> Parser (SOP I '[x])
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> SwaggerAesonOptions
-> Object -> NP FieldInfo x -> NP Maybe x -> Parser (NP I x)
forall (xs :: [*]).
(All FromJSON xs, All Eq xs) =>
SwaggerAesonOptions
-> Object -> NP FieldInfo xs -> NP Maybe xs -> Parser (NP I xs)
sopSwaggerGenericParseJSON'' SwaggerAesonOptions
opts Object
obj NP FieldInfo x
fieldsInfo NP Maybe x
NP Maybe x
defs
sopSwaggerGenericParseJSON' SwaggerAesonOptions
_ Object
_ DatatypeInfo '[xs]
_ POP Maybe '[xs]
_ = String -> Parser (SOP I '[xs])
forall a. HasCallStack => String -> a
error String
"sopSwaggerGenericParseJSON: unsupported type"
sopSwaggerGenericParseJSON''
:: (All FromJSON xs, All Eq xs)
=> SwaggerAesonOptions
-> Object
-> NP FieldInfo xs
-> NP Maybe xs
-> Parser (NP I xs)
sopSwaggerGenericParseJSON'' :: SwaggerAesonOptions
-> Object -> NP FieldInfo xs -> NP Maybe xs -> Parser (NP I xs)
sopSwaggerGenericParseJSON'' (SwaggerAesonOptions String
prefix [(Text, Value)]
_ Maybe String
sub) Object
obj = NP FieldInfo xs -> NP Maybe xs -> Parser (NP I xs)
forall (ys :: [*]).
(All FromJSON ys, All Eq ys) =>
NP FieldInfo ys -> NP Maybe ys -> Parser (NP I ys)
go
where
go :: (All FromJSON ys, All Eq ys) => NP FieldInfo ys -> NP Maybe ys -> Parser (NP I ys)
go :: NP FieldInfo ys -> NP Maybe ys -> Parser (NP I ys)
go NP FieldInfo ys
Nil NP Maybe ys
Nil = NP I '[] -> Parser (NP I '[])
forall (f :: * -> *) a. Applicative f => a -> f a
pure NP I '[]
forall k (a :: k -> *). NP a '[]
Nil
go (FieldInfo String
name :* NP FieldInfo xs
names) (Maybe x
def :* NP Maybe xs
defs)
| String -> Maybe String
forall a. a -> Maybe a
Just String
name' Maybe String -> Maybe String -> Bool
forall a. Eq a => a -> a -> Bool
== Maybe String
sub =
x -> NP I xs -> NP I (x : xs)
forall x (xs :: [*]). x -> NP I xs -> NP I (x : xs)
cons (x -> NP I xs -> NP I (x : xs))
-> Parser x -> Parser (NP I xs -> NP I (x : xs))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> (Parser x -> Parser x
withDef (Parser x -> Parser x) -> Parser x -> Parser x
forall a b. (a -> b) -> a -> b
$ Value -> Parser x
forall a. FromJSON a => Value -> Parser a
parseJSON (Value -> Parser x) -> Value -> Parser x
forall a b. (a -> b) -> a -> b
$ Object -> Value
Object Object
obj) Parser (NP I xs -> NP I (x : xs))
-> Parser (NP I xs) -> Parser (NP I (x : xs))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser (NP I xs)
rest
| Bool
otherwise = case Maybe x
def of
Just x
def' -> x -> NP I xs -> NP I (x : xs)
forall x (xs :: [*]). x -> NP I xs -> NP I (x : xs)
cons (x -> NP I xs -> NP I (x : xs))
-> Parser x -> Parser (NP I xs -> NP I (x : xs))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
obj Object -> Text -> Parser (Maybe x)
forall a. FromJSON a => Object -> Text -> Parser (Maybe a)
.:? String -> Text
T.pack String
name' Parser (Maybe x) -> x -> Parser x
forall a. Parser (Maybe a) -> a -> Parser a
.!= x
def' Parser (NP I xs -> NP I (x : xs))
-> Parser (NP I xs) -> Parser (NP I (x : xs))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser (NP I xs)
rest
Maybe x
Nothing -> x -> NP I xs -> NP I (x : xs)
forall x (xs :: [*]). x -> NP I xs -> NP I (x : xs)
cons (x -> NP I xs -> NP I (x : xs))
-> Parser x -> Parser (NP I xs -> NP I (x : xs))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Object
obj Object -> Text -> Parser x
forall a. FromJSON a => Object -> Text -> Parser a
.: String -> Text
T.pack String
name' Parser (NP I xs -> NP I (x : xs))
-> Parser (NP I xs) -> Parser (NP I (x : xs))
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> Parser (NP I xs)
rest
where
cons :: x -> NP I xs -> NP I (x : xs)
cons x
h NP I xs
t = x -> I x
forall a. a -> I a
I x
h I x -> NP I xs -> NP I (x : xs)
forall k (a :: k -> *) (x :: k) (xs :: [k]).
a x -> NP a xs -> NP a (x : xs)
:* NP I xs
t
name' :: String
name' = String -> String
fieldNameModifier String
name
rest :: Parser (NP I xs)
rest = NP FieldInfo xs -> NP Maybe xs -> Parser (NP I xs)
forall (ys :: [*]).
(All FromJSON ys, All Eq ys) =>
NP FieldInfo ys -> NP Maybe ys -> Parser (NP I ys)
go NP FieldInfo xs
names NP Maybe xs
NP Maybe xs
defs
withDef :: Parser x -> Parser x
withDef = case Maybe x
def of
Just x
def' -> (Parser x -> Parser x -> Parser x
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> x -> Parser x
forall (f :: * -> *) a. Applicative f => a -> f a
pure x
def')
Maybe x
Nothing -> Parser x -> Parser x
forall a. a -> a
id
fieldNameModifier :: String -> String
fieldNameModifier = String -> String
modifier (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> String -> String
forall a. Int -> [a] -> [a]
drop Int
1
modifier :: String -> String
modifier = String -> String
lowerFirstUppers (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> String -> String
forall a. Int -> [a] -> [a]
drop (String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
prefix)
lowerFirstUppers :: String -> String
lowerFirstUppers String
s = (Char -> Char) -> String -> String
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower String
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
y
where (String
x, String
y) = (Char -> Bool) -> String -> (String, String)
forall a. (a -> Bool) -> [a] -> ([a], [a])
span Char -> Bool
isUpper String
s
sopSwaggerGenericToEncoding
:: forall a xs.
( HasDatatypeInfo a
, HasSwaggerAesonOptions a
, All2 ToJSON (Code a)
, All2 Eq (Code a)
, Code a ~ '[xs]
)
=> a
-> Encoding
sopSwaggerGenericToEncoding :: a -> Encoding
sopSwaggerGenericToEncoding a
x =
let ps :: Series
ps = SwaggerAesonOptions
-> SOP I '[xs] -> DatatypeInfo '[xs] -> POP Maybe '[xs] -> Series
forall (xs :: [*]).
(All2 ToJSON '[xs], All2 Eq '[xs]) =>
SwaggerAesonOptions
-> SOP I '[xs] -> DatatypeInfo '[xs] -> POP Maybe '[xs] -> Series
sopSwaggerGenericToEncoding' SwaggerAesonOptions
opts (a -> Rep a
forall a. Generic a => a -> Rep a
from a
x) (Proxy a -> DatatypeInfo (Code a)
forall a (proxy :: * -> *).
HasDatatypeInfo a =>
proxy a -> DatatypeInfo (Code a)
datatypeInfo Proxy a
proxy) (Proxy a -> POP Maybe (Code a)
forall a. HasSwaggerAesonOptions a => Proxy a -> POP Maybe (Code a)
aesonDefaults Proxy a
proxy)
in Series -> Encoding
pairs ([(Text, Value)] -> Series
pairsToSeries (SwaggerAesonOptions
opts SwaggerAesonOptions
-> Getting [(Text, Value)] SwaggerAesonOptions [(Text, Value)]
-> [(Text, Value)]
forall s a. s -> Getting a s a -> a
^. Getting [(Text, Value)] SwaggerAesonOptions [(Text, Value)]
Lens' SwaggerAesonOptions [(Text, Value)]
saoAdditionalPairs) Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<> Series
ps)
where
proxy :: Proxy a
proxy = Proxy a
forall k (t :: k). Proxy t
Proxy :: Proxy a
opts :: SwaggerAesonOptions
opts = Proxy a -> SwaggerAesonOptions
forall a.
HasSwaggerAesonOptions a =>
Proxy a -> SwaggerAesonOptions
swaggerAesonOptions Proxy a
proxy
pairsToSeries :: [Pair] -> Series
pairsToSeries :: [(Text, Value)] -> Series
pairsToSeries = ((Text, Value) -> Series) -> [(Text, Value)] -> Series
forall (t :: * -> *) m a.
(Foldable t, Monoid m) =>
(a -> m) -> t a -> m
foldMap (\(Text
k, Value
v) -> (Text
k Text -> Value -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= Value
v))
sopSwaggerGenericToEncoding'
:: (All2 ToJSON '[xs], All2 Eq '[xs])
=> SwaggerAesonOptions
-> SOP I '[xs]
-> DatatypeInfo '[xs]
-> POP Maybe '[xs]
-> Series
sopSwaggerGenericToEncoding' :: SwaggerAesonOptions
-> SOP I '[xs] -> DatatypeInfo '[xs] -> POP Maybe '[xs] -> Series
sopSwaggerGenericToEncoding' SwaggerAesonOptions
opts (SOP (Z NP I x
fields)) (ADT String
_ String
_ (Record String
_ NP FieldInfo x
fieldsInfo :* NP ConstructorInfo xs
Nil) POP StrictnessInfo '[xs]
_) (POP (NP Maybe x
defs :* NP (NP Maybe) xs
Nil)) =
SwaggerAesonOptions
-> NP I x -> NP FieldInfo x -> NP Maybe x -> Series
forall (xs :: [*]).
(All ToJSON xs, All Eq xs) =>
SwaggerAesonOptions
-> NP I xs -> NP FieldInfo xs -> NP Maybe xs -> Series
sopSwaggerGenericToEncoding'' SwaggerAesonOptions
opts NP I x
fields NP FieldInfo x
NP FieldInfo x
fieldsInfo NP Maybe x
NP Maybe x
defs
sopSwaggerGenericToEncoding' SwaggerAesonOptions
_ SOP I '[xs]
_ DatatypeInfo '[xs]
_ POP Maybe '[xs]
_ = String -> Series
forall a. HasCallStack => String -> a
error String
"sopSwaggerGenericToEncoding: unsupported type"
sopSwaggerGenericToEncoding''
:: (All ToJSON xs, All Eq xs)
=> SwaggerAesonOptions
-> NP I xs
-> NP FieldInfo xs
-> NP Maybe xs
-> Series
sopSwaggerGenericToEncoding'' :: SwaggerAesonOptions
-> NP I xs -> NP FieldInfo xs -> NP Maybe xs -> Series
sopSwaggerGenericToEncoding'' (SwaggerAesonOptions String
prefix [(Text, Value)]
_ Maybe String
sub) = NP I xs -> NP FieldInfo xs -> NP Maybe xs -> Series
forall (ys :: [*]).
(All ToJSON ys, All Eq ys) =>
NP I ys -> NP FieldInfo ys -> NP Maybe ys -> Series
go
where
go :: (All ToJSON ys, All Eq ys) => NP I ys -> NP FieldInfo ys -> NP Maybe ys -> Series
go :: NP I ys -> NP FieldInfo ys -> NP Maybe ys -> Series
go NP I ys
Nil NP FieldInfo ys
Nil NP Maybe ys
Nil = Series
forall a. Monoid a => a
mempty
go (I x
x :* NP I xs
xs) (FieldInfo String
name :* NP FieldInfo xs
names) (Maybe x
def :* NP Maybe xs
defs)
| String -> Maybe String
forall a. a -> Maybe a
Just String
name' Maybe String -> Maybe String -> Bool
forall a. Eq a => a -> a -> Bool
== Maybe String
sub = case x -> Value
forall a. ToJSON a => a -> Value
toJSON x
x of
Object Object
m -> [(Text, Value)] -> Series
pairsToSeries (Object -> [(Text, Value)]
forall k v. HashMap k v -> [(k, v)]
HM.toList Object
m) Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<> Series
rest
Value
Null -> Series
rest
Value
_ -> String -> Series
forall a. HasCallStack => String -> a
error (String -> Series) -> String -> Series
forall a b. (a -> b) -> a -> b
$ String
"sopSwaggerGenericToJSON: subjson is not an object: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Value -> String
forall a. Show a => a -> String
show (x -> Value
forall a. ToJSON a => a -> Value
toJSON x
x)
| x -> Maybe x
forall a. a -> Maybe a
Just x
x Maybe x -> Maybe x -> Bool
forall a. Eq a => a -> a -> Bool
== Maybe x
Maybe x
def =
Series
rest
| Bool
otherwise =
(String -> Text
T.pack String
name' Text -> x -> Series
forall kv v. (KeyValue kv, ToJSON v) => Text -> v -> kv
.= x
x) Series -> Series -> Series
forall a. Semigroup a => a -> a -> a
<> Series
rest
where
name' :: String
name' = String -> String
fieldNameModifier String
name
rest :: Series
rest = NP I xs -> NP FieldInfo xs -> NP Maybe xs -> Series
forall (ys :: [*]).
(All ToJSON ys, All Eq ys) =>
NP I ys -> NP FieldInfo ys -> NP Maybe ys -> Series
go NP I xs
xs NP FieldInfo xs
NP FieldInfo xs
names NP Maybe xs
NP Maybe xs
defs
fieldNameModifier :: String -> String
fieldNameModifier = String -> String
modifier (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> String -> String
forall a. Int -> [a] -> [a]
drop Int
1
modifier :: String -> String
modifier = String -> String
lowerFirstUppers (String -> String) -> (String -> String) -> String -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> String -> String
forall a. Int -> [a] -> [a]
drop (String -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length String
prefix)
lowerFirstUppers :: String -> String
lowerFirstUppers String
s = (Char -> Char) -> String -> String
forall a b. (a -> b) -> [a] -> [b]
map Char -> Char
toLower String
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
y
where (String
x, String
y) = (Char -> Bool) -> String -> (String, String)
forall a. (a -> Bool) -> [a] -> ([a], [a])
span Char -> Bool
isUpper String
s