123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202(**************************************************************************)(* *)(* OCamlFormat *)(* *)(* Copyright (c) Facebook, Inc. and its affiliates. *)(* *)(* This source code is licensed under the MIT license found in *)(* the LICENSE file in the root directory of this source tree. *)(* *)(**************************************************************************)openSexplib0moduletypeCommand_S=sigtypetvalread_input:Stdlib.in_channel->tvalto_sexp:t->Sexp.tvaloutput:Stdlib.out_channel->t->unitendmoduletypeClient_S=sigtypettypecmdvalpid:t->intvalmk:pid:int->in_channel->out_channel->tvalquery:cmd->t->cmdvalhalt:t->(unit,[>`Msgofstring])resultvalconfig:(string*string)list->t->(unit,[>`Msgofstring])resultvalformat:string->t->(string,[>`Msgofstring])resultendmoduletypeV=sigmoduleCommand:Command_SmoduleClient:Client_Swithtypecmd=Command.tendmoduleCsexp=Csexp.Make(Sexp)moduleInit:Command_Swithtypet=[`Halt|`Unknown|`Versionofstring]=structtypet=[`Halt|`Unknown|`Versionofstring]letread_inputin_channel=letopenSexpinmatchCsexp.inputin_channelwith|Ok(Atom"Halt")->`Halt|Ok(List[Atom"Version";Atomv])->`Versionv|Ok_->`Unknown|Error_msg->`Haltletto_sexp=letopenSexpinfunction|`Versionv->List[Atom"Version";Atomv]|_->assertfalseletoutputchannelt=to_sexpt|>Csexp.to_channelchannel;Stdlib.flushchannelendmoduleV1:VwithtypeCommand.t=[`Halt|`Unknown|`Errorofstring|`Configof(string*string)list|`Formatofstring]=structmoduleCommand=structtypet=[`Halt|`Unknown|`Errorofstring|`Configof(string*string)list|`Formatofstring]letread_inputin_channel=letopenSexpinmatchCsexp.inputin_channelwith|Ok(List[Atom"Format";Atomx])->`Formatx|Ok(List[Atom"Config";Listl])->letc=List.fold_left(funacc->function|List[Atomname;Atomvalue]->(name,value)::acc|_->acc)[]l|>List.revin`Configc|Ok(List[Atom"Error";Atomx])->`Errorx|Ok(Atom"Halt")->`Halt|Ok_->`Unknown|Error_msg->`Haltletto_sexp=letopenSexpinfunction|`Formatx->List[Atom"Format";Atomx]|`Configc->letl=List.map(fun(name,value)->List[Atomname;Atomvalue])cinList[Atom"Config";Listl]|`Errorx->List[Atom"Error";Atomx]|`Halt->Atom"Halt"|_->assertfalseletoutputchannelt=to_sexpt|>Csexp.to_channelchannel;Stdlib.flushchannelendmoduleClient=structtypet={pid:int;input:in_channel;output:out_channel}typecmd=Command.tletpidt=t.pidletmk~pidinputoutput={pid;input;output}letquerycommandt=Command.outputt.outputcommand;Command.read_inputt.inputlethaltt=matchCommand.outputt.output`Halt;close_int.input;close_outt.outputwith|exception_->Error(`Msg"failing to close connection to server")|()->Ok()letconfigct=matchquery(`Configc)twith|`Config_->Ok()|`Errormsg->Error(`Msgmsg)|_->Error(`Msg"failing to set configuration: unknown error")letformatxt=matchquery(`Formatx)twith|`Formatx->Okx|`Errormsg->Error(`Msgmsg)|_->Error(`Msg"failing to format input: unknown error")endendtypeclient=[`V1ofV1.Client.t]letget_client~pidinputoutput=function|"v1"|"V1"->Some(`V1(V1.Client.mk~pidinputoutput))|_->Noneletget_client_exn~pidinputoutputx=matchget_client~pidinputoutputxwith|Somex->Okx|None->failwith"impossible"letpick_client~pidinputoutputversions=letrecaux=function|[]->Error(`Msg"Version negociation failed")|latest::others->(letversion=`VersionlatestinCsexp.to_channeloutput(Init.to_sexpversion);flushoutput;matchInit.read_inputinputwith|`Versionvwhenv=latest->get_client_exn~pidinputoutputv|`Versionv->(matchotherswith|h::_whenv=h->get_client_exn~pidinputoutputv|_->auxothers)|`Unknown->auxothers|`Halt->Error(`Msg"OCamlFormat-RPC did not respond. Check that a compatible \
version of the OCamlFormat RPC server (ocamlformat-rpc >= \
0.18.0) is installed."))inauxversionsletpid=function`V1cl->V1.Client.pidcllethalt=function`V1cl->V1.Client.haltclletconfigc=function`V1cl->V1.Client.configcclletformatx=function`V1cl->V1.Client.formatxcl