Skip to content

Commit e63f9d5

Browse files
server/cmd: Add cmd.ParamDescriber to allow non-reflect param schemas (#1132)
feat: add cmd ParamDescriber
1 parent 4c63a4b commit e63f9d5

File tree

2 files changed

+19
-5
lines changed

2 files changed

+19
-5
lines changed

server/cmd/command.go

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,12 @@ package cmd
33
import (
44
"encoding/csv"
55
"fmt"
6-
"github.com/df-mc/dragonfly/server/world"
76
"go/ast"
87
"reflect"
98
"slices"
109
"strings"
10+
11+
"github.com/df-mc/dragonfly/server/world"
1112
)
1213

1314
// Runnable represents a Command that may be run by a Command source. The Command must be a struct type and
@@ -178,14 +179,20 @@ type ParamInfo struct {
178179
func (cmd Command) Params(src Source) [][]ParamInfo {
179180
params := make([][]ParamInfo, 0, len(cmd.v))
180181
for _, runnable := range cmd.v {
181-
elem := reflect.New(runnable.Type()).Elem()
182-
elem.Set(runnable)
183-
184182
if allower, ok := runnable.Interface().(Allower); ok && !allower.Allow(src) {
185183
// This source cannot execute this runnable.
186184
continue
187185
}
188186

187+
// If the runnable can describe its own parameters, prefer that over reflection.
188+
if d, ok := runnable.Interface().(ParamDescriber); ok {
189+
params = append(params, d.DescribeParams(src))
190+
continue
191+
}
192+
193+
elem := reflect.New(runnable.Type()).Elem()
194+
elem.Set(runnable)
195+
189196
var fields []ParamInfo
190197
for _, t := range exportedFields(elem) {
191198
field := elem.FieldByName(t.Name)

server/cmd/parameter.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
package cmd
22

33
import (
4-
"github.com/go-gl/mathgl/mgl64"
54
"reflect"
65
"strings"
6+
7+
"github.com/go-gl/mathgl/mgl64"
78
)
89

910
// Parameter is an interface for a generic parameters. Users may have types as command parameters that
@@ -39,6 +40,12 @@ type Enum interface {
3940
Options(source Source) []string
4041
}
4142

43+
// ParamDescriber may be implemented by a Runnable to programmatically describe its parameters
44+
// without relying on struct field reflection.
45+
type ParamDescriber interface {
46+
DescribeParams(src Source) []ParamInfo
47+
}
48+
4249
// SubCommand represents a subcommand that may be added as a static value that must be written. Adding
4350
// multiple Runnable implementations to the command in New with different SubCommand fields as the
4451
// first parameter allows for commands with subcommands.

0 commit comments

Comments
 (0)