--- /dev/null
+
+package main
+
+import (
+ "fmt"
+ "encoding/json"
+ "time"
+ "encoding"
+ "strings"
+)
+
+type Message struct {
+ Name Name
+ Body Body
+ Time time.Time
+}
+
+// Marshal manually using encoding.TextMarshaler into text.
+type Name string
+
+var _ encoding.TextMarshaler = (Name)("")
+func (v Name) MarshalText() (text []byte, err error) {
+ return []byte(v + " by MarshalText"), nil
+}
+
+var _ encoding.TextUnmarshaler = (*Name)(nil)
+func (v *Name) UnmarshalText(text []byte) error {
+ *v = (Name)(strings.TrimSuffix(string(text), " by MarshalText"))
+ return nil
+}
+
+// Marshal manually using json.MarshalJSON() into json array.
+type Body string
+
+var _ json.Marshaler = (Body)("")
+func (b Body) MarshalJSON() (text []byte, err error) {
+ var arr []string
+ for _, c := range b {
+ arr = append(arr, string(c))
+ }
+ arr = append(arr, " by MarshalJSON")
+ v, err := json.Marshal(arr)
+ return v, err
+}
+
+var _ json.Unmarshaler = (*Body)(nil)
+func (b *Body) UnmarshalJSON(text []byte) error {
+ var v interface{}
+ // Unmarshal into "unknown" type.
+ err := json.Unmarshal(text, &v)
+ if err != nil {
+ return err
+ }
+ var arr []byte
+ for _, c := range v.([]interface{}) {
+ s := c.(string)
+ if s == " by MarshalJSON" {
+ continue
+ }
+ arr = append(arr, ([]byte)(s)...)
+ }
+ *b = Body(arr)
+ return nil
+}
+
+func main() {
+ m0 := Message{"Alice", "Hello", time.Now()}
+ fmt.Printf("m0 = %#v\n", m0)
+
+ b, err := json.Marshal(m0)
+ if err != nil {
+ fmt.Println("Error", err)
+ return
+ }
+ fmt.Printf("json = %v\n", string(b))
+
+ var m1 Message
+ err = json.Unmarshal(b, &m1)
+ if err != nil {
+ fmt.Println("Error", err)
+ return
+ }
+ fmt.Printf("m1 = %#v\n", m1)
+}