From 647619a7f60f369b7f60c9e3542031dd40bbb67b Mon Sep 17 00:00:00 2001 From: Sasha Koshka Date: Wed, 19 Nov 2025 16:25:31 -0500 Subject: [PATCH] generate: It is no longer possible to make impossible type asserts with Receive --- generate/generate.go | 44 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/generate/generate.go b/generate/generate.go index b8d1b82..02959f5 100644 --- a/generate/generate.go +++ b/generate/generate.go @@ -114,6 +114,8 @@ func (this *Generator) Generate(protocol *Protocol) (n int, err error) { n += nn; if err != nil { return n, err } // type definitions + nn, err = this.generateMessageValueInterface() + n += nn; if err != nil { return n, err } for _, name := range slices.Sorted(maps.Keys(protocol.Types)) { nn, err := this.generateTypedef(name, protocol.Types[name]) n += nn; if err != nil { return n, err } @@ -140,6 +142,42 @@ func (this *Generator) Generate(protocol *Protocol) (n int, err error) { return n, nil } +func (this *Generator) generateMessageValueInterface() (n int, err error) { + keys := slices.Sorted(maps.Keys(this.protocol.Messages)) + nn, err := this.iprint( + "\n// ReceivedMessage is a sealed interface representing the value of a\n" + + "// message in this package. To determine what kind of message it is,\n" + + "// use a type switch like this:\n" + + "// \n" + + "// switch message := message.(type) {\n") + n += nn; if err != nil { return n, err } + for index, method := range keys { + if index > 2 { + nn, err := this.iprint("// \n// ...\n// \n") + n += nn; if err != nil { return n, err } + break + } + nn, err := this.iprintf("// case %s:\n", + this.resolveMessageName(this.protocol.Messages[method].Name)) + n += nn; if err != nil { return n, err } + nn, err = this.iprintf("// doSomething()\n") + n += nn; if err != nil { return n, err } + } + nn, err = this.iprintf("// }\n") + n += nn; if err != nil { return n, err } + + nn, err = this.iprintf("type ReceivedMessage interface {\n") + n += nn; if err != nil { return n, err } + this.push() + nn, err = this.iprintf("isReceivedMessage()\n") + n += nn; if err != nil { return n, err } + this.pop() + nn, err = this.iprintf("}\n") + n += nn; if err != nil { return n, err } + + return n, nil +} + func (this *Generator) generateTypedef(name string, typedef Typedef) (n int, err error) { typ := typedef.Type @@ -327,6 +365,10 @@ func (this *Generator) generateMessage(method uint16, message Message) (n int, e this.pop() nn, err = this.iprintf("}\n") n += nn; if err != nil { return n, err } + + // isReceivedMessage method + nn, err = this.iprintf("func (this %s) isReceivedMessage() { }\n", this.resolveMessageName(message.Name)) + n += nn; if err != nil { return n, err } return n, nil } @@ -1207,7 +1249,7 @@ func (this *Generator) generateReceive() (n int, err error) { "// Use a type switch to determine what type of message it is.\n") n += nn; if err != nil { return n, err } nn, err = this.iprintf( - "func Receive(trans hopp.Trans) (message any, n int, err error) {\n") + "func Receive(trans hopp.Trans) (message ReceivedMessage, n int, err error) {\n") n += nn; if err != nil { return n, err } this.push() nn, err = this.iprintf("method, reader, err := trans.ReceiveReader()\n")