Skip to content

Instantly share code, notes, and snippets.

@kskyten
Created February 12, 2020 11:42
Show Gist options
  • Save kskyten/6e1f58538bd8d22453dfeaec61060cf9 to your computer and use it in GitHub Desktop.
Save kskyten/6e1f58538bd8d22453dfeaec61060cf9 to your computer and use it in GitHub Desktop.
JSON Schema sketches
using JSON3
# https://github.com/interagent/schematic/blob/master/schema.go
struct HRef{S}
href :: Union{Nothing, String}
order :: Union{Nothing, Vector{String}}
schemas :: Union{Nothing, Dict{String, S}}
HRef() = new{Schema}(nothing, nothing, nothing)
end
JSON3.StructType(::Type{HRef}) = JSON3.Mutable()
# https://github.com/JuliaLang/julia/issues/269
# https://discourse.julialang.org/t/mutually-recursive-type/25536
mutable struct Link{S}
title :: Union{Nothing, String}
description :: Union{Nothing, String}
href :: Union{Nothing, HRef}
rel :: Union{Nothing, String}
method :: Union{Nothing, String}
schema :: Union{Nothing, S}
targetSchema :: Union{Nothing, S}
mediaType :: Union{Nothing, String}
encType :: Union{Nothing, String}
Link() = new{Schema}(fill(nothing, 9)...)
end
JSON3.StructType(::Type{Link}) = JSON3.Mutable()
struct Reference
ref :: String
end
JSON3.StructType(::Type{Reference}) = JSON3.StringType()
Reference(ref::AbstractString) = Reference(ref)
mutable struct Schema
id :: Union{Nothing, String}
title :: Union{Nothing, String}
description :: Union{Nothing, String}
version :: Union{Nothing, String}
default :: Union{Nothing, Any}
readonly :: Union{Nothing, Bool}
example :: Union{Nothing, Any}
format :: Union{Nothing, String}
type :: Union{Nothing, Any}
ref :: Union{Nothing, Reference}
schema :: Union{Nothing, Reference}
definitions :: Union{Nothing, Dict{String, Schema}}
# Numbers
multipleOf :: Union{Nothing, Float64}
maximum :: Union{Nothing, Float64}
exclusiveMaximum :: Union{Nothing, Bool}
minimum :: Union{Nothing, Float64}
exclusiveMinimum :: Union{Nothing, Union{Bool, Int}}
# Strings
minLength :: Union{Nothing, Int}
maxLength :: Union{Nothing, Int}
pattern :: Union{Nothing, String}
# Objects
minProperties :: Union{Nothing, Int}
maxProperties :: Union{Nothing, Int}
required :: Union{Nothing, Vector{String}}
properties :: Union{Nothing, Dict{String, Union{Schema, Bool}}}
dependencies :: Union{Nothing, Dict{String, Any}}
additionalProperties :: Union{Nothing, Any}
patternProperties :: Union{Nothing, Dict{String, Schema}}
# Arrays
items :: Union{Nothing, Union{Schema, Bool}}
minItems :: Union{Nothing, Int}
maxItems :: Union{Nothing, Int}
uniqueItems :: Union{Nothing, Bool}
additionalItems :: Union{Nothing, Any}
# All
enum :: Union{Nothing, Vector{String}}
# Schemas
oneOf :: Union{Nothing, Vector{Schema}}
anyOf :: Union{Nothing, Vector{Schema}}
allOf :: Union{Nothing, Vector{Schema}}
not :: Union{Nothing, Vector{Schema}}
# Links
links :: Union{Nothing, Vector{Link}}
# This constructor doesn't work for some reason. Schema() returns nothing
Schema() = new(fill(nothing, 38)...)
end
JSON3.StructType(::Type{Schema}) = JSON3.Mutable()
JSON3.names(::Type{Schema}) = ((:id, Symbol("\$id")),
(:schema, Symbol("\$schema")),
(:ref, Symbol("\$ref")))
using Nullables
using Parameters
using JSON3
# This set of definitions is incomplete
JSON3.StructType(::Type{Nullable{String}}) = JSON3.StringType()
JSON3.StructType(::Type{Nullable{Bool}}) = JSON3.BoolType()
JSON3.StructType(::Type{Nullable{Int}}) = JSON3.NumberType()
JSON3.numbertype(::Type{Nullable{Int}}) = Int
# https://github.com/interagent/schematic/blob/master/schema.go
@with_kw struct HRef{S}
href = Nullable{String}() :: Nullable{String}
order = Nullable{Vector{String}}() :: Nullable{Vector{String}}
schemas = Nullable{Dict{String, Schema}}() :: Nullable{Dict{String, Schema}}
# HRef() = new{Schema}()
end
HRef() = HRef{Schema}()
# https://github.com/JuliaLang/julia/issues/269
# https://discourse.julialang.org/t/mutually-recursive-type/25536
@with_kw mutable struct Link{S}
title = Nullable{String}() :: Nullable{String}
description = Nullable{String}() :: Nullable{String}
href = Nullable{HRef{Schema}}() :: Nullable{HRef{Schema}}
rel = Nullable{String}() :: Nullable{String}
method = Nullable{String}() :: Nullable{String}
schema = Nullable{Schema}() :: Nullable{Schema}
targetSchema = Nullable{S}() :: Nullable{S}
mediaType = Nullable{String}() :: Nullable{String}
encType = Nullable{String}() :: Nullable{String}
# Link() = new{Schema}()
end
Link() = Link{Schema}()
@with_kw struct Reference
ref :: String
end
JSON3.StructType(::Type{Reference}) = JSON3.StringType()
Reference(ref::AbstractString) = Reference(ref)
@with_kw mutable struct Schema
id = Nullable{String}() :: Nullable{String}
title = Nullable{String}() :: Nullable{String}
description = Nullable{String}() :: Nullable{String}
version = Nullable{String}() :: Nullable{String}
default = Nullable{Any}() :: Nullable{Any}
readonly = Nullable{Bool}() :: Nullable{Bool}
example = Nullable{Any}() :: Nullable{Any}
format = Nullable{String}() :: Nullable{String}
type = Nullable{Any}() :: Nullable{Any}
ref = Nullable{Reference}() :: Nullable{Reference}
schema = Nullable{Reference}() :: Nullable{Reference}
definitions = Nullable{Dict{String, Schema}}() :: Nullable{Dict{String, Schema}}
# Numbers
multipleOf = Nullable{Float64}() :: Nullable{Float64}
maximum = Nullable{Float64}() :: Nullable{Float64}
exclusiveMaximum = Nullable{Bool}() :: Nullable{Bool}
minimum = Nullable{Float64}() :: Nullable{Float64}
exclusiveMinimum = Nullable{Union{Bool, Int}}() :: Nullable{Union{Bool, Int}}
# Strings
minLength = Nullable{Int}() :: Nullable{Int}
maxLength = Nullable{Int}() :: Nullable{Int}
pattern = Nullable{String}() :: Nullable{String}
# Objects
minProperties = Nullable{Int}() :: Nullable{Int}
maxProperties = Nullable{Int}() :: Nullable{Int}
required = Nullable{Vector{String}}() :: Nullable{Vector{String}}
properties = Nullable{Dict{String, Union{Schema, Bool}}}() :: Nullable{Dict{String, Union{Schema, Bool}}}
dependencies = Nullable{Dict{String, Any}}() :: Nullable{Dict{String, Any}}
additionalProperties = Nullable{Any}() :: Nullable{Any}
patternProperties = Nullable{Dict{String, Schema}}() :: Nullable{Dict{String, Schema}}
# Arrays
items = Nullable{Union{Schema, Bool}}() :: Nullable{Union{Schema, Bool}}
minItems = Nullable{Int}() :: Nullable{Int}
maxItems = Nullable{Int}() :: Nullable{Int}
uniqueItems = Nullable{Bool}() :: Nullable{Bool}
additionalItems = Nullable{Any}() :: Nullable{Any}
# All
enum = Nullable{Vector{String}}() :: Nullable{Vector{String}}
# Schemas
oneOf = Nullable{Vector{Schema}}() :: Nullable{Vector{Schema}}
anyOf = Nullable{Vector{Schema}}() :: Nullable{Vector{Schema}}
allOf = Nullable{Vector{Schema}}() :: Nullable{Vector{Schema}}
not = Nullable{Vector{Schema}}() :: Nullable{Vector{Schema}}
# Links
links = Nullable{Vector{Link{Schema}}}() :: Nullable{Vector{Link{Schema}}}
# Schema() = new()
end
JSON3.StructType(::Type{Schema}) = JSON3.Mutable()
JSON3.names(::Type{Schema}) = ((:id, Symbol("\$id")),
(:schema, Symbol("\$schema")),
(:ref, Symbol("\$ref")))
using JSON3
# https://github.com/interagent/schematic/blob/master/schema.go
struct HRef{S}
href :: String
order :: Vector{String}
schemas :: Dict{String, S}
HRef() = new{Schema}()
end
JSON3.StructType(::Type{HRef}) = JSON3.Mutable()
# https://github.com/JuliaLang/julia/issues/269
# https://discourse.julialang.org/t/mutually-recursive-type/25536
mutable struct Link{S}
title :: String
description :: String
href :: HRef
rel :: String
method :: String
schema :: S
targetSchema :: S
mediaType :: String
encType :: String
Link() = new{Schema}()
end
JSON3.StructType(::Type{Link}) = JSON3.Mutable()
struct Reference
ref :: String
end
JSON3.StructType(::Type{Reference}) = JSON3.StringType()
Reference(ref::AbstractString) = Reference(ref)
mutable struct Schema
id :: String
title :: String
description :: String
version :: String
default :: Any
readonly :: Bool
example :: Any
format :: String
type :: Any
ref :: Reference
schema :: Reference
definitions :: Dict{String, Schema}
# Numbers
multipleOf :: Float64
maximum :: Float64
exclusiveMaximum :: Bool
minimum :: Float64
exclusiveMinimum :: Union{Bool, Int}
# Strings
minLength :: Int
maxLength :: Int
pattern :: String
# Objects
minProperties :: Int
maxProperties :: Int
required :: Vector{String}
properties :: Dict{String, Union{Schema, Bool}}
dependencies :: Dict{String, Any}
additionalProperties :: Any
patternProperties :: Dict{String, Schema}
# Arrays
items :: Union{Schema, Bool}
minItems :: Int
maxItems :: Int
uniqueItems :: Bool
additionalItems :: Any
# All
enum :: Vector{String}
# Schemas
oneOf :: Vector{Schema}
anyOf :: Vector{Schema}
allOf :: Vector{Schema}
not :: Vector{Schema}
# Links
links :: Vector{Link}
Schema() = new()
end
JSON3.StructType(::Type{Schema}) = JSON3.Mutable()
JSON3.names(::Type{Schema}) = ((:id, Symbol("\$id")),
(:schema, Symbol("\$schema")),
(:ref, Symbol("\$ref")))
function defined_fields(schema::Schema)
[f => getfield(schema, f)
for f in fieldnames(Schema) if isdefined(schema, f)]
end
function Base.getproperty(link::Union{Link, Schema}, s::Symbol)
if isdefined(link, s)
return getfield(link, s)
else
return nothing
end
end
function Base.display(schema::Schema)
defined = [f => getproperty(schema, f)
for f in fieldnames(Schema) if isdefined(schema, f)]
return join(["Schema {", string(defined), "}"])
end
# function Base.show(io, schema::Schema)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment