Implement custom verbs for fmt.Printf use

The dns package implements String() for all RR types, but sometimes you will
need more flexibility. The functions Printf, Sprintf, etc. implemented formatted I/O
for the RR type.

Printing

The verbs:

Generic part of RRs:

     %N	the owner name of the RR
     %C	the class: IN, CH, CLASS15, etc.
     %D	the TTL in seconds
     %Y	the type: MX, A, etc.

The rdata of each RR differs, we allow each field to be printed as a string.

Rdata:

     %0	the first rdata field
     %1	the second rdata field
     %2	the third rdata field
     ..	...
     %9      the nineth rdata field
     %R	all rdata fields

The rdata fields remain a TODO, but will be implemented using
reflection.
This commit is contained in:
Miek Gieben 2015-01-11 17:23:02 +00:00
parent a07be6b2c1
commit aaa3aba4ed
2 changed files with 36 additions and 13 deletions

5
dns.go
View File

@ -94,6 +94,7 @@
package dns
import (
"fmt"
"strconv"
)
@ -122,9 +123,11 @@ type RR interface {
Header() *RR_Header
// String returns the text representation of the resource record.
String() string
// Formatted output
Format(f fmt.State, c rune)
// copy returns a copy of the RR
copy() RR
// len returns the length (in octects) of the uncompressed RR in wire format.
// len returns the length (in octets) of the uncompressed RR in wire format.
len() int
}

View File

@ -1286,54 +1286,74 @@ func TestNewRRSpecial(t *testing.T) {
rr, err = NewRR("; comment")
expect = ""
if err != nil {
t.Errorf("unexpect err: %s", err)
t.Errorf("unexpected err: %s", err)
}
if rr != nil {
t.Errorf("unexpect result: [%s] != [%s]", rr, expect)
t.Errorf("unexpected result: [%s] != [%s]", rr, expect)
}
rr, err = NewRR("")
expect = ""
if err != nil {
t.Errorf("unexpect err: %s", err)
t.Errorf("unexpected err: %s", err)
}
if rr != nil {
t.Errorf("unexpect result: [%s] != [%s]", rr, expect)
t.Errorf("unexpected result: [%s] != [%s]", rr, expect)
}
rr, err = NewRR("$ORIGIN foo.")
expect = ""
if err != nil {
t.Errorf("unexpect err: %s", err)
t.Errorf("unexpected err: %s", err)
}
if rr != nil {
t.Errorf("unexpect result: [%s] != [%s]", rr, expect)
t.Errorf("unexpected result: [%s] != [%s]", rr, expect)
}
rr, err = NewRR(" ")
expect = ""
if err != nil {
t.Errorf("unexpect err: %s", err)
t.Errorf("unexpected err: %s", err)
}
if rr != nil {
t.Errorf("unexpect result: [%s] != [%s]", rr, expect)
t.Errorf("unexpected result: [%s] != [%s]", rr, expect)
}
rr, err = NewRR("\n")
expect = ""
if err != nil {
t.Errorf("unexpect err: %s", err)
t.Errorf("unexpected err: %s", err)
}
if rr != nil {
t.Errorf("unexpect result: [%s] != [%s]", rr, expect)
t.Errorf("unexpected result: [%s] != [%s]", rr, expect)
}
rr, err = NewRR("foo. A 1.1.1.1\nbar. A 2.2.2.2")
expect = "foo.\t3600\tIN\tA\t1.1.1.1"
if err != nil {
t.Errorf("unexpect err: %s", err)
t.Errorf("unexpected err: %s", err)
}
if rr == nil || rr.String() != expect {
t.Errorf("unexpect result: [%s] != [%s]", rr, expect)
t.Errorf("unexpected result: [%s] != [%s]", rr, expect)
}
}
func TestPrintfVerbs(t *testing.T) {
x, _ := NewRR("www.miek.nl. IN A 127.0.0.1")
if fmt.Sprintf("%N", x) != "www.miek.nl." {
t.Errorf("%N does return name")
}
if fmt.Sprintf("%C", x) != "IN" {
t.Errorf("%C does return class")
}
if fmt.Sprintf("%D", x) != "3600" {
t.Errorf("%D does return ttl")
}
if fmt.Sprintf("%Y", x) != "A" {
t.Errorf("%Y does return type")
}
if fmt.Sprintf("%Y %d", x, 5) != "A 5" {
t.Errorf("%N does return name")
}
// TODO(miek): RDATA
}