123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148(**************************************************************************)(* *)(* 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. *)(* *)(**************************************************************************)typeformat_args=Protocol.format_args={path:stringoption;config:(string*string)listoption}letempty_args=Protocol.empty_argsmoduleVersion=Protocol.VersionmoduletypeIO=IO.SmoduleProtocol=ProtocolmoduleMake(IO:IO)=structmoduleProtocol=Protocol.Make(IO)moduleV1=structmoduleClient=structtypet={pid:int;input:IO.ic;output:IO.oc}letpidt=t.pidletmk~pidinputoutput={pid;input;output}letquerycommandt=letopenIOinProtocol.V1.outputt.outputcommand>>=fun()->Protocol.V1.read_inputt.inputlethaltt=letopenIOinmatchProtocol.V1.outputt.output`Haltwith|exception_->return(Error(`Msg"failing to close connection to server"))|(_:unitIO.t)->return(Ok())letconfigct=letopenIOinquery(`Configc)t>>=function|`Config_->return(Ok())|`Errormsg->return(Error(`Msgmsg))|_->return(Error(`Msg"failing to set configuration: unknown error"))letformatxt=letopenIOinquery(`Formatx)t>>=function|`Formatx->return(Okx)|`Errormsg->return(Error(`Msgmsg))|_->return(Error(`Msg"failing to format input: unknown error"))endendmoduleV2=structmoduleClient=structtypet={pid:int;input:IO.ic;output:IO.oc}letpidt=t.pidletmk~pidinputoutput={pid;input;output}letquerycommandt=letopenIOinProtocol.V2.outputt.outputcommand>>=fun()->Protocol.V2.read_inputt.inputlethaltt=letopenIOinmatchProtocol.V2.outputt.output`Haltwith|exception_->return(Error(`Msg"failing to close connection to server"))|(_:unitIO.t)->return(Ok())letformat~format_argsxt=letopenIOinquery(`Format(x,format_args))t>>=function|`Format(x,_args)->return(Okx)|`Errormsg->return(Error(`Msgmsg))|_->return(Error(`Msg"failing to format input: unknown error"))endendtypeclient=[`V1ofV1.Client.t|`V2ofV2.Client.t]letget_client~pidinputoutputx=matchVersion.of_stringxwith|SomeV1->Ok(`V1(V1.Client.mk~pidinputoutput))|SomeV2->Ok(`V2(V2.Client.mk~pidinputoutput))|None->Error(`Msg"invalid client version")letpick_client~pidicocversions=letopenIOinletrecaux=function|[]->return(Error(`Msg"Version negociation failed"))|latest::others->(Protocol.Init.outputoc(`Versionlatest)>>=fun()->Protocol.Init.read_inputic>>=function|`Versionvwhenv=latest->return(get_client~pidicocv)|`Versionv->(matchotherswith|h::_whenv=h->return(get_client~pidicocv)|_->auxothers)|`Unknown->auxothers|`Halt->return(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.pidcl|`V2cl->V2.Client.pidcllethalt=function|`V1cl->V1.Client.haltcl|`V2cl->V2.Client.haltclletconfigc=function|`V1cl->V1.Client.configccl|`V2_->IO.return(Error(`Msg"'Config' command not implemented in ocamlformat-rpc V2"))letformat?(format_args=empty_args)x=function|`V1cl->V1.Client.formatxcl|`V2cl->V2.Client.format~format_argsxclend