module Data.JSON.Schema.Combinators
( SchemaC
, (<|>)
, (<+>)
, merge
, field
, value
, number
, array
, addField
, addFields
, empty
, enum
, unbounded
, unboundedLength
, nullable
) where
import Data.JSON.Schema.Types
import Data.Text (Text)
import qualified Data.Aeson as Aeson
type SchemaC = Schema -> Schema
infixl 3 <|>
(<|>) :: Schema -> Schema -> Schema
(Choice s1) <|> (Choice s2) = Choice $ s1 ++ s2
(Choice s1) <|> v = Choice $ s1 ++ [v]
v <|> (Choice s2) = Choice $ v : s2
v1 <|> v2 = Choice $ [v1, v2]
infixl 4 <+>
(<+>) :: Schema -> Schema -> Schema
(Tuple t1) <+> (Tuple t2) = Tuple $ t1 ++ t2
(Tuple t1) <+> v = Tuple $ t1 ++ [v]
v <+> (Tuple t2) = Tuple $ v : t2
v1 <+> v2 = Tuple $ [v1, v2]
merge :: Schema -> Schema -> Schema
merge (Object f1) (Object f2) = Object $ f1 ++ f2
merge v1 v2 = v1 <+> v2
field :: Text -> Bool -> Schema -> Schema
field k r v = Object [Field k r v]
value :: Schema
value = Value unboundedLength
number :: Schema
number = Number unbounded
array :: Schema -> Schema
array = Array unboundedLength False
addField :: Text -> Bool -> Schema -> SchemaC
addField k r v = merge $ field k r v
addFields :: [(Text, Bool, Schema)] -> SchemaC
addFields = flip $ foldr (\(k, r, v) -> addField k r v)
empty :: Schema
empty = Object []
enum :: [Aeson.Value] -> Schema
enum = Choice . map Constant
nullable :: Schema -> Schema
nullable = (<|> Constant Aeson.Null)