module Hydra.Ext.Graphql.Coder where -- (printGraph) where import Hydra.All --import Hydra.Adapter --import Hydra.Adapters.Term --import Hydra.CoreDecoding --import Hydra.CoreLanguage --import Hydra.Adapters.Coders --import Hydra.Ext.Graphql.Language --import Hydra.Ext.Graphql.Serde --import qualified Hydra.Ext.Graphql.Syntax as G --import qualified Hydra.Impl.Haskell.Dsl.Types as Types --import Hydra.Util.Codetree.Script import qualified Control.Monad as CM import qualified Data.List as L import qualified Data.Map as M import qualified Data.Maybe as Y --printGraph :: (Ord m, Read m, Show m) => Graph m -> GraphFlow m (M.Map FilePath String) --printGraph g = do -- sf <- moduleToGraphqlSchema g -- let s = printExpr $ parenthesize $ exprDocument sf -- return $ M.fromList [(graphNameToFilePath False (FileExtension "graphql") $ graphName g, s)] -- --constructModule :: (Ord m, Read m, Show m) -- => Graph m -- -> M.Map (Type m) (Coder (Context m) (Term m) ()) -- -> [(Element m, TypedTerm m)] -- -> GraphFlow m G.Document --constructModule g coders pairs = do -- fail "TODO" ---- let ns = pdlNameForGraph g ---- let pkg = Nothing ---- let imports = [] -- TODO ---- sortedPairs <- case (topologicalSortElements $ fst <$> pairs) of ---- Nothing -> fail $ "types form a cycle (unsupported in PDL)" ---- Just sorted -> pure $ Y.catMaybes $ fmap (\n -> M.lookup n pairByName) sorted ---- schemas <- CM.mapM toSchema sortedPairs ---- return $ PDL.SchemaFile ns pkg imports schemas ---- where ---- pairByName = L.foldl (\m p@(el, tt) -> M.insert (elementName el) p m) M.empty pairs ---- aliases = importAliasesForGraph g ---- toSchema (el, TypedTerm typ term) = if stripType typ == TypeNominal _Type ---- then decodeType term >>= typeToSchema el ---- else fail $ "mapping of non-type elements to PDL is not yet supported: " ++ show typ ---- typeToSchema el typ = do ---- let qname = pdlNameForElement aliases False $ elementName el ---- res <- encodeAdaptedType aliases typ ---- let ptype = case res of ---- Left schema -> PDL.NamedSchema_TypeTyperef schema ---- Right t -> t ---- cx <- getState ---- r <- annotationClassTermDescription (contextAnnotations cx) $ elementTerm el ---- let anns = doc r ---- return $ PDL.NamedSchema qname ptype anns -- --moduleToGraphqlSchema :: (Ord m, Read m, Show m) => Graph m -> GraphFlow m G.Document --moduleToGraphqlSchema g = graphToExternalModule language (encodeTerm aliases) constructModule g -- where -- aliases = importAliasesForGraph g -- ----doc :: Y.Maybe String -> PDL.Annotations ----doc s = PDL.Annotations s False ---- ----encodeAdaptedType :: (Ord m, Read m, Show m) ---- => M.Map GraphName String -> Type m ---- -> GraphFlow m (Either PDL.Schema PDL.NamedSchema_Type) ----encodeAdaptedType aliases typ = do ---- cx <- getState ---- let acx = AdapterContext cx hydraCoreLanguage language ---- ad <- withState acx $ termAdapter typ ---- encodeType aliases $ adapterTarget ad -- --encodeTerm :: (Eq m, Ord m, Read m, Show m) => M.Map GraphName String -> Term m -> GraphFlow m () --encodeTerm aliases term = fail "term encoding is not yet implemented" -- ----encodeType :: (Eq m, Show m) => M.Map GraphName String -> Type m -> GraphFlow m (Either PDL.Schema PDL.NamedSchema_Type) ----encodeType aliases typ = case stripType typ of ---- TypeList lt -> Left . PDL.SchemaArray <$> encode lt ---- TypeLiteral lt -> Left . PDL.SchemaPrimitive <$> case lt of ---- LiteralTypeBinary -> pure PDL.PrimitiveTypeBytes ---- LiteralTypeBoolean -> pure PDL.PrimitiveTypeBoolean ---- LiteralTypeFloat ft -> case ft of ---- FloatTypeFloat32 -> pure PDL.PrimitiveTypeFloat ---- FloatTypeFloat64 -> pure PDL.PrimitiveTypeDouble ---- _ -> fail $ "unexpected floating-point type: " ++ show ft ---- LiteralTypeInteger it -> case it of ---- IntegerTypeInt32 -> pure PDL.PrimitiveTypeInt ---- IntegerTypeInt64 -> pure PDL.PrimitiveTypeLong ---- _ -> fail $ "unexpected integer type: " ++ show it ---- LiteralTypeString -> pure PDL.PrimitiveTypeString ---- TypeMap (MapType kt vt) -> Left . PDL.SchemaMap <$> encode vt -- note: we simply assume string as a key type ---- TypeNominal name -> pure $ Left $ PDL.SchemaNamed $ pdlNameForElement aliases True name ---- TypeOptional ot -> fail $ "optionals unexpected at top level" ---- TypeRecord (RowType _ fields) -> do ---- let includes = [] ---- rfields <- CM.mapM encodeRecordField fields ---- return $ Right $ PDL.NamedSchema_TypeRecord $ PDL.RecordSchema rfields includes ---- TypeUnion (RowType _ fields) -> if isEnum ---- then do ---- fs <- CM.mapM encodeEnumField fields ---- return $ Right $ PDL.NamedSchema_TypeEnum $ PDL.EnumSchema fs ---- else Left . PDL.SchemaUnion . PDL.UnionSchema <$> CM.mapM encodeUnionField fields ---- where ---- isEnum = L.foldl (\b t -> b && stripType t == Types.unit) True $ fmap fieldTypeType fields ---- _ -> fail $ "unexpected type: " ++ show typ ---- where ---- encode t = case stripType t of ---- TypeRecord (RowType _ []) -> encode Types.int32 -- special case for the unit type ---- _ -> do ---- res <- encodeType aliases t ---- case res of ---- Left schema -> pure schema ---- Right _ -> fail $ "type resolved to an unsupported nested named schema: " ++ show t ---- encodeRecordField (FieldType (FieldName name) typ) = do ---- anns <- getAnns typ ---- (schema, optional) <- encodePossiblyOptionalType typ ---- return PDL.RecordField { ---- PDL.recordFieldName = PDL.FieldName name, ---- PDL.recordFieldValue = schema, ---- PDL.recordFieldOptional = optional, ---- PDL.recordFieldDefault = Nothing, ---- PDL.recordFieldAnnotations = anns} ---- encodeUnionField (FieldType (FieldName name) typ) = do ---- anns <- getAnns typ ---- (s, optional) <- encodePossiblyOptionalType typ ---- let schema = if optional ---- then PDL.SchemaUnion $ PDL.UnionSchema (simpleUnionMember <$> [PDL.SchemaNull, s]) ---- else s ---- return PDL.UnionMember { ---- PDL.unionMemberAlias = Just $ PDL.FieldName name, ---- PDL.unionMemberValue = schema, ---- PDL.unionMemberAnnotations = anns} ---- encodeEnumField (FieldType (FieldName name) typ) = do ---- anns <- getAnns typ ---- return PDL.EnumField { ---- PDL.enumFieldName = PDL.EnumFieldName $ convertCase CaseCamel CaseUpperSnake name, ---- PDL.enumFieldAnnotations = anns} ---- encodePossiblyOptionalType typ = case stripType typ of ---- TypeOptional ot -> do ---- t <- encode ot ---- return (t, True) ---- _ -> do ---- t <- encode typ ---- return (t, False) ---- getAnns typ = do ---- cx <- getState ---- r <- annotationClassTypeDescription (contextAnnotations cx) typ ---- return $ doc r -- --importAliasesForGraph g = M.empty -- TODO -- ----noAnnotations :: PDL.Annotations ----noAnnotations = PDL.Annotations Nothing False ---- ----pdlNameForElement :: M.Map GraphName String -> Bool -> Name -> PDL.QualifiedName ----pdlNameForElement aliases withNs name = PDL.QualifiedName (PDL.Name local) ---- $ if withNs ---- then PDL.Namespace . slashesToDots <$> alias ---- else Nothing ---- where ---- (ns, local) = toQname name ---- alias = M.lookup ns aliases ---- ----pdlNameForGraph :: Graph m -> PDL.Namespace ----pdlNameForGraph = PDL.Namespace . slashesToDots . h . graphName ---- where ---- h (GraphName n) = n ---- ----simpleUnionMember :: PDL.Schema -> PDL.UnionMember ----simpleUnionMember schema = PDL.UnionMember Nothing schema noAnnotations ---- ----slashesToDots :: String -> String ----slashesToDots = fmap (\c -> if c == '/' then '.' else c)