{-# LANGUAGE DerivingStrategies #-}
{-# LANGUAGE FlexibleContexts #-}

module Data.Medea.Parser.Spec.Property
  ( Specification (..),
    parseSpecification,
  )
where

import Data.Functor (($>))
import Data.Medea.Parser.Primitive
  ( Identifier,
    MedeaString,
    ReservedIdentifier (..),
    parseIdentifier,
    parseKeyVal,
    parseLine,
    parseReserved,
    parseString,
  )
import Data.Medea.Parser.Types (MedeaParser)
import Text.Megaparsec (MonadParsec (..), option, try)

data Specification = Specification
  { Specification -> MedeaString
propName :: !MedeaString,
    Specification -> Maybe Identifier
propSchema :: !(Maybe Identifier),
    Specification -> Bool
propOptional :: !Bool
  }
  deriving stock (Specification -> Specification -> Bool
(Specification -> Specification -> Bool)
-> (Specification -> Specification -> Bool) -> Eq Specification
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Specification -> Specification -> Bool
$c/= :: Specification -> Specification -> Bool
== :: Specification -> Specification -> Bool
$c== :: Specification -> Specification -> Bool
Eq)

parseSpecification :: MedeaParser Specification
parseSpecification :: MedeaParser Specification
parseSpecification =
  MedeaString -> Maybe Identifier -> Bool -> Specification
Specification
    (MedeaString -> Maybe Identifier -> Bool -> Specification)
-> ParsecT ParseError Text Identity MedeaString
-> ParsecT
     ParseError
     Text
     Identity
     (Maybe Identifier -> Bool -> Specification)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ParsecT ParseError Text Identity MedeaString
parsePropName
    ParsecT
  ParseError
  Text
  Identity
  (Maybe Identifier -> Bool -> Specification)
-> ParsecT ParseError Text Identity (Maybe Identifier)
-> ParsecT ParseError Text Identity (Bool -> Specification)
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT ParseError Text Identity (Maybe Identifier)
parsePropSchema
    ParsecT ParseError Text Identity (Bool -> Specification)
-> ParsecT ParseError Text Identity Bool
-> MedeaParser Specification
forall (f :: * -> *) a b. Applicative f => f (a -> b) -> f a -> f b
<*> ParsecT ParseError Text Identity Bool
parsePropOptional
  where
    parsePropName :: ParsecT ParseError Text Identity MedeaString
parsePropName =
      Int
-> ParsecT ParseError Text Identity MedeaString
-> ParsecT ParseError Text Identity MedeaString
forall a. Int -> MedeaParser a -> MedeaParser a
parseLine Int
8 (ParsecT ParseError Text Identity MedeaString
 -> ParsecT ParseError Text Identity MedeaString)
-> ParsecT ParseError Text Identity MedeaString
-> ParsecT ParseError Text Identity MedeaString
forall a b. (a -> b) -> a -> b
$
        ReservedIdentifier
-> ParsecT ParseError Text Identity MedeaString
-> ParsecT ParseError Text Identity MedeaString
forall a. ReservedIdentifier -> MedeaParser a -> MedeaParser a
parseKeyVal ReservedIdentifier
RPropertyName ParsecT ParseError Text Identity MedeaString
parseString
    parsePropSchema :: ParsecT ParseError Text Identity (Maybe Identifier)
parsePropSchema =
      Maybe Identifier
-> ParsecT ParseError Text Identity (Maybe Identifier)
-> ParsecT ParseError Text Identity (Maybe Identifier)
forall (m :: * -> *) a. Alternative m => a -> m a -> m a
option Maybe Identifier
forall a. Maybe a
Nothing (ParsecT ParseError Text Identity (Maybe Identifier)
 -> ParsecT ParseError Text Identity (Maybe Identifier))
-> (ParsecT ParseError Text Identity (Maybe Identifier)
    -> ParsecT ParseError Text Identity (Maybe Identifier))
-> ParsecT ParseError Text Identity (Maybe Identifier)
-> ParsecT ParseError Text Identity (Maybe Identifier)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParsecT ParseError Text Identity (Maybe Identifier)
-> ParsecT ParseError Text Identity (Maybe Identifier)
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (ParsecT ParseError Text Identity (Maybe Identifier)
 -> ParsecT ParseError Text Identity (Maybe Identifier))
-> (ParsecT ParseError Text Identity (Maybe Identifier)
    -> ParsecT ParseError Text Identity (Maybe Identifier))
-> ParsecT ParseError Text Identity (Maybe Identifier)
-> ParsecT ParseError Text Identity (Maybe Identifier)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int
-> ParsecT ParseError Text Identity (Maybe Identifier)
-> ParsecT ParseError Text Identity (Maybe Identifier)
forall a. Int -> MedeaParser a -> MedeaParser a
parseLine Int
8 (ParsecT ParseError Text Identity (Maybe Identifier)
 -> ParsecT ParseError Text Identity (Maybe Identifier))
-> ParsecT ParseError Text Identity (Maybe Identifier)
-> ParsecT ParseError Text Identity (Maybe Identifier)
forall a b. (a -> b) -> a -> b
$
        Identifier -> Maybe Identifier
forall a. a -> Maybe a
Just (Identifier -> Maybe Identifier)
-> ParsecT ParseError Text Identity Identifier
-> ParsecT ParseError Text Identity (Maybe Identifier)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ReservedIdentifier
-> ParsecT ParseError Text Identity Identifier
-> ParsecT ParseError Text Identity Identifier
forall a. ReservedIdentifier -> MedeaParser a -> MedeaParser a
parseKeyVal ReservedIdentifier
RPropertySchema ParsecT ParseError Text Identity Identifier
parseIdentifier
    parsePropOptional :: ParsecT ParseError Text Identity Bool
parsePropOptional =
      Bool
-> ParsecT ParseError Text Identity Bool
-> ParsecT ParseError Text Identity Bool
forall (m :: * -> *) a. Alternative m => a -> m a -> m a
option Bool
False (ParsecT ParseError Text Identity Bool
 -> ParsecT ParseError Text Identity Bool)
-> (ParsecT ParseError Text Identity Bool
    -> ParsecT ParseError Text Identity Bool)
-> ParsecT ParseError Text Identity Bool
-> ParsecT ParseError Text Identity Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ParsecT ParseError Text Identity Bool
-> ParsecT ParseError Text Identity Bool
forall e s (m :: * -> *) a. MonadParsec e s m => m a -> m a
try (ParsecT ParseError Text Identity Bool
 -> ParsecT ParseError Text Identity Bool)
-> (ParsecT ParseError Text Identity Bool
    -> ParsecT ParseError Text Identity Bool)
-> ParsecT ParseError Text Identity Bool
-> ParsecT ParseError Text Identity Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int
-> ParsecT ParseError Text Identity Bool
-> ParsecT ParseError Text Identity Bool
forall a. Int -> MedeaParser a -> MedeaParser a
parseLine Int
8 (ParsecT ParseError Text Identity Bool
 -> ParsecT ParseError Text Identity Bool)
-> ParsecT ParseError Text Identity Bool
-> ParsecT ParseError Text Identity Bool
forall a b. (a -> b) -> a -> b
$
        ReservedIdentifier -> ParsecT ParseError Text Identity Identifier
parseReserved ReservedIdentifier
ROptionalProperty ParsecT ParseError Text Identity Identifier
-> Bool -> ParsecT ParseError Text Identity Bool
forall (f :: * -> *) a b. Functor f => f a -> b -> f b
$> Bool
True