module Graql.Property
( Property (..)
, Var
, Name
, VarOrName
, Value (..)
, IsVarOrName
, IsRolePlayer
, IsResource
, var
, name
, (.:)
, rp
, toVarOrName
, toRolePlayer
, toResource
) where
import Graql.Util
import Data.Text (Text, unpack)
import Data.Scientific (Scientific)
import Text.Regex.Posix ((=~))
import Control.Applicative (empty)
import Data.Aeson (FromJSON, FromJSONKey,
FromJSONKeyFunction (FromJSONKeyText),
parseJSON)
import qualified Data.Aeson as Aeson
data Property = Isa VarOrName
| NameProperty Name
| Rel [RolePlayer]
| Has Name (Either Value Var)
data Var = Var Text deriving (Eq, Ord)
data Name = Name Text
data VarOrName = VarName Var | TypeName Name
data Value = ValueString Text | ValueNumber Scientific | ValueBool Bool
data RolePlayer = RolePlayer (Maybe VarOrName) Var
class IsVarOrName a where
toVarOrName :: a -> VarOrName
class IsRolePlayer a where
toRolePlayer :: a -> RolePlayer
class IsResource a where
toResource :: a -> Either Value Var
var :: Text -> Var
var = Var
name :: Text -> Name
name = Name
(.:) :: IsVarOrName a => a -> Var -> RolePlayer
rt .: player = RolePlayer (Just $ toVarOrName rt) player
rp :: Var -> RolePlayer
rp = RolePlayer Nothing
nameRegex :: String
nameRegex = "^[a-zA-Z_][a-zA-Z0-9_-]*$"
instance Show Property where
show (Isa varOrName ) = "isa " ++ show varOrName
show (NameProperty n) = "type-name " ++ show n
show (Rel castings ) = "(" ++ commas castings ++ ")"
show (Has rt value ) = "has " ++ show rt ++ " " ++ showEither value
instance Show RolePlayer where
show (RolePlayer roletype player) = roletype `with` ": " ++ show player
instance Show Value where
show (ValueString text) = show text
show (ValueNumber num ) = show num
show (ValueBool bool) = show bool
instance Show Name where
show (Name text)
| str =~ nameRegex = str
| otherwise = show text
where str = unpack text
instance Show Var where
show (Var v) = '$' : unpack v
instance Show VarOrName where
show (VarName v) = show v
show (TypeName t) = show t
instance IsVarOrName Var where
toVarOrName = VarName
instance IsVarOrName Name where
toVarOrName = TypeName
instance IsRolePlayer RolePlayer where
toRolePlayer = id
instance IsRolePlayer Var where
toRolePlayer = rp
instance IsResource Var where
toResource = Right
instance IsResource Text where
toResource = Left . ValueString
instance IsResource Scientific where
toResource = Left . ValueNumber
instance IsResource Bool where
toResource = Left . ValueBool
instance FromJSON Value where
parseJSON (Aeson.String s) = return $ ValueString s
parseJSON (Aeson.Number n) = return $ ValueNumber n
parseJSON (Aeson.Bool b) = return $ ValueBool b
parseJSON _ = empty
instance FromJSON Name where
parseJSON (Aeson.String s) = return $ name s
parseJSON _ = empty
instance FromJSON Var where
parseJSON (Aeson.String s) = return $ var s
parseJSON _ = empty
instance FromJSONKey Var where
fromJSONKey = FromJSONKeyText var
showEither :: (Show a, Show b) => Either a b -> String
showEither = either show show