Documentation
¶
Index ¶
Examples ¶
- Join (IdnaHost)
- Join (NonAsciiHost)
- Join (NonAsciiPath)
- Join (OnlyHost)
- Join (WithPath)
- Join (WithSubDomain)
- PaymentPointer.Parse (IdnaHost)
- PaymentPointer.Parse (NonAsciiHost)
- PaymentPointer.Parse (NonAsciiPath)
- PaymentPointer.Parse (OnlyHost)
- PaymentPointer.Parse (WithPath)
- PaymentPointer.Parse (WithSubDomain)
- PaymentPointer.Pretty (IdnaHost)
- PaymentPointer.Pretty (NonAsciiHost)
- PaymentPointer.Pretty (NonAsciiPath)
- PaymentPointer.Pretty (OnlyHost)
- PaymentPointer.Pretty (WithPath)
- PaymentPointer.Pretty (WithSubDomain)
- PaymentPointer.Resolve (IdnaHost)
- PaymentPointer.Resolve (NonAsciiHost)
- PaymentPointer.Resolve (NonAsciiPath)
- PaymentPointer.Resolve (OnlyHost)
- PaymentPointer.Resolve (WithPath)
- PaymentPointer.Resolve (WithSubDomain)
- PaymentPointer.String (IdnaHost)
- PaymentPointer.String (NonAsciiHost)
- PaymentPointer.String (NonAsciiPath)
- PaymentPointer.String (OnlyHost)
- PaymentPointer.String (WithPath)
- PaymentPointer.String (WithSubDomain)
- Pretty (IdnaHost)
- Pretty (NonAsciiHost)
- Pretty (NonAsciiPath)
- Pretty (OnlyHost)
- Pretty (WithPath)
- Pretty (WithSubDomain)
- Resolve (IdnaHost)
- Resolve (NonAsciiHost)
- Resolve (NonAsciiPath)
- Resolve (OnlyHost)
- Resolve (WithPath)
- Resolve (WithSubDomain)
- Sanitize (AlreadyEncoded)
- Sanitize (JustHost)
- Sanitize (NonAscii)
- Sanitize (UpperCaseHost)
- Sanitize (WellKnown)
- Split (IdnaHost)
- Split (NonAsciiHost)
- Split (NonAsciiPath)
- Split (OnlyHost)
- Split (WithPath)
- Split (WithSubDomain)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Join ¶
Join returns the payment-pointer.
An example payment-pointer looks like these:
$example.com $joeblow.example.com $example.com/joeblow $xn--938h.com/%DB%B1/%DB%B2/%DB%B3/%DB%B4/%DB%B5
Note that what Join returns is in ASCII.
A host with non-ASCII characters is encoded into ASCII using punycode.
A path with non-ASCII character is encoded into ASCII using urlencode.
Example (IdnaHost) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var host string = "xn--m28h.com"
var path string = ""
str := pymtptr.Join(host, path)
fmt.Println(str)
}
Output: $xn--m28h.com
Example (NonAsciiHost) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var host string = "😈.com"
var path string = ""
str := pymtptr.Join(host, path)
fmt.Println(str)
}
Output: $xn--m28h.com
Example (NonAsciiPath) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var host string = "example.com"
var path string = "/۱/۲/۳/۴/۵"
str := pymtptr.Join(host, path)
fmt.Println(str)
}
Output: $example.com/%DB%B1/%DB%B2/%DB%B3/%DB%B4/%DB%B5
Example (OnlyHost) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var host string = "example.com"
var path string = ""
str := pymtptr.Join(host, path)
fmt.Println(str)
}
Output: $example.com
Example (WithPath) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var host string = "example.com"
var path string = "/joeblow"
str := pymtptr.Join(host, path)
fmt.Println(str)
}
Output: $example.com/joeblow
Example (WithSubDomain) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var host string = "joeblow.example.com"
var path string = ""
str := pymtptr.Join(host, path)
fmt.Println(str)
}
Output: $joeblow.example.com
func Pretty ¶
Pretty returns the "pretty" version of a payment-pointer.
NOTE that the the "pretty" version of a payment-pointer might NOT be a valid payment-pointer!
What pretty returns is meant to be a more human-legible form meant for displaying to people (and is NOT mean to be consumed by machines).
Some example "pretty" payment-pointer are:
$example.com $joeblow.example.com $example.com/joeblow $🙂.com/۱/۲/۳/۴/۵
Note that the last example of a "pretty" version of a payment-pointer (i.e., "$🙂.com/۱/۲/۳/۴/۵") is NOT a valid payment-pointer!
Example (IdnaHost) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var paymentPointer string = "$xn--m28h.com"
pretty := pymtptr.Pretty(paymentPointer)
fmt.Println(pretty)
}
Output: $😈.com
Example (NonAsciiHost) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var paymentPointer string = "$😈.com"
pretty := pymtptr.Pretty(paymentPointer)
fmt.Println(pretty)
}
Output: $😈.com
Example (NonAsciiPath) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var paymentPointer string = "$example.com/۱/۲/۳/۴/۵"
pretty := pymtptr.Pretty(paymentPointer)
fmt.Println(pretty)
}
Output: $example.com/۱/۲/۳/۴/۵
Example (OnlyHost) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var paymentPointer string = "$example.com"
pretty := pymtptr.Pretty(paymentPointer)
fmt.Println(pretty)
}
Output: $example.com
Example (WithPath) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var paymentPointer string = "$example.com/joeblow"
pretty := pymtptr.Pretty(paymentPointer)
fmt.Println(pretty)
}
Output: $example.com/joeblow
Example (WithSubDomain) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var paymentPointer string = "$joeblow.example.com"
pretty := pymtptr.Pretty(paymentPointer)
fmt.Println(pretty)
}
Output: $joeblow.example.com
func Resolve ¶
Resolve resolves a Payment-Pointer to an HTTP URL.
If the Payment-Pointer is NOT a valid the Resolve returns an empty string.
Example (IdnaHost) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
paymentPointer := "$xn--m28h.com"
url := pymtptr.Resolve(paymentPointer)
fmt.Println(url)
}
Output: https://xn--m28h.com/.well-known/pay
Example (NonAsciiHost) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
paymentPointer := "$😈.com"
url := pymtptr.Resolve(paymentPointer)
fmt.Println(url)
}
Output: https://xn--m28h.com/.well-known/pay
Example (NonAsciiPath) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
paymentPointer := "$example.com/۱/۲/۳/۴/۵"
url := pymtptr.Resolve(paymentPointer)
fmt.Println(url)
}
Output: https://example.com/%DB%B1/%DB%B2/%DB%B3/%DB%B4/%DB%B5
Example (OnlyHost) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
paymentPointer := "$example.com"
url := pymtptr.Resolve(paymentPointer)
fmt.Println(url)
}
Output: https://example.com/.well-known/pay
Example (WithPath) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
paymentPointer := "$example.com/joeblow"
url := pymtptr.Resolve(paymentPointer)
fmt.Println(url)
}
Output: https://example.com/joeblow
Example (WithSubDomain) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
paymentPointer := "$joeblow.example.com"
url := pymtptr.Resolve(paymentPointer)
fmt.Println(url)
}
Output: https://joeblow.example.com/.well-known/pay
func Sanitize ¶
Sanitize returns the sanitized form of a Payment-Pointer.
Example (AlreadyEncoded) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var paymentPointer string = "$xn--hello-world-lk27j.com/%DB%B1/%DB%B2/%DB%B3/%DB%B4/%DB%B5"
sanitized := pymtptr.Sanitize(paymentPointer)
fmt.Println(sanitized)
}
Output: $xn--hello-world-lk27j.com/%DB%B1/%DB%B2/%DB%B3/%DB%B4/%DB%B5
Example (JustHost) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var paymentPointer string = "$hello-world🙂.com"
sanitized := pymtptr.Sanitize(paymentPointer)
fmt.Println(sanitized)
}
Output: $xn--hello-world-lk27j.com
Example (NonAscii) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var paymentPointer string = "$hello-world🙂.com/۱/۲/۳/۴/۵"
sanitized := pymtptr.Sanitize(paymentPointer)
fmt.Println(sanitized)
}
Output: $xn--hello-world-lk27j.com/%DB%B1/%DB%B2/%DB%B3/%DB%B4/%DB%B5
Example (UpperCaseHost) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var paymentPointer string = "$HELLO-WORLD🙂.com"
sanitized := pymtptr.Sanitize(paymentPointer)
fmt.Println(sanitized)
}
Output: $xn--hello-world-lk27j.com
Example (WellKnown) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var paymentPointer string = "$example.com/.well-known/pay"
sanitized := pymtptr.Sanitize(paymentPointer)
fmt.Println(sanitized)
}
Output: $example.com
func Split ¶
Split parses a Payment-Pointer, and if valid, extracts the host and path from the Payment-Pointer and returns them.
host is NOT punycode encoded, but instead can contain non-ASCII Unicode characters.
path is NOT urlencoded, but instead can contain non-ASCII Unicode characters.
Example (IdnaHost) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var value string = "$xn--m28h.com"
host, path, err := pymtptr.Split(value)
if nil != err {
fmt.Printf("ERROR: %s\n", err)
return
}
fmt.Printf("HOST: %q\n", host)
fmt.Printf("PATH: %q\n", path)
}
Output: HOST: "😈.com" PATH: ""
Example (NonAsciiHost) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var value string = "$😈.com"
host, path, err := pymtptr.Split(value)
if nil != err {
fmt.Printf("ERROR: %s\n", err)
return
}
fmt.Printf("HOST: %q\n", host)
fmt.Printf("PATH: %q\n", path)
}
Output: HOST: "😈.com" PATH: ""
Example (NonAsciiPath) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var value string = "$example.com/۱/۲/۳/۴/۵"
host, path, err := pymtptr.Split(value)
if nil != err {
fmt.Printf("ERROR: %s\n", err)
return
}
fmt.Printf("HOST: %q\n", host)
fmt.Printf("PATH: %q\n", path)
}
Output: HOST: "example.com" PATH: "/۱/۲/۳/۴/۵"
Example (OnlyHost) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var value string = "$example.com"
host, path, err := pymtptr.Split(value)
if nil != err {
fmt.Printf("ERROR: %s\n", err)
return
}
fmt.Printf("HOST: %q\n", host)
fmt.Printf("PATH: %q\n", path)
}
Output: HOST: "example.com" PATH: ""
Example (WithPath) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var value string = "$example.com/joeblow"
host, path, err := pymtptr.Split(value)
if nil != err {
fmt.Printf("ERROR: %s\n", err)
return
}
fmt.Printf("HOST: %q\n", host)
fmt.Printf("PATH: %q\n", path)
}
Output: HOST: "example.com" PATH: "/joeblow"
Example (WithSubDomain) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var value string = "$joeblow.example.com"
host, path, err := pymtptr.Split(value)
if nil != err {
fmt.Printf("ERROR: %s\n", err)
return
}
fmt.Printf("HOST: %q\n", host)
fmt.Printf("PATH: %q\n", path)
}
Output: HOST: "joeblow.example.com" PATH: ""
Types ¶
type PaymentPointer ¶
PaymentPointer represents a Payment-Pointer, as defined by: https://paymentpointers.org/ and https://paymentpointers.org/syntax/
func (*PaymentPointer) Parse ¶
func (receiver *PaymentPointer) Parse(value string) error
Parse parses a Payment-Pointer, and if valid, extracts the host and path from the Payment-Pointer and loads it into the receiver.
Host is NOT punycode encoded, but instead can contain non-ASCII Unicode characters.
Path is NOT urlencoded, but instead can contain non-ASCII Unicode characters.
Example (IdnaHost) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var value string = "$xn--m28h.com"
var paymentPointer pymtptr.PaymentPointer
err := paymentPointer.Parse(value)
if nil != err {
fmt.Printf("ERROR: %s\n", err)
return
}
fmt.Printf("HOST: %q\n", paymentPointer.Host)
fmt.Printf("PATH: %q\n", paymentPointer.Path)
}
Output: HOST: "😈.com" PATH: ""
Example (NonAsciiHost) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var value string = "$😈.com"
var paymentPointer pymtptr.PaymentPointer
err := paymentPointer.Parse(value)
if nil != err {
fmt.Printf("ERROR: %s\n", err)
return
}
fmt.Printf("HOST: %q\n", paymentPointer.Host)
fmt.Printf("PATH: %q\n", paymentPointer.Path)
}
Output: HOST: "😈.com" PATH: ""
Example (NonAsciiPath) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var value string = "$example.com/۱/۲/۳/۴/۵"
var paymentPointer pymtptr.PaymentPointer
err := paymentPointer.Parse(value)
if nil != err {
fmt.Printf("ERROR: %s\n", err)
return
}
fmt.Printf("HOST: %q\n", paymentPointer.Host)
fmt.Printf("PATH: %q\n", paymentPointer.Path)
}
Output: HOST: "example.com" PATH: "/۱/۲/۳/۴/۵"
Example (OnlyHost) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var value string = "$example.com"
var paymentPointer pymtptr.PaymentPointer
err := paymentPointer.Parse(value)
if nil != err {
fmt.Printf("ERROR: %s\n", err)
return
}
fmt.Printf("HOST: %q\n", paymentPointer.Host)
fmt.Printf("PATH: %q\n", paymentPointer.Path)
}
Output: HOST: "example.com" PATH: ""
Example (WithPath) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var value string = "$example.com/joeblow"
var paymentPointer pymtptr.PaymentPointer
err := paymentPointer.Parse(value)
if nil != err {
fmt.Printf("ERROR: %s\n", err)
return
}
fmt.Printf("HOST: %q\n", paymentPointer.Host)
fmt.Printf("PATH: %q\n", paymentPointer.Path)
}
Output: HOST: "example.com" PATH: "/joeblow"
Example (WithSubDomain) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var value string = "$joeblow.example.com"
var paymentPointer pymtptr.PaymentPointer
err := paymentPointer.Parse(value)
if nil != err {
fmt.Printf("ERROR: %s\n", err)
return
}
fmt.Printf("HOST: %q\n", paymentPointer.Host)
fmt.Printf("PATH: %q\n", paymentPointer.Path)
}
Output: HOST: "joeblow.example.com" PATH: ""
func (PaymentPointer) Pretty ¶
func (receiver PaymentPointer) Pretty() string
Pretty returns the "pretty" version of a payment-pointer.
NOTE that the the "pretty" version of a payment-pointer might NOT be a valid payment-pointer!
What pretty returns is meant to be a more human-legible form meant for displaying to people (and is NOT mean to be consumed by machines).
Some example "pretty" payment-pointer are:
$example.com $joeblow.example.com $example.com/joeblow $🙂.com/۱/۲/۳/۴/۵
Note that the last example of a "pretty" version of a payment-pointer (i.e., "$🙂.com/۱/۲/۳/۴/۵") is NOT a valid payment-pointer!
To get a valid payment-pointer, instead use PaymentPointer.String.
Example (IdnaHost) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var paymentPointer = pymtptr.PaymentPointer{
Host: "xn--m28h.com",
}
pretty := paymentPointer.Pretty()
fmt.Println(pretty)
}
Output: $😈.com
Example (NonAsciiHost) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var paymentPointer = pymtptr.PaymentPointer{
Host: "😈.com",
}
pretty := paymentPointer.Pretty()
fmt.Println(pretty)
}
Output: $😈.com
Example (NonAsciiPath) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var paymentPointer = pymtptr.PaymentPointer{
Host: "example.com",
Path: "/۱/۲/۳/۴/۵",
}
pretty := paymentPointer.Pretty()
fmt.Println(pretty)
}
Output: $example.com/۱/۲/۳/۴/۵
Example (OnlyHost) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var paymentPointer = pymtptr.PaymentPointer{
Host: "example.com",
}
str := paymentPointer.Pretty()
fmt.Println(str)
}
Output: $example.com
Example (WithPath) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var paymentPointer = pymtptr.PaymentPointer{
Host: "example.com",
Path: "/joeblow",
}
pretty := paymentPointer.Pretty()
fmt.Println(pretty)
}
Output: $example.com/joeblow
Example (WithSubDomain) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var paymentPointer = pymtptr.PaymentPointer{
Host: "joeblow.example.com",
}
pretty := paymentPointer.Pretty()
fmt.Println(pretty)
}
Output: $joeblow.example.com
func (PaymentPointer) Resolve ¶
func (receiver PaymentPointer) Resolve() string
Resolve resolves a PaymentPointer to an HTTP URL.
If the PaymentPointer receiver is NOT a valid the Resolve returns an empty string.
Example (IdnaHost) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var paymentPointer = pymtptr.PaymentPointer{
Host: "xn--m28h.com",
}
url := paymentPointer.Resolve()
fmt.Println(url)
}
Output: https://xn--m28h.com/.well-known/pay
Example (NonAsciiHost) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var paymentPointer = pymtptr.PaymentPointer{
Host: "😈.com",
}
url := paymentPointer.Resolve()
fmt.Println(url)
}
Output: https://xn--m28h.com/.well-known/pay
Example (NonAsciiPath) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var paymentPointer = pymtptr.PaymentPointer{
Host: "example.com",
Path: "/۱/۲/۳/۴/۵",
}
url := paymentPointer.Resolve()
fmt.Println(url)
}
Output: https://example.com/%DB%B1/%DB%B2/%DB%B3/%DB%B4/%DB%B5
Example (OnlyHost) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var paymentPointer = pymtptr.PaymentPointer{
Host: "example.com",
}
url := paymentPointer.Resolve()
fmt.Println(url)
}
Output: https://example.com/.well-known/pay
Example (WithPath) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var paymentPointer = pymtptr.PaymentPointer{
Host: "example.com",
Path: "/joeblow",
}
url := paymentPointer.Resolve()
fmt.Println(url)
}
Output: https://example.com/joeblow
Example (WithSubDomain) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var paymentPointer = pymtptr.PaymentPointer{
Host: "joeblow.example.com",
}
url := paymentPointer.Resolve()
fmt.Println(url)
}
Output: https://joeblow.example.com/.well-known/pay
func (PaymentPointer) String ¶
func (receiver PaymentPointer) String() string
String returns the payment-pointer.
An example payment-pointer looks like these:
$example.com $joeblow.example.com $example.com/joeblow $xn--938h.com/%DB%B1/%DB%B2/%DB%B3/%DB%B4/%DB%B5
Note that what String returns is in ASCII.
A host with non-ASCII characters is encoded into ASCII using punycode.
A path with non-ASCII character is encoded into ASCII using urlencode.
Example (IdnaHost) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var paymentPointer = pymtptr.PaymentPointer{
Host: "xn--m28h.com",
}
str := paymentPointer.String()
fmt.Println(str)
}
Output: $xn--m28h.com
Example (NonAsciiHost) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var paymentPointer = pymtptr.PaymentPointer{
Host: "😈.com",
}
str := paymentPointer.String()
fmt.Println(str)
}
Output: $xn--m28h.com
Example (NonAsciiPath) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var paymentPointer = pymtptr.PaymentPointer{
Host: "example.com",
Path: "/۱/۲/۳/۴/۵",
}
str := paymentPointer.String()
fmt.Println(str)
}
Output: $example.com/%DB%B1/%DB%B2/%DB%B3/%DB%B4/%DB%B5
Example (OnlyHost) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var paymentPointer = pymtptr.PaymentPointer{
Host: "example.com",
}
str := paymentPointer.String()
fmt.Println(str)
}
Output: $example.com
Example (WithPath) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var paymentPointer = pymtptr.PaymentPointer{
Host: "example.com",
Path: "/joeblow",
}
str := paymentPointer.String()
fmt.Println(str)
}
Output: $example.com/joeblow
Example (WithSubDomain) ¶
package main
import (
"fmt"
"github.com/reiver/go-pymtptr"
)
func main() {
var paymentPointer = pymtptr.PaymentPointer{
Host: "joeblow.example.com",
}
str := paymentPointer.String()
fmt.Println(str)
}
Output: $joeblow.example.com