diff --git a/bittorrent/bittorrent.go b/bittorrent/bittorrent.go index cd0bd2a..24e71f0 100644 --- a/bittorrent/bittorrent.go +++ b/bittorrent/bittorrent.go @@ -4,6 +4,7 @@ package bittorrent import ( + "fmt" "net" "time" @@ -26,7 +27,13 @@ func PeerIDFromBytes(b []byte) PeerID { return PeerID(buf) } +// String implements fmt.Stringer, returning the base16 encoded PeerID. func (p PeerID) String() string { + return fmt.Sprintf("%x", p[:]) +} + +// RawString returns a 20-byte string of the raw bytes of the ID. +func (p PeerID) RawString() string { return string(p[:]) } @@ -72,7 +79,13 @@ func InfoHashFromString(s string) InfoHash { return InfoHash(buf) } +// String implements fmt.Stringer, returning the base16 encoded InfoHash. func (i InfoHash) String() string { + return fmt.Sprintf("%x", i[:]) +} + +// RawString returns a 20-byte string of the raw bytes of the InfoHash. +func (i InfoHash) RawString() string { return string(i[:]) } @@ -212,6 +225,22 @@ type Peer struct { Port uint16 } +// String implements fmt.Stringer to return a human-readable representation. +// The string will have the format @[]:, for example +// "0102030405060708090a0b0c0d0e0f1011121314@[10.11.12.13]:1234" +func (p Peer) String() string { + return fmt.Sprintf("%s@[%s]:%d", p.ID.String(), p.IP.String(), p.Port) +} + +// LogFields renders the current peer as a set of Logrus fields. +func (p Peer) LogFields() log.Fields { + return log.Fields{ + "ID": p.ID, + "IP": p.IP, + "port": p.Port, + } +} + // Equal reports whether p and x are the same. func (p Peer) Equal(x Peer) bool { return p.EqualEndpoint(x) && p.ID == x.ID } diff --git a/bittorrent/bittorrent_test.go b/bittorrent/bittorrent_test.go new file mode 100644 index 0000000..c69d299 --- /dev/null +++ b/bittorrent/bittorrent_test.go @@ -0,0 +1,59 @@ +package bittorrent + +import ( + "fmt" + "net" + "testing" + + "github.com/stretchr/testify/require" +) + +var ( + b = []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20} + expected = "0102030405060708090a0b0c0d0e0f1011121314" +) + +var peerStringTestCases = []struct { + input Peer + expected string +}{ + { + input: Peer{ + ID: PeerIDFromBytes(b), + IP: IP{ + IP: net.IPv4(10, 11, 12, 1), + AddressFamily: IPv4, + }, + Port: 1234, + }, + expected: fmt.Sprintf("%s@[10.11.12.1]:1234", expected), + }, + { + input: Peer{ + ID: PeerIDFromBytes(b), + IP: IP{ + IP: net.ParseIP("2001:db8::ff00:42:8329"), + AddressFamily: IPv6, + }, + Port: 1234, + }, + expected: fmt.Sprintf("%s@[2001:db8::ff00:42:8329]:1234", expected), + }, +} + +func TestPeerID_String(t *testing.T) { + s := PeerIDFromBytes(b).String() + require.Equal(t, expected, s) +} + +func TestInfoHash_String(t *testing.T) { + s := InfoHashFromBytes(b).String() + require.Equal(t, expected, s) +} + +func TestPeer_String(t *testing.T) { + for _, c := range peerStringTestCases { + got := c.input.String() + require.Equal(t, c.expected, got) + } +}