123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134open!Core_kernelopen!ImportmoduletypeS=sigtypet[@@derivingsexp_of]valall:tlistendtype'at=(moduleSwithtypet='a)letcommand_friendly_namet=t|>String.tr~target:'_'~replacement:'-'|>String.lowercase;;letatom(typea)(m:at)a=letmoduleM=(valm)inmatch[%sexp_of:M.t]awith|Atoms->s|List_assexp->raise_s[%sexp"Enum.t expects atomic sexps.",(sexp:Sexp.t)];;letto_string_humma=command_friendly_name(atomma)letcheck_field_name(typea)(t:at)(a:a)field=[%test_eq:string](to_string_humta)(command_friendly_name(Field.namefield));;letenum(typea)(m:at)=letmoduleM=(valm)inList.mapM.all~f:(funa->to_string_humma,a);;letassert_alphabetic_order_exnhere(typea)(m:at)=letmoduleM=(valm)inletas_strings=List.mapM.all~f:(atomm)in[%test_result:stringlist]~here:[here]~message:"This enumerable type is intended to be defined in alphabetic order"~expect:(List.sortas_strings~compare:String.compare)as_strings;;letarg_type'=Command.Arg_type.of_alist_exnletarg_typem=arg_type'(enumm)letdoc'?represent_choice_withenum~doc=letchoices=enum|>List.map~f:fst|>List.sort~compare:String.compare|>String.concat~sep:"|"inmatchrepresent_choice_withwith|None->sprintf"(%s) %s"choicesdoc|Somerepresent_choice_with->letdoc=ifString.is_emptydocthen""else(letseparator=matchdoc.[String.lengthdoc-1]with|','|'.'->""|_->","insprintf" %s%s"docseparator)insprintf"%s%s %s can be (%s)"represent_choice_withdocrepresent_choice_withchoices;;letdoc?represent_choice_withm~doc=doc'?represent_choice_with(enumm)~docmoduleMake_param=structtype'at={arg_type:'aCommand.Arg_type.t;doc:string}letcreate?represent_choice_with~docm=letenum=enummin{arg_type=arg_type'enum;doc=doc'?represent_choice_withenum~doc};;endtype('a,'b)make_param=?represent_choice_with:string->?aliases:stringlist->string->doc:string->'at->'bCommand.Param.tletmake_param~f?represent_choice_with?aliasesflag_name~docm=let{Make_param.arg_type;doc}=Make_param.create?represent_choice_with~docminCommand.Param.flag?aliasesflag_name~doc(farg_type);;letmake_param_optional_with_default_doc~default?represent_choice_with?aliasesflag_name~docm=let{Make_param.arg_type;doc}=Make_param.create?represent_choice_with~docminCommand.Param.flag_optional_with_default_doc?aliasesflag_namearg_type(fundefault->Sexp.Atom(to_string_hummdefault))~default~doc;;moduleMake_stringable(M:S)=structletto_string=to_string_hum(moduleM)letof_string=letknown_values=lazy(List.fold[%all:M.t]~init:(Map.empty(moduleString))~f:(funmapt->Map.setmap~key:(to_stringt)~data:t))infuns->matchMap.find(forceknown_values)swith|None->letknown_values=Map.keys(forceknown_values)inraise_s[%message"Unknown value."s(known_values:stringlist)]|Somet->t;;end