Integrate soap.Action type with soap/client.
This commit is contained in:
		@@ -81,7 +81,7 @@ func run() error {
 | 
			
		||||
	// as well as necessary for extended types.
 | 
			
		||||
	typeMap := types.TypeMap().Clone()
 | 
			
		||||
	typeMap[soapActionInterface] = typedesc.TypeDesc{
 | 
			
		||||
		GoType: reflect.TypeOf((*soap.SOAPAction)(nil)).Elem(),
 | 
			
		||||
		GoType: reflect.TypeOf((*soap.Action)(nil)).Elem(),
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	for _, m := range manifests.DCPS {
 | 
			
		||||
 
 | 
			
		||||
@@ -9,6 +9,7 @@ import (
 | 
			
		||||
	"io"
 | 
			
		||||
	"net/http"
 | 
			
		||||
 | 
			
		||||
	"github.com/huin/goupnp/v2alpha/soap"
 | 
			
		||||
	"github.com/huin/goupnp/v2alpha/soap/envelope"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
@@ -85,19 +86,17 @@ func (c *Client) Do(
 | 
			
		||||
	return ParseResponseAction(resp, actionOut)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// PerformAction makes a SOAP request, with the given `argsIn` as input
 | 
			
		||||
// arguments, and `argsOut` to capture the output arguments into.
 | 
			
		||||
// `serviceType` is the SOAP service type URN, `actionName` is the action to
 | 
			
		||||
// call.
 | 
			
		||||
// PerformAction makes a SOAP request, with the given action.
 | 
			
		||||
//
 | 
			
		||||
// This is a convenience for calling `Client.Do` without creating `*Action` values.
 | 
			
		||||
// This is a convenience for calling `Client.Do` without creating
 | 
			
		||||
// `*envelope.Action` values.
 | 
			
		||||
func PerformAction(
 | 
			
		||||
	ctx context.Context, c *Client,
 | 
			
		||||
	serviceType, actionName string,
 | 
			
		||||
	argsIn, argsOut any,
 | 
			
		||||
	action soap.Action,
 | 
			
		||||
) error {
 | 
			
		||||
	actionIn := envelope.NewSendAction(serviceType, actionName, argsIn)
 | 
			
		||||
	actionOut := &envelope.Action{Args: argsOut}
 | 
			
		||||
	actionIn := envelope.NewSendAction(
 | 
			
		||||
		action.ServiceType(), action.ActionName(), action.RefRequest())
 | 
			
		||||
	actionOut := &envelope.Action{Args: action.RefResponse()}
 | 
			
		||||
	return c.Do(ctx, actionIn, actionOut)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -8,9 +8,25 @@ import (
 | 
			
		||||
	"testing"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/huin/goupnp/v2alpha/soap"
 | 
			
		||||
	"github.com/huin/goupnp/v2alpha/soap/envelope"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const serviceType = "fake:service:type"
 | 
			
		||||
const actionName = "ActionName"
 | 
			
		||||
 | 
			
		||||
type Action struct {
 | 
			
		||||
	req  ActionArgs
 | 
			
		||||
	resp ActionReply
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var _ soap.Action = &Action{}
 | 
			
		||||
 | 
			
		||||
func (a *Action) ServiceType() string { return serviceType }
 | 
			
		||||
func (a *Action) ActionName() string  { return actionName }
 | 
			
		||||
func (a *Action) RefRequest() any     { return &a.req }
 | 
			
		||||
func (a *Action) RefResponse() any    { return &a.resp }
 | 
			
		||||
 | 
			
		||||
type ActionArgs struct {
 | 
			
		||||
	Name string
 | 
			
		||||
}
 | 
			
		||||
@@ -81,7 +97,7 @@ func TestPerformAction(t *testing.T) {
 | 
			
		||||
 | 
			
		||||
	service := &fakeSoapServer{
 | 
			
		||||
		responses: map[actionKey]*envelope.Action{
 | 
			
		||||
			{"/endpointpath", "\"http://example.com/endpointns#Foo\""}: {
 | 
			
		||||
			{"/endpointpath", fmt.Sprintf("\"%s#%s\"", serviceType, actionName)}: {
 | 
			
		||||
				Args: &ActionReply{Greeting: "Hello, World!"},
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
@@ -91,13 +107,14 @@ func TestPerformAction(t *testing.T) {
 | 
			
		||||
 | 
			
		||||
	c := New(ts.URL + "/endpointpath")
 | 
			
		||||
 | 
			
		||||
	reply := &ActionReply{}
 | 
			
		||||
	a := &Action{
 | 
			
		||||
		req: ActionArgs{Name: "World"},
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := PerformAction(ctx, c, "http://example.com/endpointns", "Foo",
 | 
			
		||||
		&ActionArgs{Name: "World"}, reply); err != nil {
 | 
			
		||||
	if err := PerformAction(ctx, c, a); err != nil {
 | 
			
		||||
		t.Errorf("got error: %v, want success", err)
 | 
			
		||||
	} else {
 | 
			
		||||
		if got, want := reply.Greeting, "Hello, World!"; got != want {
 | 
			
		||||
		if got, want := a.resp.Greeting, "Hello, World!"; got != want {
 | 
			
		||||
			t.Errorf("got %q, want %q", got, want)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,9 @@
 | 
			
		||||
// Package soap defines basic types used by SOAP packages.
 | 
			
		||||
package soap
 | 
			
		||||
 | 
			
		||||
// SOAPAction defines the interface for the convenience self-describing action request/response
 | 
			
		||||
// Action defines the interface for the convenience self-describing action request/response
 | 
			
		||||
// struct types.
 | 
			
		||||
type SOAPAction interface {
 | 
			
		||||
type Action interface {
 | 
			
		||||
	// ServiceType returns Service type, e.g. "urn:schemas-upnp-org:service:Foo:1".
 | 
			
		||||
	ServiceType() string
 | 
			
		||||
	// ActionName returns Action name, e.g. "SetBar".
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user