Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Source file ppx_deriving_jsonschema.ml
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175openPpxlibopenAst_builder.Defaultletderiver_name="jsonschema"letjsonschema_key=Attribute.declare"jsonschema.key"Attribute.Context.label_declarationAst_pattern.(pstr(pstr_eval(estring__)nil^::nil))(funx->x)letjsonschema_ref=Attribute.declare"jsonschema.ref"Attribute.Context.label_declarationAst_pattern.(pstr(pstr_eval(estring__)nil^::nil))(funx->x)letjsonschema_variant_name=Attribute.declare"jsonschema.name"Attribute.Context.constructor_declarationAst_pattern.(pstr(pstr_eval(estring__)nil^::nil))(funx->x)letjsonschema_polymorphic_variant_name=Attribute.declare"jsonschema.name"Attribute.Context.rtagAst_pattern.(pstr(pstr_eval(estring__)nil^::nil))(funx->x)letattributes=[Attribute.Tjsonschema_key;Attribute.Tjsonschema_ref;Attribute.Tjsonschema_variant_name;Attribute.Tjsonschema_polymorphic_variant_name;]letargs()=Deriving.Args.(empty)(* let args () = Deriving.Args.(empty +> arg "option1" (eint __) +> flag "flag") *)letdeps=[]letpredefined_types=["string";"int";"float";"bool"]letis_predefined_typetype_name=List.memtype_namepredefined_typeslettype_ref~loctype_name=letname=estring~loc("#/$defs/"^type_name)in[%expr`Assoc["$ref",`String[%ename]]]lettype_def~loctype_name=[%expr`Assoc["type",`String[%eestring~loctype_name]]]letchar~loc=[%expr`Assoc["type",`String"string";"minLength",`Int1;"maxLength",`Int1]]letenum~locvalues=letvalues=List.map(funname->[%expr`String[%eestring~locname]])valuesin[%expr`Assoc["type",`String"string";"enum",`List[%eelist~locvalues]]]letarray_~locelement_type=[%expr`Assoc["type",`String"array";"items",[%eelement_type]]]lettuple~locelements=[%expr`Assoc["type",`String"array";"items",`List[%eelist~locelements]]]letvalue_name_pattern~loctype_name=ppat_var~loc{txt=type_name^"_jsonschema";loc}letcreate_value~locnamevalue=[%strilet[@warning"-32-39"](* rec *)[%pvalue_name_pattern~locname(* : [< `Assoc of _ list ] *)]=[%evalue]]letis_optional_typecore_type=matchcore_typewith|[%type:[%t?_]option]->true|_->falseletrectype_of_core~loccore_type=matchcore_typewith|[%type:int]|[%type:int32]|[%type:int64]->type_def~loc"integer"|[%type:float]->type_def~loc"number"|[%type:string]->type_def~loc"string"|[%type:bool]->type_def~loc"boolean"|[%type:char]->char~loc|[%type:[%t?t]option]->type_of_core~loct|[%type:[%t?t]list]|[%type:[%t?t]array]->lett=type_of_core~loctinarray_~loct|_->matchcore_type.ptyp_descwith|Ptyp_constr(id,[])->(* todo: support using references with [type_ref ~loc type_name] instead of inlining everything *)type_constr_conv~locid~f:(funs->s^"_jsonschema")[]|Ptyp_tupletypes->letts=List.map(type_of_core~loc)typesintuple~locts|Ptyp_variant(row_fields,_,_)->letconstr_names=List.map(funrow_field->letname_overwrite=Attribute.getjsonschema_polymorphic_variant_namerow_fieldinmatchname_overwritewith|Somename->name|None->matchrow_fieldwith|{prf_desc=Rtag(name,_,_);_}->name.txt|{prf_desc=Rinherit_core_type;_}->Format.asprintf"unsupported polymorphic variant type: %a"Astlib.Pprintast.core_typecore_type(* todo: *))row_fieldsinenum~locconstr_names|_->(* Format.printf "unsuported core type: %a\n------\n" Astlib.Pprintast.core_type core_type; *)[%expr(* todo: this type is unknown, placeholder to accept anything. Should create an error instead. *)`Assoc["unsuported core type",`String[%eestring~loc(Format.asprintf"%a"Astlib.Pprintast.core_typecore_type)];]](* todo: add option to inline types instead of using definitions references *)letobject_~locfields=letfields,required=List.fold_left(fun(fields,required)({pld_name={txt=name;_};pld_type;_}asfield)->letname=matchAttribute.getjsonschema_keyfieldwith|Somename->name|None->nameinlettype_def=matchAttribute.getjsonschema_reffieldwith|Somedef->type_ref~locdef|None->type_of_core~locpld_typein([%expr[%eestring~locname],[%etype_def]]::fields,ifis_optional_typepld_typethenrequiredelsename::required))([],[])fieldsinletrequired=List.map(funname->[%expr`String[%eestring~locname]])requiredin[%expr`Assoc["type",`String"object";"properties",`Assoc[%eelist~locfields];"required",`List[%eelist~locrequired];]]letderive_jsonschema~ctxtast=letloc=Expansion_context.Deriver.derived_item_locctxtinmatchastwith|_,[{ptype_name={txt=type_name;_};ptype_kind=Ptype_variantvariants;_}]->letvariants=List.map(fun({pcd_args;pcd_name={txt=name;_};_}asvar)->letname_overwrite=Attribute.getjsonschema_variant_namevarinmatchname_overwritewith|Somename->name|None->matchpcd_argswith|Pcstr_record_|Pcstr_tuple(_::_)->(* todo: emit an error when a type can't be turned into a valid json schema *)Format.asprintf"unsuported variant constructor with a payload: %a"Format.(pp_print_listAstlib.Pprintast.type_declaration)(sndast)|Pcstr_tuple[]->name)variantsin(* let names = List.map (fun { pcd_name = { txt = value; _ }; _ } -> value) variants in *)letjsonschema_expr=create_value~loctype_name(enum~locvariants)in[jsonschema_expr]|_,[{ptype_name={txt=type_name;_};ptype_kind=Ptype_recordlabel_declarations;_}]->letjsonschema_expr=create_value~loctype_name(object_~loclabel_declarations)in[jsonschema_expr]|_,[{ptype_name={txt=type_name;_};ptype_kind=Ptype_abstract;ptype_manifest=Somecore_type;_}]->letjsonschema_expr=create_value~loctype_name(type_of_core~loccore_type)in[jsonschema_expr]|_,_ast->(* Format.printf "unsuported type: %a\n======\n" Format.(pp_print_list Astlib.Pprintast.type_declaration) ast; *)[%str[%ocaml.error"Oops, jsonschema deriving does not support this type"]]letgenerator()=Deriving.Generator.V2.make~attributes(args())derive_jsonschema(* let generator () = Deriving.Generator.V2.make_noarg derive_jsonschema *)let_:Deriving.t=Deriving.addderiver_name~str_type_decl:(generator())