compaREST-0.1.0.0: src/Data/OpenApi/Compare/Validate/Schema/Traced.hs
{-# OPTIONS_GHC -Wno-orphans #-}
module Data.OpenApi.Compare.Validate.Schema.Traced
( Step (..),
tracedAllOf,
tracedAnyOf,
tracedOneOf,
tracedItems,
tracedAdditionalProperties,
tracedDiscriminator,
tracedProperties,
tracedConjunct,
PartitionLocation (..),
PartitionChoice (..),
Partition,
)
where
import qualified Data.Aeson as A
import Data.Functor
import qualified Data.HashMap.Strict.InsOrd as IOHM
import qualified Data.List.NonEmpty as NE
import Data.OpenApi
import Data.OpenApi.Compare.Subtree
import qualified Data.Set as S
import Data.Text (Text)
data PartitionChoice
= CByEnumValue (S.Set A.Value)
| CByProperties (S.Set Text) (S.Set Text) -- included, excluded
deriving stock (Eq, Ord, Show)
data PartitionLocation
= PHere
| PInProperty Text PartitionLocation
deriving stock (Eq, Ord, Show)
type Partition = (PartitionLocation, PartitionChoice)
instance Steppable Schema (Referenced Schema) where
data Step Schema (Referenced Schema)
= AllOfStep Int
| OneOfStep Int
| AnyOfStep Int
| ItemsObjectStep
| ItemsArrayStep Int
| AdditionalPropertiesStep
| NotStep
| ImplicitTopSchema
deriving stock (Eq, Ord, Show)
instance Steppable (Referenced Schema) (Referenced Schema) where
data Step (Referenced Schema) (Referenced Schema)
= -- | Invariant (for better memoization only): the "tail" of the trace is
-- the "least" of the traces of the conjuncted schemata
ConjunctedWith (NE.NonEmpty (Trace (Referenced Schema)))
| Partitioned Partition
deriving stock (Eq, Ord, Show)
instance Steppable Schema (Definitions (Referenced Schema)) where
data Step Schema (Definitions (Referenced Schema)) = PropertiesStep
deriving stock (Eq, Ord, Show)
instance Steppable Schema Discriminator where
data Step Schema Discriminator = DiscriminatorStep
deriving stock (Eq, Ord, Show)
instance Steppable Discriminator (Definitions (Referenced Schema)) where
data Step Discriminator (Definitions (Referenced Schema)) = DiscriminatorMapping
deriving stock (Eq, Ord, Show)
tracedAllOf :: Traced Schema -> Maybe [Traced (Referenced Schema)]
tracedAllOf sch =
_schemaAllOf (extract sch) <&> \xs ->
[traced (ask sch >>> step (AllOfStep i)) x | (i, x) <- zip [0 ..] xs]
tracedAnyOf :: Traced Schema -> Maybe [Traced (Referenced Schema)]
tracedAnyOf sch =
_schemaAnyOf (extract sch) <&> \xs ->
[traced (ask sch >>> step (AnyOfStep i)) x | (i, x) <- zip [0 ..] xs]
tracedOneOf :: Traced Schema -> Maybe [Traced (Referenced Schema)]
tracedOneOf sch =
_schemaOneOf (extract sch) <&> \xs ->
[traced (ask sch >>> step (OneOfStep i)) x | (i, x) <- zip [0 ..] xs]
tracedItems :: Traced Schema -> Maybe (Either (Traced (Referenced Schema)) [Traced (Referenced Schema)])
tracedItems sch =
_schemaItems (extract sch) <&> \case
OpenApiItemsObject x -> Left $ traced (ask sch >>> step ItemsObjectStep) x
OpenApiItemsArray xs ->
Right
[traced (ask sch >>> step (ItemsArrayStep i)) x | (i, x) <- zip [0 ..] xs]
tracedAdditionalProperties :: Traced Schema -> Maybe (Either Bool (Traced (Referenced Schema)))
tracedAdditionalProperties sch =
_schemaAdditionalProperties (extract sch) <&> \case
AdditionalPropertiesAllowed b -> Left b
AdditionalPropertiesSchema x -> Right $ traced (ask sch >>> step AdditionalPropertiesStep) x
tracedDiscriminator :: Traced Schema -> Maybe (Traced Discriminator)
tracedDiscriminator = sequence . stepTraced DiscriminatorStep . fmap _schemaDiscriminator
tracedProperties :: Traced Schema -> IOHM.InsOrdHashMap Text (Traced (Referenced Schema))
tracedProperties sch =
IOHM.mapWithKey
(\k -> traced (ask sch >>> step PropertiesStep >>> step (InsOrdHashMapKeyStep k)))
(_schemaProperties $ extract sch)
tracedConjunct :: NE.NonEmpty (Traced (Referenced Schema)) -> Traced (Referenced Schema)
tracedConjunct refSchemas = case NE.sortWith ask refSchemas of
(rs NE.:| []) -> rs
(rs1 NE.:| rs2 : rss) ->
traced (ask rs1 >>> step (ConjunctedWith $ ask <$> rs2 NE.:| rss)) $
Inline mempty {_schemaAllOf = Just $ extract <$> rs1 : rs2 : rss}