module JSONSchema.Draft4.Internal.Utils
(
alt
, andMaybe
, computeMaximumConstraints
, computeMinimumConstraints
, zipWithPadding
, listToMaybeList
, setToMaybeSet
, parseValue
, printSchema
) where
import Protolude
import qualified Data.Aeson as AE
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as BSL
import qualified Data.Scientific as DS
import qualified Data.Set as DS
import qualified Data.Text.Encoding as TE
import qualified Data.Aeson.Encode.Pretty as AEEP
import qualified JSONSchema.Draft4 as D4
alt :: Alternative f => (a -> a -> a) -> f a -> f a -> f a
alt f a b = f <$> a <*> b <|> a <|> b
emptyFold :: (Foldable t) => (t a -> a) -> t a -> Maybe a
emptyFold f tma
| null tma = Nothing
| otherwise = Just $ f tma
andMaybe :: [Maybe Bool] -> Maybe Bool
andMaybe = emptyFold and . catMaybes
computeMaximumConstraints ::
[Maybe DS.Scientific] -> [Maybe Bool] -> (Maybe DS.Scientific, Maybe Bool)
computeMaximumConstraints maxes emaxes =
maximumBy zipComparer (zip maxes emaxes)
where
zipComparer (m1, em1) (m2, em2) =
if m1 == m2
then if and $ isNothing <$> [m1, m2] then compare em1 em2 else compare (Down em1) (Down em2)
else compare m1 m2
computeMinimumConstraints ::
[Maybe DS.Scientific] -> [Maybe Bool] -> (Maybe DS.Scientific, Maybe Bool)
computeMinimumConstraints mins emins = minimumBy zipComparer (zip mins emins)
where
justComparer :: (Ord a) => Maybe a -> Maybe a -> Ordering
justComparer (Just x) (Just y) = compare x y
justComparer (Just _) Nothing = LT
justComparer Nothing (Just _) = GT
justComparer Nothing Nothing = EQ
zipComparer (m1, em1) (m2, em2)
=
if m1 == m2
then if and $ isNothing <$> [m1, m2] then compare (Down em1) (Down em2) else compare em1 em2
else justComparer m1 m2
zipWithPadding :: a -> b -> [a] -> [b] -> [(a, b)]
zipWithPadding a b (x:xs) (y:ys) = (x, y) : zipWithPadding a b xs ys
zipWithPadding a _ [] ys = zip (repeat a) ys
zipWithPadding _ b xs [] = zip xs (repeat b)
listToMaybeList :: [a] -> Maybe [a]
listToMaybeList [] = Nothing
listToMaybeList xs = Just xs
setToMaybeSet :: DS.Set a -> Maybe (DS.Set a)
setToMaybeSet s
| DS.null s = Nothing
| otherwise = Just s
parseValue :: BS.ByteString -> AE.Value
parseValue s =
fromMaybe (panic $ "Failed to parse JSON document " <> TE.decodeUtf8 s) .
AE.decode .
BSL.fromStrict $ s
printSchema :: D4.Schema -> Text
printSchema = TE.decodeUtf8 . BSL.toStrict . AEEP.encodePretty . AE.toJSON