feat: support optional RPC fields
This commit is contained in:
parent
dd6528bceb
commit
bea68819c9
2 changed files with 39 additions and 3 deletions
|
|
@ -85,6 +85,9 @@ def withFieldsFlattened (indVal : InductiveVal) (params : Array Expr)
|
|||
|
||||
end
|
||||
|
||||
def isOptField (n : Name) : Bool :=
|
||||
n.toString.endsWith "?"
|
||||
|
||||
private def deriveStructureInstance (indVal : InductiveVal) (params : Array Expr) : TermElabM Syntax :=
|
||||
withFields indVal params fun fields => do
|
||||
trace[Elab.Deriving.RpcEncoding] "for structure {indVal.name} with params {params}"
|
||||
|
|
@ -97,20 +100,30 @@ private def deriveStructureInstance (indVal : InductiveVal) (params : Array Expr
|
|||
let mut uniqFieldEncIds : Array Syntax := #[]
|
||||
let mut fieldEncIds' : DiscrTree Syntax := {}
|
||||
for (fieldName, fieldTp) in fields do
|
||||
let mut fieldTp := fieldTp
|
||||
if isOptField fieldName then
|
||||
if !fieldTp.isAppOf ``Option then
|
||||
throwError "optional field '{fieldName}' has type{indentD m!"{fieldTp}"}\nbut is expected to have type{indentD "Option _"}"
|
||||
fieldTp := fieldTp.getArg! 0
|
||||
|
||||
-- postulate that the field has an encoding and remember the encoding's binder name
|
||||
fieldIds := fieldIds.push <| mkIdent fieldName
|
||||
let mut fieldEncId := Syntax.missing
|
||||
match (← fieldEncIds'.getMatch fieldTp).back? with
|
||||
| none =>
|
||||
let fieldEncId ← mkIdent <$> mkFreshUserName fieldName
|
||||
fieldEncId ← mkIdent <$> mkFreshUserName fieldName
|
||||
binders := binders.push <| ← `(Deriving.explicitBinderF| ( $fieldEncId:ident ))
|
||||
let stx ← PrettyPrinter.delab fieldTp
|
||||
binders := binders.push <|
|
||||
← `(Deriving.instBinderF| [ $(mkIdent ``Lean.Server.RpcEncoding) $stx $fieldEncId:ident ])
|
||||
fieldEncIds' ← fieldEncIds'.insert fieldTp fieldEncId
|
||||
uniqFieldEncIds := uniqFieldEncIds.push fieldEncId
|
||||
| some fid => fieldEncId := fid
|
||||
|
||||
if isOptField fieldName then
|
||||
fieldEncIds := fieldEncIds.push <| ← ``(Option $fieldEncId:ident)
|
||||
else
|
||||
fieldEncIds := fieldEncIds.push fieldEncId
|
||||
| some fid =>
|
||||
fieldEncIds := fieldEncIds.push fid
|
||||
|
||||
-- helpers for field initialization syntax
|
||||
let fieldInits (func : Name) := fieldIds.mapM fun fid =>
|
||||
|
|
@ -222,6 +235,7 @@ private def deriveInductiveInstance (indVal : InductiveVal) (params : Array Expr
|
|||
|
||||
inductive $(mkIdent packetNm) where
|
||||
$[$(st.ctors):ctor]*
|
||||
deriving $(mkIdent ``FromJson), $(mkIdent ``ToJson)
|
||||
|
||||
instance : $(mkIdent ``RpcEncoding) $typeId:ident $packetAppliedId:ident where
|
||||
rpcEncode := fun x => match x with
|
||||
|
|
|
|||
|
|
@ -2,10 +2,16 @@ import Lean.Server.Rpc.Basic
|
|||
|
||||
open Lean Server
|
||||
|
||||
@[reducible]
|
||||
def rpcPacketFor (α : Type) {β : outParam Type} [RpcEncoding α β] := β
|
||||
|
||||
structure FooRef where
|
||||
a : Array Nat
|
||||
deriving RpcEncoding with { withRef := true }
|
||||
|
||||
#synth FromJson (rpcPacketFor (WithRpcRef FooRef))
|
||||
#synth ToJson (rpcPacketFor (WithRpcRef FooRef))
|
||||
|
||||
structure FooJson where
|
||||
s : String
|
||||
deriving FromJson, ToJson
|
||||
|
|
@ -15,19 +21,35 @@ structure Bar where
|
|||
fooJson : FooJson
|
||||
deriving RpcEncoding
|
||||
|
||||
#synth FromJson (rpcPacketFor Bar)
|
||||
#synth ToJson (rpcPacketFor Bar)
|
||||
|
||||
structure BarTrans where
|
||||
bar : Bar
|
||||
deriving RpcEncoding
|
||||
|
||||
#synth FromJson (rpcPacketFor BarTrans)
|
||||
#synth ToJson (rpcPacketFor BarTrans)
|
||||
|
||||
structure Baz where
|
||||
arr : Array String -- non-constant field
|
||||
deriving RpcEncoding
|
||||
|
||||
#synth FromJson (rpcPacketFor Baz)
|
||||
#synth ToJson (rpcPacketFor Baz)
|
||||
|
||||
structure FooGeneric (α : Type) where
|
||||
a : α
|
||||
b? : Option α
|
||||
deriving RpcEncoding
|
||||
|
||||
#synth FromJson (rpcPacketFor <| FooGeneric Nat)
|
||||
#synth ToJson (rpcPacketFor <| FooGeneric Nat)
|
||||
|
||||
inductive FooInductive (α : Type) where
|
||||
| a : α → Bar → FooInductive α
|
||||
| b : (n : Nat) → (a : α) → Nat → FooInductive α
|
||||
deriving RpcEncoding
|
||||
|
||||
#synth FromJson (rpcPacketFor <| FooInductive Nat)
|
||||
#synth ToJson (rpcPacketFor <| FooInductive Nat)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue