embed: timestamp iface
This commit is contained in:
		| @@ -24,7 +24,7 @@ type item interface { | |||||||
| 	// | 	// | ||||||
| 	// same as this: | 	// same as this: | ||||||
| 	// String() string | 	// String() string | ||||||
| 	fmt.Stringer | 	// fmt.Stringer | ||||||
| } | } | ||||||
| type list []item | type list []item | ||||||
|  |  | ||||||
| @@ -42,11 +42,12 @@ func (l list) String() string { | |||||||
| 		// the builder.WriteString doesn't know about the stringer interface. | 		// the builder.WriteString doesn't know about the stringer interface. | ||||||
| 		// because it takes a string argument. | 		// because it takes a string argument. | ||||||
| 		// so, you need to call the String method yourself. | 		// so, you need to call the String method yourself. | ||||||
| 		str.WriteString(it.String()) | 		// str.WriteString(it.String()) | ||||||
| 		str.WriteRune('\n') | 		// str.WriteRune('\n') | ||||||
|  |  | ||||||
| 		// or slower way: | 		// or slower way: | ||||||
| 		// fmt.Fprintln(&str, it) | 		// Print funcs can detect fmt.Stringer automatically. | ||||||
|  | 		fmt.Fprintln(&str, it) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return str.String() | 	return str.String() | ||||||
|   | |||||||
| @@ -12,66 +12,53 @@ import ( | |||||||
| 	"time" | 	"time" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // unknown is the zero value of a timestamp. | type timestamp struct { | ||||||
| var unknown = timestamp(time.Time{}) | 	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 |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // 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 { | func (ts *timestamp) UnmarshalJSON(data []byte) error { | ||||||
| 	s := string(data) | 	*ts = toTimestamp(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)) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| // String representation of the timestamp. | // timestamp knows how to encode itself to json. | ||||||
| func (ts timestamp) String() string { | // | ||||||
| 	t := time.Time(ts) | // 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" | 		return "unknown" | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Mon Jan 2 15:04:05 -0700 MST 2006 | 	// Mon Jan 2 15:04:05 -0700 MST 2006 | ||||||
| 	const layout = "2006/01" | 	const layout = "2006/01" | ||||||
|  | 	return ts.Format(layout) | ||||||
| 	return t.Format(layout) |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // toTimestamp from an unknown value. |  | ||||||
| func toTimestamp(v interface{}) timestamp { | func toTimestamp(v interface{}) timestamp { | ||||||
| 	var t int | 	var t int | ||||||
|  |  | ||||||
| 	switch v := v.(type) { | 	switch v := v.(type) { | ||||||
| 	case int: | 	case int: | ||||||
|  | 		// book{title: "moby dick", price: 10, published: 118281600}, | ||||||
| 		t = v | 		t = v | ||||||
| 	case string: | 	case string: | ||||||
|  | 		// book{title: "odyssey", price: 15, published: "733622400"}, | ||||||
| 		t, _ = strconv.Atoi(v) | 		t, _ = strconv.Atoi(v) | ||||||
| 	default: | 	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), | ||||||
|  | 	} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -31,6 +31,12 @@ func (db *database) MarshalJSON() ([]byte, error) { | |||||||
| 		// Name   -> returns the type name as string | 		// Name   -> returns the type name as string | ||||||
| 		t := reflect.TypeOf(it).Elem().Name() | 		t := reflect.TypeOf(it).Elem().Name() | ||||||
| 		e = append(e, encodable{t, it}) | 		e = append(e, encodable{t, it}) | ||||||
|  |  | ||||||
|  | 		// Another way: | ||||||
|  | 		// | ||||||
|  | 		// t := fmt.Sprintf("%T", it) | ||||||
|  | 		// | ||||||
|  | 		// Uses: reflect.TypeOf(arg).String() | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	return json.Marshal(e) | 	return json.Marshal(e) | ||||||
|   | |||||||
| @@ -12,66 +12,53 @@ import ( | |||||||
| 	"time" | 	"time" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // unknown is the zero value of a timestamp. | type timestamp struct { | ||||||
| var unknown = timestamp(time.Time{}) | 	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 |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // 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 { | func (ts *timestamp) UnmarshalJSON(data []byte) error { | ||||||
| 	s := string(data) | 	*ts = toTimestamp(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)) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| // String representation of the timestamp. | // timestamp knows how to encode itself to json. | ||||||
| func (ts timestamp) String() string { | // | ||||||
| 	t := time.Time(ts) | // 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" | 		return "unknown" | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Mon Jan 2 15:04:05 -0700 MST 2006 | 	// Mon Jan 2 15:04:05 -0700 MST 2006 | ||||||
| 	const layout = "2006/01" | 	const layout = "2006/01" | ||||||
|  | 	return ts.Format(layout) | ||||||
| 	return t.Format(layout) |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // toTimestamp from an unknown value. |  | ||||||
| func toTimestamp(v interface{}) timestamp { | func toTimestamp(v interface{}) timestamp { | ||||||
| 	var t int | 	var t int | ||||||
|  |  | ||||||
| 	switch v := v.(type) { | 	switch v := v.(type) { | ||||||
| 	case int: | 	case int: | ||||||
|  | 		// book{title: "moby dick", price: 10, published: 118281600}, | ||||||
| 		t = v | 		t = v | ||||||
| 	case string: | 	case string: | ||||||
|  | 		// book{title: "odyssey", price: 15, published: "733622400"}, | ||||||
| 		t, _ = strconv.Atoi(v) | 		t, _ = strconv.Atoi(v) | ||||||
| 	default: | 	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), | ||||||
|  | 	} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -12,66 +12,53 @@ import ( | |||||||
| 	"time" | 	"time" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // unknown is the zero value of a timestamp. | type timestamp struct { | ||||||
| var unknown = timestamp(time.Time{}) | 	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 |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // 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 { | func (ts *timestamp) UnmarshalJSON(data []byte) error { | ||||||
| 	s := string(data) | 	*ts = toTimestamp(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)) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| // String representation of the timestamp. | // timestamp knows how to encode itself to json. | ||||||
| func (ts timestamp) String() string { | // | ||||||
| 	t := time.Time(ts) | // 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" | 		return "unknown" | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Mon Jan 2 15:04:05 -0700 MST 2006 | 	// Mon Jan 2 15:04:05 -0700 MST 2006 | ||||||
| 	const layout = "2006/01" | 	const layout = "2006/01" | ||||||
|  | 	return ts.Format(layout) | ||||||
| 	return t.Format(layout) |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // toTimestamp from an unknown value. |  | ||||||
| func toTimestamp(v interface{}) timestamp { | func toTimestamp(v interface{}) timestamp { | ||||||
| 	var t int | 	var t int | ||||||
|  |  | ||||||
| 	switch v := v.(type) { | 	switch v := v.(type) { | ||||||
| 	case int: | 	case int: | ||||||
|  | 		// book{title: "moby dick", price: 10, published: 118281600}, | ||||||
| 		t = v | 		t = v | ||||||
| 	case string: | 	case string: | ||||||
|  | 		// book{title: "odyssey", price: 15, published: "733622400"}, | ||||||
| 		t, _ = strconv.Atoi(v) | 		t, _ = strconv.Atoi(v) | ||||||
| 	default: | 	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), | ||||||
|  | 	} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -12,66 +12,53 @@ import ( | |||||||
| 	"time" | 	"time" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // unknown is the zero value of a timestamp. | type timestamp struct { | ||||||
| var unknown = timestamp(time.Time{}) | 	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 |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // 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 { | func (ts *timestamp) UnmarshalJSON(data []byte) error { | ||||||
| 	s := string(data) | 	*ts = toTimestamp(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)) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| // String representation of the timestamp. | // timestamp knows how to encode itself to json. | ||||||
| func (ts timestamp) String() string { | // | ||||||
| 	t := time.Time(ts) | // 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" | 		return "unknown" | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Mon Jan 2 15:04:05 -0700 MST 2006 | 	// Mon Jan 2 15:04:05 -0700 MST 2006 | ||||||
| 	const layout = "2006/01" | 	const layout = "2006/01" | ||||||
|  | 	return ts.Format(layout) | ||||||
| 	return t.Format(layout) |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // toTimestamp from an unknown value. |  | ||||||
| func toTimestamp(v interface{}) timestamp { | func toTimestamp(v interface{}) timestamp { | ||||||
| 	var t int | 	var t int | ||||||
|  |  | ||||||
| 	switch v := v.(type) { | 	switch v := v.(type) { | ||||||
| 	case int: | 	case int: | ||||||
|  | 		// book{title: "moby dick", price: 10, published: 118281600}, | ||||||
| 		t = v | 		t = v | ||||||
| 	case string: | 	case string: | ||||||
|  | 		// book{title: "odyssey", price: 15, published: "733622400"}, | ||||||
| 		t, _ = strconv.Atoi(v) | 		t, _ = strconv.Atoi(v) | ||||||
| 	default: | 	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), | ||||||
|  | 	} | ||||||
| } | } | ||||||
|   | |||||||
| @@ -12,66 +12,53 @@ import ( | |||||||
| 	"time" | 	"time" | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // unknown is the zero value of a timestamp. | type timestamp struct { | ||||||
| var unknown = timestamp(time.Time{}) | 	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 |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // 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 { | func (ts *timestamp) UnmarshalJSON(data []byte) error { | ||||||
| 	s := string(data) | 	*ts = toTimestamp(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)) |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| // String representation of the timestamp. | // timestamp knows how to encode itself to json. | ||||||
| func (ts timestamp) String() string { | // | ||||||
| 	t := time.Time(ts) | // 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" | 		return "unknown" | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	// Mon Jan 2 15:04:05 -0700 MST 2006 | 	// Mon Jan 2 15:04:05 -0700 MST 2006 | ||||||
| 	const layout = "2006/01" | 	const layout = "2006/01" | ||||||
|  | 	return ts.Format(layout) | ||||||
| 	return t.Format(layout) |  | ||||||
| } | } | ||||||
|  |  | ||||||
| // toTimestamp from an unknown value. |  | ||||||
| func toTimestamp(v interface{}) timestamp { | func toTimestamp(v interface{}) timestamp { | ||||||
| 	var t int | 	var t int | ||||||
|  |  | ||||||
| 	switch v := v.(type) { | 	switch v := v.(type) { | ||||||
| 	case int: | 	case int: | ||||||
|  | 		// book{title: "moby dick", price: 10, published: 118281600}, | ||||||
| 		t = v | 		t = v | ||||||
| 	case string: | 	case string: | ||||||
|  | 		// book{title: "odyssey", price: 15, published: "733622400"}, | ||||||
| 		t, _ = strconv.Atoi(v) | 		t, _ = strconv.Atoi(v) | ||||||
| 	default: | 	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), | ||||||
|  | 	} | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user