~samwhited/xmpp

ad75c29d6d7fbf723f20b83b435b35572e5ef20e — Sam Whited 5 years ago 3f1c969
Start stubbing out IQ sending methods
3 files changed, 101 insertions(+), 13 deletions(-)

M iq.go
A iq_test.go
A iqtype_string.go
M iq.go => iq.go +55 -13
@@ 5,32 5,74 @@
package xmpp

import (
	"context"
	"encoding/xml"

	"mellium.im/xmpp/jid"
)

// IQ ("Information Query") is used as a general request response mechanism.
// IQ's are one-to-one, provide get and set semantics, and always require a
// response in the form of a result or an error.
type IQ struct {
	stanza

	XMLName xml.Name `xml:"iq"`
	From     *jid.JID `xml:"from,attr"`
	ID       string   `xml:"id,attr"`
	InnerXML []byte   `xml:",innerxml"`
	Lang     string   `xml:"http://www.w3.org/XML/1998/namespace lang,attr,omitempty"`
	To       *jid.JID `xml:"to,attr"`
	Type     iqType   `xml:"type,attr"`
	XMLName  xml.Name `xml:"iq"`
}

type iqType int

const (
	// A GetIQ is used to query another entity for information.
	GetIQ iqType = iota
	// A Get IQ is used to query another entity for information.
	Get iqType = iota

	// A SetIQ is used to provide data to another entity, set new values, replace
	// existing values, and other such operations.
	SetIQ
	// A Set IQ is used to provide data to another entity, set new values, and
	// replace existing values.
	Set

	// A ResultIQ is sent in response to a successful GetIQ or SetIQ stanza.
	ResultIQ
	// A Result IQ is sent in response to a successful get or set IQ.
	Result

	// An ErrorIQ is sent to report that an error occured during the delivery or
	// processing of a GetIQ or SetIQ.
	ErrorIQ
	// An Error IQ is sent to report that an error occured during the delivery or
	// processing of a get or set IQ.
	Error
)

func (t iqType) MarshalXMLAttr(name xml.Name) (xml.Attr, error) {
	return xml.Attr{Name: name, Value: t.String()}, nil
}

// TODO: Should this be variadic and accept many payloads or many to's?
func (c *Conn) sendIQ(ctx context.Context, to *jid.JID, t iqType, v interface{}) (*IQ, error) {
	panic("xmpp: sendIQ not yet implemented")
}

// Do sends an IQ request and blocks until an IQ response is received. If the
// provided context expires before a response is received, the function unblocks
// and an error is returned. An error is only returned on timeouts or connection
// errors, error resonses to the IQ are expected and returned as normal IQ
// responses (err will still be nil).
//
// If the IQ is not of type Get or Set, panic.
func (c *Conn) Do(ctx context.Context, iq IQ) (resp *IQ, err error) {
	if iq.Type != Get && iq.Type != Set {
		panic("xmpp: Attempted to send non-response IQ with invalid type.")
	}
	return c.sendIQ(ctx, nil, iq.Type, iq)
}

// Set marshals the provided data to XML and then sends it as the payload of a
// "set" IQ stanza. For more information, see the Do function.
func (c *Conn) Set(ctx context.Context, to *jid.JID, payload interface{}) (resp *IQ, err error) {
	return c.sendIQ(ctx, to, Set, payload)
}

// Get marshals the provided data to XML and then sends it as the payload of a
// "get" IQ stanza. For more information see the Do function.
func (c *Conn) Get(ctx context.Context, to *jid.JID, payload interface{}) (resp *IQ, err error) {
	return c.sendIQ(ctx, to, Get, payload)
}

A iq_test.go => iq_test.go +30 -0
@@ 0,0 1,30 @@
// Copyright 2016 Sam Whited.
// Use of this source code is governed by the BSD 2-clause license that can be
// found in the LICENSE file.

package xmpp

import (
	"encoding/xml"
	"testing"
)

func TestMarshalIQTypeAttr(t *testing.T) {
	n := xml.Name{Space: "space", Local: "type"}
	for _, test := range []struct {
		iqtype iqType
		value  string
	}{{Get, "get"}, {Set, "set"}, {Result, "result"}, {Error, "error"}} {
		attr, err := test.iqtype.MarshalXMLAttr(n)
		if err != nil {
			t.Error(err)
			continue
		}
		if attr.Name != n {
			t.Errorf("Got wrong attribute name for IQ type %s. Got %v, want %v", test.value, attr.Name, n)
		}
		if attr.Value != test.value {
			t.Errorf("Got wrong attribute value for IQ type %s: `%s`", test.value, attr.Value)
		}
	}
}

A iqtype_string.go => iqtype_string.go +16 -0
@@ 0,0 1,16 @@
// Code generated by "stringer -type=iqType"; DO NOT EDIT

package xmpp

import "fmt"

const _iqType_name = "getsetresulterror"

var _iqType_index = [...]uint8{0, 3, 6, 12, 17}

func (i iqType) String() string {
	if i < 0 || i >= iqType(len(_iqType_index)-1) {
		return fmt.Sprintf("iqType(%d)", i)
	}
	return _iqType_name[_iqType_index[i]:_iqType_index[i+1]]
}