# HG changeset patch # User Chris Jones # Date 1355722613 25200 # Node ID 36287f2cf06e594832f7de3c6dd81dd7bbf89b18 # Parent 7696e6a017090fdee3a4269fc0871ef68cf07101 Step 1 of moving to interface Stanza and embedded struct Header. diff -r 7696e6a01709 -r 36287f2cf06e roster.go --- a/roster.go Sun Dec 16 22:17:49 2012 -0700 +++ b/roster.go Sun Dec 16 22:36:53 2012 -0700 @@ -48,7 +48,7 @@ func fetchRoster(client *Client) error { rosterUpdate := rosterClients[client.Uid].rosterUpdate - iq := &Iq{Stanza: Stanza{From: client.Jid.String(), Type: "get", + iq := &Iq{Header: Header{From: client.Jid.String(), Type: "get", Id: <-Id, Nested: []interface{}{RosterQuery{}}}} ch := make(chan error) f := func(v interface{}) bool { @@ -128,7 +128,7 @@ rosterUpdate <- item } // Send a reply. - reply := &Iq{Stanza: Stanza{To: iq.From, Id: iq.Id, + reply := &Iq{Header: Header{To: iq.From, Id: iq.Id, Type: "result"}} client.Out <- reply } diff -r 7696e6a01709 -r 36287f2cf06e roster_test.go --- a/roster_test.go Sun Dec 16 22:17:49 2012 -0700 +++ b/roster_test.go Sun Dec 16 22:36:53 2012 -0700 @@ -13,7 +13,7 @@ // This is mostly just tests of the roster data structures. func TestRosterIqMarshal(t *testing.T) { - iq := &Iq{Stanza: Stanza{From: "from", Lang: "en", + iq := &Iq{Header: Header{From: "from", Lang: "en", Nested: []interface{}{RosterQuery{}}}} exp := `` @@ -26,7 +26,7 @@ iq := Iq{} xml.Unmarshal([]byte(str), &iq) m := map[string]func(*xml.Name) interface{}{NsRoster: newRosterQuery} - err := parseExtended(&iq.Stanza, m) + err := parseExtended(&iq.Header, m) if err != nil { t.Fatalf("parseExtended: %v", err) } diff -r 7696e6a01709 -r 36287f2cf06e stream.go --- a/stream.go Sun Dec 16 22:17:49 2012 -0700 +++ b/stream.go Sun Dec 16 22:36:53 2012 -0700 @@ -148,8 +148,8 @@ // If it's a Stanza, we try to unmarshal its innerxml // into objects of the appropriate respective // types. This is specified by our extensions. - if st := getStanza(obj) ; st != nil { - err = parseExtended(st, extStanza) + if st, ok := obj.(Stanzer) ; ok { + err = parseExtended(st.GetHeader(), extStanza) if err != nil { Warn.Logf("ext unmarshal: %s", err) break Loop @@ -161,7 +161,7 @@ } } -func parseExtended(st *Stanza, extStanza map[string]func(*xml.Name) interface{}) error { +func parseExtended(st *Header, extStanza map[string]func(*xml.Name) interface{}) error { // Now parse the stanza's innerxml to find the string that we // can unmarshal this nested element from. reader := strings.NewReader(st.Innerxml) @@ -238,7 +238,7 @@ if !ok { break Loop } - var st *Stanza + var st *Header switch obj := x.(type) { case *stream: handleStream(obj) @@ -250,8 +250,8 @@ cl.handleTls(obj) case *auth: cl.handleSasl(obj) - case *Iq, *Message, *Presence: - st = getStanza(obj) + case Stanzer: + st = obj.GetHeader() default: Warn.Logf("Unhandled non-stanza: %T %#v", x, x) } @@ -596,7 +596,7 @@ if res != "" { bindReq.Resource = &res } - msg := &Iq{Stanza: Stanza{Type: "set", Id: <-Id, + msg := &Iq{Header: Header{Type: "set", Id: <-Id, Nested: []interface{}{bindReq}}} f := func(st interface{}) bool { iq, ok := st.(*Iq) diff -r 7696e6a01709 -r 36287f2cf06e structs.go --- a/structs.go Sun Dec 16 22:17:49 2012 -0700 +++ b/structs.go Sun Dec 16 22:36:53 2012 -0700 @@ -77,9 +77,13 @@ Any *Generic } +type Stanzer interface { + GetHeader() *Header +} + // One of the three core XMPP stanza types: iq, message, presence. See // RFC3920, section 9. -type Stanza struct { +type Header struct { To string `xml:"to,attr,omitempty"` From string `xml:"from,attr,omitempty"` Id string `xml:"id,attr,omitempty"` @@ -93,26 +97,29 @@ // message stanza type Message struct { XMLName xml.Name `xml:"message"` - Stanza + Header Subject *Generic `xml:"subject"` Body *Generic `xml:"body"` Thread *Generic `xml:"thread"` } +var _ Stanzer = &Message{} // presence stanza type Presence struct { XMLName xml.Name `xml:"presence"` - Stanza + Header Show *Generic `xml:"show"` Status *Generic `xml:"status"` Priority *Generic `xml:"priority"` } +var _ Stanzer = &Presence{} // iq stanza type Iq struct { XMLName xml.Name `xml:"iq"` - Stanza + Header } +var _ Stanzer = &Iq{} // Describes an XMPP stanza error. See RFC 3920, Section 9.3. type Error struct { @@ -222,6 +229,18 @@ return s, nil } +func (iq *Iq) GetHeader() *Header { + return &iq.Header +} + +func (m *Message) GetHeader() *Header { + return &m.Header +} + +func (p *Presence) GetHeader() *Header { + return &p.Header +} + func (u *Generic) String() string { if u == nil { return "nil" @@ -250,15 +269,3 @@ func newBind(name *xml.Name) interface{} { return &bindIq{} } - -func getStanza(v interface{}) *Stanza { - switch s := v.(type) { - case *Iq: - return &s.Stanza - case *Message: - return &s.Stanza - case *Presence: - return &s.Stanza - } - return nil -} diff -r 7696e6a01709 -r 36287f2cf06e structs_test.go --- a/structs_test.go Sun Dec 16 22:17:49 2012 -0700 +++ b/structs_test.go Sun Dec 16 22:36:53 2012 -0700 @@ -89,7 +89,7 @@ } func TestIqMarshal(t *testing.T) { - iq := &Iq{Stanza: Stanza{Type: "set", Id: "3", + iq := &Iq{Header: Header{Type: "set", Id: "3", Nested: []interface{}{Generic{XMLName: xml.Name{Space: NsBind, Local: "bind"}}}}} exp := `