basic marshaler support
diff --git a/encode.go b/encode.go
index 74a121b..175071d 100644
--- a/encode.go
+++ b/encode.go
@@ -26,6 +26,12 @@
 	return e.Bytes(), nil
 }
 
+// Marshaler is the interface implemented by objects that
+// can marshal themselves into valid JSON.
+type Marshaler interface {
+	MarshalJSON() ([]byte, error)
+}
+
 // An UnsupportedTypeError is returned by Marshal when attempting
 // to encode an unsupported value type.
 type UnsupportedTypeError struct {
@@ -137,6 +143,26 @@
 		return
 	}
 
+	m, ok := v.Interface().(Marshaler)
+	if !ok {
+		// T doesn't match the interface. Check against *T too.
+		if v.Kind() != reflect.Ptr && v.CanAddr() {
+			m, ok = v.Addr().Interface().(Marshaler)
+			if ok {
+				v = v.Addr()
+			}
+		}
+	}
+	if ok && (v.Kind() != reflect.Ptr || !v.IsNil()) {
+		b, err := m.MarshalJSON()
+		if err != nil {
+			e.error(&MarshalerError{v.Type(), err})
+		}
+		// TODO: canonicalize this json
+		e.Buffer.Write(b)
+		return
+	}
+
 	writeString := (*encodeState).WriteString
 	if quoted {
 		writeString = (*encodeState).string