diff --git a/src/intertypes/InterTypes.jl b/src/intertypes/InterTypes.jl index d886ea9..d728817 100644 --- a/src/intertypes/InterTypes.jl +++ b/src/intertypes/InterTypes.jl @@ -1,5 +1,5 @@ module InterTypes -export InterType, InterTypeDecl, Binary, intertype, @intertypes +export InterType, InterTypeDecl, Binary, LanguageTarget, SerializationTarget, generate_module, intertype, @intertypes using MLStyle using OrderedCollections @@ -100,6 +100,19 @@ end function intertype end +abstract type ExportTarget end +abstract type LanguageTarget <: ExportTarget end +abstract type SerializationTarget <: ExportTarget end + +""" + generate_module(mod::Module, target::Type{<:ExportTarget}, path="."; target_specific_args...) + +Generate files that define the intertypes for the specified target. +""" +function generate_module(mod::Module, target::Type{<:ExportTarget}, path="."; target_specific_args...) + generate_module(mod.Meta, target, path; target_specific_args...) +end + include("json.jl") include("sexp.jl") include("julia.jl") diff --git a/src/intertypes/json.jl b/src/intertypes/json.jl index 6efc8e2..400cea0 100644 --- a/src/intertypes/json.jl +++ b/src/intertypes/json.jl @@ -1,4 +1,4 @@ -export tojsonschema, jsonwrite, jsonread, generate_jsonschema_module +export JSONTarget, tojsonschema, jsonwrite, jsonread using OrderedCollections using Base64 @@ -358,8 +358,16 @@ function acsettype(spec) ) end -function generate_jsonschema_module( - mod::InterTypeModule, path="." +""" + JSONTarget + +Specifies a serialization target of JSON Schema when +generating a module. +""" +struct JSONTarget <: SerializationTarget end + +function generate_module( + mod::InterTypeModule, ::Type{JSONTarget}, path ;ac=JSON3.AlignmentContext(indent=2) ) defs = Pair{String, Object}[] @@ -384,11 +392,8 @@ function generate_jsonschema_module( "\$schema" => "http://json-schema.org/draft-07/schema#", "\$defs" => Object(defs) ) - open(string(mod.name) * "_schema.json", "w") do io + schema_filepath = joinpath(path, string(mod.name)*"_schema.json") + open(schema_filepath, "w") do io JSON3.pretty(io, schema, ac) end end - -function generate_jsonschema_module(mod::Module, path=".") - generate_jsonschema_module(mod.Meta, path) -end diff --git a/src/intertypes/julia.jl b/src/intertypes/julia.jl index 1ee86ab..cae656a 100644 --- a/src/intertypes/julia.jl +++ b/src/intertypes/julia.jl @@ -307,7 +307,7 @@ end function include_intertypes(into::Module, file::String, imports::AbstractVector) endswith(file, ".it") || error("expected a file ending in \".it\"") - name = Symbol(chop(file; tail=3)) + name = Symbol(basename(chop(file; tail=3))) mod = InterTypeModule(name, OrderedDict{Symbol, InterTypeModule}(imports)) into.include(as_intertypes(mod), file) # recompute the hash diff --git a/src/intertypes/python.jl b/src/intertypes/python.jl index 8512499..f3fe8f1 100644 --- a/src/intertypes/python.jl +++ b/src/intertypes/python.jl @@ -1,4 +1,4 @@ -export generate_python_module +export PydanticTarget function topy(intertype::InterType; forward_ref=true) @match intertype begin @@ -141,6 +141,7 @@ from intertypes import SafeInt, InterTypeBase from acsets import Ob, Hom, Attr, AttrType, Schema, ACSet """ +# TODO: Expose this to the user? Write automatically for the user? INTERTYPE_PYTHON_MODULE = """ from typing import Annotated @@ -156,9 +157,19 @@ class InterTypeBase(BaseModel): return super().model_dump_json(*args, **kwargs, by_alias=True) """ -function generate_python_module(jmod::Module, outdir) - mod = jmod.Meta - outfile = outdir * "/" * string(mod.name) * ".py" + +""" + PydanticTarget + +Targets the creation of `.py` files that use the Pydantic library +which enables integration with the Python language (specifically +when (de)serializing JSON). +""" +struct PydanticTarget <: LanguageTarget end + + +function generate_module(mod::InterTypeModule, ::Type{PydanticTarget}, path) + outfile = joinpath(path, string(mod.name) * ".py") open(outfile, "w") do io print(io, PYTHON_PREAMBLE) for (name, importedmod) in mod.imports diff --git a/test/intertypes/InterTypes.jl b/test/intertypes/InterTypes.jl index 5c03609..bcf13e3 100644 --- a/test/intertypes/InterTypes.jl +++ b/test/intertypes/InterTypes.jl @@ -43,7 +43,7 @@ s = jsonwrite(t) @test jsonread(s, Term) == t -generate_jsonschema_module(simpleast, ".") +generate_module(simpleast, JSONTarget) simpleast_schema = JSONSchema.Schema(read("simpleast_schema.json", String)) @@ -71,7 +71,7 @@ add_part!(g, :E, src=1, tgt=2, weight=EdgeData(:mass_ave, 42)) @test testjson(m) -generate_jsonschema_module(wgraph, ".") +generate_module(wgraph, JSONTarget) wgraph_schema = JSONSchema.Schema(read("wgraph_schema.json", String)) @@ -86,9 +86,9 @@ wgraph_schema = JSONSchema.Schema(read("wgraph_schema.json", String)) dir = @__DIR__ write(dir * "/intertypes.py", InterTypes.INTERTYPE_PYTHON_MODULE) - generate_python_module(simpleast, dir) - generate_python_module(model, dir) - generate_python_module(wgraph, dir) + generate_module(simpleast, PydanticTarget, dir) + generate_module(model, PydanticTarget, dir) + generate_module(wgraph, PydanticTarget, dir) pushfirst!(PyList(pyimport("sys")."path"), Py(dir))