diff --git a/interfaces/09-stringer/list.go b/interfaces/09-stringer/list.go index 465cc73..92907a9 100644 --- a/interfaces/09-stringer/list.go +++ b/interfaces/09-stringer/list.go @@ -24,7 +24,7 @@ type item interface { // // same as this: // String() string - fmt.Stringer + // fmt.Stringer } type list []item @@ -42,11 +42,12 @@ func (l list) String() string { // the builder.WriteString doesn't know about the stringer interface. // because it takes a string argument. // so, you need to call the String method yourself. - str.WriteString(it.String()) - str.WriteRune('\n') + // str.WriteString(it.String()) + // str.WriteRune('\n') // or slower way: - // fmt.Fprintln(&str, it) + // Print funcs can detect fmt.Stringer automatically. + fmt.Fprintln(&str, it) } return str.String() diff --git a/interfaces/11-decode-toiface/timestamp.go b/interfaces/11-decode-toiface/timestamp.go index ab29528..04732e6 100644 --- a/interfaces/11-decode-toiface/timestamp.go +++ b/interfaces/11-decode-toiface/timestamp.go @@ -12,66 +12,53 @@ import ( "time" ) -// unknown is the zero value of a timestamp. -var unknown = timestamp(time.Time{}) - -// timestamp prints timestamps, it's a stringer. -// It is useful even if it's zero. -type timestamp time.Time - -// MarshalJSON from timestamp. -func (ts timestamp) MarshalJSON() (out []byte, err error) { - u := time.Time(ts).Unix() - return strconv.AppendInt(out, u, 10), nil +type timestamp struct { + time.Time } -// UnmarshalJSON data to timestamp. +// timestamp knows how to decode itself from json. +// +// UnmarshalJSON is an implementation of the json.Unmarshaler interface. +// json.Unmarshal and json.Decode call this method. func (ts *timestamp) UnmarshalJSON(data []byte) error { - s := string(data) - - // Let the ParseInt parse quoted strings. - us, err := strconv.Unquote(s) - if err == nil { - s = us - } - - // Always overwrite the timestamp when decoding. - *ts = unknown - - // Handle the numeric case. - if n, err := strconv.ParseInt(s, 10, 64); err == nil { - *ts = timestamp(time.Unix(n, 0)) - } - + *ts = toTimestamp(string(data)) return nil } -// String representation of the timestamp. -func (ts timestamp) String() string { - t := time.Time(ts) +// timestamp knows how to encode itself to json. +// +// MarshalJSON is an implementation of the json.Marshaler interface. +// json.Marshal and json.Encode call this method. +func (ts timestamp) MarshalJSON() (out []byte, err error) { + return strconv.AppendInt(out, ts.Unix(), 10), nil +} - if t.IsZero() { +func (ts timestamp) String() string { + if ts.IsZero() { return "unknown" } // Mon Jan 2 15:04:05 -0700 MST 2006 const layout = "2006/01" - - return t.Format(layout) + return ts.Format(layout) } -// toTimestamp from an unknown value. func toTimestamp(v interface{}) timestamp { var t int switch v := v.(type) { case int: + // book{title: "moby dick", price: 10, published: 118281600}, t = v case string: + // book{title: "odyssey", price: 15, published: "733622400"}, t, _ = strconv.Atoi(v) default: - return unknown + // book{title: "hobbit", price: 25}, + return timestamp{} } - return timestamp(time.Unix(int64(t), 0)) + return timestamp{ + Time: time.Unix(int64(t), 0), + } } diff --git a/interfaces/12-reflection/database.go b/interfaces/12-reflection/database.go index 5aa1d37..1d22b70 100644 --- a/interfaces/12-reflection/database.go +++ b/interfaces/12-reflection/database.go @@ -31,6 +31,12 @@ func (db *database) MarshalJSON() ([]byte, error) { // Name -> returns the type name as string t := reflect.TypeOf(it).Elem().Name() e = append(e, encodable{t, it}) + + // Another way: + // + // t := fmt.Sprintf("%T", it) + // + // Uses: reflect.TypeOf(arg).String() } return json.Marshal(e) diff --git a/interfaces/12-reflection/timestamp.go b/interfaces/12-reflection/timestamp.go index ab29528..04732e6 100644 --- a/interfaces/12-reflection/timestamp.go +++ b/interfaces/12-reflection/timestamp.go @@ -12,66 +12,53 @@ import ( "time" ) -// unknown is the zero value of a timestamp. -var unknown = timestamp(time.Time{}) - -// timestamp prints timestamps, it's a stringer. -// It is useful even if it's zero. -type timestamp time.Time - -// MarshalJSON from timestamp. -func (ts timestamp) MarshalJSON() (out []byte, err error) { - u := time.Time(ts).Unix() - return strconv.AppendInt(out, u, 10), nil +type timestamp struct { + time.Time } -// UnmarshalJSON data to timestamp. +// timestamp knows how to decode itself from json. +// +// UnmarshalJSON is an implementation of the json.Unmarshaler interface. +// json.Unmarshal and json.Decode call this method. func (ts *timestamp) UnmarshalJSON(data []byte) error { - s := string(data) - - // Let the ParseInt parse quoted strings. - us, err := strconv.Unquote(s) - if err == nil { - s = us - } - - // Always overwrite the timestamp when decoding. - *ts = unknown - - // Handle the numeric case. - if n, err := strconv.ParseInt(s, 10, 64); err == nil { - *ts = timestamp(time.Unix(n, 0)) - } - + *ts = toTimestamp(string(data)) return nil } -// String representation of the timestamp. -func (ts timestamp) String() string { - t := time.Time(ts) +// timestamp knows how to encode itself to json. +// +// MarshalJSON is an implementation of the json.Marshaler interface. +// json.Marshal and json.Encode call this method. +func (ts timestamp) MarshalJSON() (out []byte, err error) { + return strconv.AppendInt(out, ts.Unix(), 10), nil +} - if t.IsZero() { +func (ts timestamp) String() string { + if ts.IsZero() { return "unknown" } // Mon Jan 2 15:04:05 -0700 MST 2006 const layout = "2006/01" - - return t.Format(layout) + return ts.Format(layout) } -// toTimestamp from an unknown value. func toTimestamp(v interface{}) timestamp { var t int switch v := v.(type) { case int: + // book{title: "moby dick", price: 10, published: 118281600}, t = v case string: + // book{title: "odyssey", price: 15, published: "733622400"}, t, _ = strconv.Atoi(v) default: - return unknown + // book{title: "hobbit", price: 25}, + return timestamp{} } - return timestamp(time.Unix(int64(t), 0)) + return timestamp{ + Time: time.Unix(int64(t), 0), + } } diff --git a/interfaces/13-reflection-2/timestamp.go b/interfaces/13-reflection-2/timestamp.go index ab29528..04732e6 100644 --- a/interfaces/13-reflection-2/timestamp.go +++ b/interfaces/13-reflection-2/timestamp.go @@ -12,66 +12,53 @@ import ( "time" ) -// unknown is the zero value of a timestamp. -var unknown = timestamp(time.Time{}) - -// timestamp prints timestamps, it's a stringer. -// It is useful even if it's zero. -type timestamp time.Time - -// MarshalJSON from timestamp. -func (ts timestamp) MarshalJSON() (out []byte, err error) { - u := time.Time(ts).Unix() - return strconv.AppendInt(out, u, 10), nil +type timestamp struct { + time.Time } -// UnmarshalJSON data to timestamp. +// timestamp knows how to decode itself from json. +// +// UnmarshalJSON is an implementation of the json.Unmarshaler interface. +// json.Unmarshal and json.Decode call this method. func (ts *timestamp) UnmarshalJSON(data []byte) error { - s := string(data) - - // Let the ParseInt parse quoted strings. - us, err := strconv.Unquote(s) - if err == nil { - s = us - } - - // Always overwrite the timestamp when decoding. - *ts = unknown - - // Handle the numeric case. - if n, err := strconv.ParseInt(s, 10, 64); err == nil { - *ts = timestamp(time.Unix(n, 0)) - } - + *ts = toTimestamp(string(data)) return nil } -// String representation of the timestamp. -func (ts timestamp) String() string { - t := time.Time(ts) +// timestamp knows how to encode itself to json. +// +// MarshalJSON is an implementation of the json.Marshaler interface. +// json.Marshal and json.Encode call this method. +func (ts timestamp) MarshalJSON() (out []byte, err error) { + return strconv.AppendInt(out, ts.Unix(), 10), nil +} - if t.IsZero() { +func (ts timestamp) String() string { + if ts.IsZero() { return "unknown" } // Mon Jan 2 15:04:05 -0700 MST 2006 const layout = "2006/01" - - return t.Format(layout) + return ts.Format(layout) } -// toTimestamp from an unknown value. func toTimestamp(v interface{}) timestamp { var t int switch v := v.(type) { case int: + // book{title: "moby dick", price: 10, published: 118281600}, t = v case string: + // book{title: "odyssey", price: 15, published: "733622400"}, t, _ = strconv.Atoi(v) default: - return unknown + // book{title: "hobbit", price: 25}, + return timestamp{} } - return timestamp(time.Unix(int64(t), 0)) + return timestamp{ + Time: time.Unix(int64(t), 0), + } } diff --git a/interfaces/14-io-reader/timestamp.go b/interfaces/14-io-reader/timestamp.go index ab29528..04732e6 100644 --- a/interfaces/14-io-reader/timestamp.go +++ b/interfaces/14-io-reader/timestamp.go @@ -12,66 +12,53 @@ import ( "time" ) -// unknown is the zero value of a timestamp. -var unknown = timestamp(time.Time{}) - -// timestamp prints timestamps, it's a stringer. -// It is useful even if it's zero. -type timestamp time.Time - -// MarshalJSON from timestamp. -func (ts timestamp) MarshalJSON() (out []byte, err error) { - u := time.Time(ts).Unix() - return strconv.AppendInt(out, u, 10), nil +type timestamp struct { + time.Time } -// UnmarshalJSON data to timestamp. +// timestamp knows how to decode itself from json. +// +// UnmarshalJSON is an implementation of the json.Unmarshaler interface. +// json.Unmarshal and json.Decode call this method. func (ts *timestamp) UnmarshalJSON(data []byte) error { - s := string(data) - - // Let the ParseInt parse quoted strings. - us, err := strconv.Unquote(s) - if err == nil { - s = us - } - - // Always overwrite the timestamp when decoding. - *ts = unknown - - // Handle the numeric case. - if n, err := strconv.ParseInt(s, 10, 64); err == nil { - *ts = timestamp(time.Unix(n, 0)) - } - + *ts = toTimestamp(string(data)) return nil } -// String representation of the timestamp. -func (ts timestamp) String() string { - t := time.Time(ts) +// timestamp knows how to encode itself to json. +// +// MarshalJSON is an implementation of the json.Marshaler interface. +// json.Marshal and json.Encode call this method. +func (ts timestamp) MarshalJSON() (out []byte, err error) { + return strconv.AppendInt(out, ts.Unix(), 10), nil +} - if t.IsZero() { +func (ts timestamp) String() string { + if ts.IsZero() { return "unknown" } // Mon Jan 2 15:04:05 -0700 MST 2006 const layout = "2006/01" - - return t.Format(layout) + return ts.Format(layout) } -// toTimestamp from an unknown value. func toTimestamp(v interface{}) timestamp { var t int switch v := v.(type) { case int: + // book{title: "moby dick", price: 10, published: 118281600}, t = v case string: + // book{title: "odyssey", price: 15, published: "733622400"}, t, _ = strconv.Atoi(v) default: - return unknown + // book{title: "hobbit", price: 25}, + return timestamp{} } - return timestamp(time.Unix(int64(t), 0)) + return timestamp{ + Time: time.Unix(int64(t), 0), + } } diff --git a/interfaces/15-io-reader-composition/timestamp.go b/interfaces/15-io-reader-composition/timestamp.go index ab29528..04732e6 100644 --- a/interfaces/15-io-reader-composition/timestamp.go +++ b/interfaces/15-io-reader-composition/timestamp.go @@ -12,66 +12,53 @@ import ( "time" ) -// unknown is the zero value of a timestamp. -var unknown = timestamp(time.Time{}) - -// timestamp prints timestamps, it's a stringer. -// It is useful even if it's zero. -type timestamp time.Time - -// MarshalJSON from timestamp. -func (ts timestamp) MarshalJSON() (out []byte, err error) { - u := time.Time(ts).Unix() - return strconv.AppendInt(out, u, 10), nil +type timestamp struct { + time.Time } -// UnmarshalJSON data to timestamp. +// timestamp knows how to decode itself from json. +// +// UnmarshalJSON is an implementation of the json.Unmarshaler interface. +// json.Unmarshal and json.Decode call this method. func (ts *timestamp) UnmarshalJSON(data []byte) error { - s := string(data) - - // Let the ParseInt parse quoted strings. - us, err := strconv.Unquote(s) - if err == nil { - s = us - } - - // Always overwrite the timestamp when decoding. - *ts = unknown - - // Handle the numeric case. - if n, err := strconv.ParseInt(s, 10, 64); err == nil { - *ts = timestamp(time.Unix(n, 0)) - } - + *ts = toTimestamp(string(data)) return nil } -// String representation of the timestamp. -func (ts timestamp) String() string { - t := time.Time(ts) +// timestamp knows how to encode itself to json. +// +// MarshalJSON is an implementation of the json.Marshaler interface. +// json.Marshal and json.Encode call this method. +func (ts timestamp) MarshalJSON() (out []byte, err error) { + return strconv.AppendInt(out, ts.Unix(), 10), nil +} - if t.IsZero() { +func (ts timestamp) String() string { + if ts.IsZero() { return "unknown" } // Mon Jan 2 15:04:05 -0700 MST 2006 const layout = "2006/01" - - return t.Format(layout) + return ts.Format(layout) } -// toTimestamp from an unknown value. func toTimestamp(v interface{}) timestamp { var t int switch v := v.(type) { case int: + // book{title: "moby dick", price: 10, published: 118281600}, t = v case string: + // book{title: "odyssey", price: 15, published: "733622400"}, t, _ = strconv.Atoi(v) default: - return unknown + // book{title: "hobbit", price: 25}, + return timestamp{} } - return timestamp(time.Unix(int64(t), 0)) + return timestamp{ + Time: time.Unix(int64(t), 0), + } }