Add action container structs with descriptor methods.

This commit is contained in:
John Beisley 2022-06-08 17:51:47 +01:00
parent 0536e2c588
commit 91c176e495
4 changed files with 57 additions and 10 deletions

View File

@ -7,6 +7,7 @@ import (
"fmt" "fmt"
"os" "os"
"path/filepath" "path/filepath"
"reflect"
"sort" "sort"
"strconv" "strconv"
"strings" "strings"
@ -17,6 +18,7 @@ import (
"github.com/huin/goupnp/v2alpha/description/srvdesc" "github.com/huin/goupnp/v2alpha/description/srvdesc"
"github.com/huin/goupnp/v2alpha/description/typedesc" "github.com/huin/goupnp/v2alpha/description/typedesc"
"github.com/huin/goupnp/v2alpha/description/xmlsrvdesc" "github.com/huin/goupnp/v2alpha/description/xmlsrvdesc"
"github.com/huin/goupnp/v2alpha/soap"
"github.com/huin/goupnp/v2alpha/soap/types" "github.com/huin/goupnp/v2alpha/soap/types"
) )
@ -25,6 +27,8 @@ var (
upnpresourcesZip = flag.String("upnpresources_zip", "", "Path to upnpresources.zip.") upnpresourcesZip = flag.String("upnpresources_zip", "", "Path to upnpresources.zip.")
) )
const soapActionInterface = "SOAPActionInterface"
func main() { func main() {
flag.Parse() flag.Parse()
if err := run(); err != nil { if err := run(); err != nil {
@ -63,7 +67,10 @@ func run() error {
// Use default type map for now. Addtional types could be use instead or // Use default type map for now. Addtional types could be use instead or
// as well as necessary for extended types. // as well as necessary for extended types.
typeMap := types.TypeMap() typeMap := types.TypeMap().Clone()
typeMap[soapActionInterface] = typedesc.TypeDesc{
GoType: reflect.TypeOf((*soap.SOAPAction)(nil)).Elem(),
}
for _, m := range manifests { for _, m := range manifests {
if err := processDCP(upnpresources, m, typeMap, tmpl); err != nil { if err := processDCP(upnpresources, m, typeMap, tmpl); err != nil {
@ -78,14 +85,14 @@ var manifests = []*DCPSpecManifest{
Path: "standardizeddcps/Internet Gateway_2/UPnP-gw-IGD-TestFiles-20101210.zip", Path: "standardizeddcps/Internet Gateway_2/UPnP-gw-IGD-TestFiles-20101210.zip",
Services: []*ServiceManifest{ Services: []*ServiceManifest{
{ {
Package: "lanhostconfigmanagement1", Package: "lanhostconfigmanagement1",
Type: "urn:schemas-upnp-org:service:LANHostConfigManagement:1", ServiceType: "urn:schemas-upnp-org:service:LANHostConfigManagement:1",
Path: "xml data files/service/LANHostConfigManagement1.xml", Path: "xml data files/service/LANHostConfigManagement1.xml",
}, },
{ {
Package: "wanpppconnection1", Package: "wanpppconnection1",
Type: "urn:schemas-upnp-org:service:WANPPPConnection:1", ServiceType: "urn:schemas-upnp-org:service:WANPPPConnection:1",
Path: "xml data files/service/WANPPPConnection1.xml", Path: "xml data files/service/WANPPPConnection1.xml",
}, },
}, },
}, },
@ -103,7 +110,7 @@ func processDCP(
} }
for _, srvManifest := range manifest.Services { for _, srvManifest := range manifest.Services {
if err := processService(dcpSpecData, srvManifest, typeMap, tmpl); err != nil { if err := processService(dcpSpecData, srvManifest, typeMap, tmpl); err != nil {
return fmt.Errorf("processing service %s: %w", srvManifest.Type, err) return fmt.Errorf("processing service %s: %w", srvManifest.ServiceType, err)
} }
} }
return nil return nil
@ -162,9 +169,9 @@ type DCPSpecManifest struct {
type ServiceManifest struct { type ServiceManifest struct {
// Package is the Go package name to generate e.g. "foo1". // Package is the Go package name to generate e.g. "foo1".
Package string Package string
// Type is the SOAP namespace and service type that identifes the service e.g. // ServiceType is the SOAP namespace and service type that identifes the service e.g.
// "urn:schemas-upnp-org:service:Foo:1" // "urn:schemas-upnp-org:service:Foo:1"
Type string ServiceType string
// Path within the DCP spec ZIP file e.g. "xml data files/service/Foo1.xml". // Path within the DCP spec ZIP file e.g. "xml data files/service/Foo1.xml".
Path string Path string
} }
@ -189,6 +196,8 @@ type importItem struct {
func accumulateImports(srvDesc *srvdesc.SCPD, typeMap typedesc.TypeMap) (*imports, error) { func accumulateImports(srvDesc *srvdesc.SCPD, typeMap typedesc.TypeMap) (*imports, error) {
typeNames := make(map[string]bool) typeNames := make(map[string]bool)
typeNames[soapActionInterface] = true
err := visitTypesSCPD(srvDesc, func(typeName string) { err := visitTypesSCPD(srvDesc, func(typeName string) {
typeNames[typeName] = true typeNames[typeName] = true
}) })

View File

@ -7,3 +7,11 @@ type TypeDesc struct {
} }
type TypeMap map[string]TypeDesc type TypeMap map[string]TypeDesc
func (tm TypeMap) Clone() TypeMap {
r := make(TypeMap, len(tm))
for k, v := range tm {
r[k] = v
}
return r
}

15
v2alpha/soap/soap.go Normal file
View File

@ -0,0 +1,15 @@
// Package soap defines basic types used by SOAP packages.
package soap
// SOAPAction defines the interface for the convenience self-describing action request/response
// struct types.
type SOAPAction interface {
// ServiceType returns Service type, e.g. "urn:schemas-upnp-org:service:Foo:1".
ServiceType() string
// ActionName returns Action name, e.g. "SetBar".
ActionName() string
// RefRequest returns reference to the action request member.
RefRequest() any
// RefResponse returns reference to the action response member.
RefResponse() any
}

View File

@ -7,6 +7,9 @@ import (
{{.Alias}} {{quote .Path}} {{.Alias}} {{quote .Path}}
{{- end}} {{- end}}
) )
const ServiceType = {{quote .Manifest.ServiceType}}
{{range .SCPD.SortedActions}} {{range .SCPD.SortedActions}}
{{- template "action" args "Action" . "Imps" $Imps}} {{- template "action" args "Action" . "Imps" $Imps}}
{{end}} {{end}}
@ -14,6 +17,18 @@ import (
{{define "action"}} {{define "action"}}
{{- $Imps := .Imps}} {{- $Imps := .Imps}}
type {{.Action.Name}} struct{
Request {{.Action.Name}}Request
Response {{.Action.Name}}Response
}
var _ {{index $Imps.TypeRefByTypeName "SOAPActionInterface"}} = &{{.Action.Name}}{{"{}"}}
func (a *{{.Action.Name}}) ServiceType() string { return ServiceType }
func (a *{{.Action.Name}}) ActionName() string { return {{quote .Action.Name}} }
func (a *{{.Action.Name}}) RefRequest() any { return &a.Request }
func (a *{{.Action.Name}}) RefResponse() any { return &a.Response }
type {{.Action.Name}}Request struct type {{.Action.Name}}Request struct
{{- template "args" args "Args" .Action.InArgs "Imps" $Imps}} {{- template "args" args "Args" .Action.InArgs "Imps" $Imps}}