Compare commits
	
		
			5 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 14bbd205f8 | |||
| cecfb0d788 | |||
| a445e6f623 | |||
| 0aa6310971 | |||
| 2f66ab1cf0 | 
| @@ -167,15 +167,30 @@ func Marshal(v any) ([]byte, error) { | |||||||
| 	return buf, nil | 	return buf, nil | ||||||
| } | } | ||||||
|  |  | ||||||
|  | type IndentOpt struct { | ||||||
|  | 	Prefix string | ||||||
|  | 	Indent string | ||||||
|  | } | ||||||
|  |  | ||||||
| // MarshalSafeCollections is like Marshal except it will marshal nil maps and | // MarshalSafeCollections is like Marshal except it will marshal nil maps and | ||||||
| // slices as '{}' and '[]' respectfully instead of 'null' | // slices as '{}' and '[]' respectfully instead of 'null' | ||||||
| func MarshalSafeCollections(v interface{}, nilSafeSlices bool, nilSafeMaps bool) ([]byte, error) { | func MarshalSafeCollections(v interface{}, nilSafeSlices bool, nilSafeMaps bool, indent *IndentOpt) ([]byte, error) { | ||||||
| 	e := &encodeState{} | 	e := &encodeState{} | ||||||
| 	err := e.marshal(v, encOpts{escapeHTML: true, nilSafeSlices: nilSafeSlices, nilSafeMaps: nilSafeMaps}) | 	err := e.marshal(v, encOpts{escapeHTML: true, nilSafeSlices: nilSafeSlices, nilSafeMaps: nilSafeMaps}) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return nil, err | 		return nil, err | ||||||
| 	} | 	} | ||||||
|  | 	b := e.Bytes() | ||||||
|  | 	if indent != nil { | ||||||
|  | 		var buf bytes.Buffer | ||||||
|  | 		err = Indent(&buf, b, indent.Prefix, indent.Indent) | ||||||
|  | 		if err != nil { | ||||||
|  | 			return nil, err | ||||||
|  | 		} | ||||||
|  | 		return buf.Bytes(), nil | ||||||
|  | 	} else { | ||||||
| 		return e.Bytes(), nil | 		return e.Bytes(), nil | ||||||
|  | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| // MarshalIndent is like Marshal but applies Indent to format the output. | // MarshalIndent is like Marshal but applies Indent to format the output. | ||||||
|   | |||||||
							
								
								
									
										44
									
								
								gojson/gionic.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								gojson/gionic.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | |||||||
|  | package json | ||||||
|  |  | ||||||
|  | import ( | ||||||
|  | 	"net/http" | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | // Render interface is copied from github.com/gin-gonic/gin@v1.8.1/render/render.go | ||||||
|  | type Render interface { | ||||||
|  | 	// Render writes data with custom ContentType. | ||||||
|  | 	Render(http.ResponseWriter) error | ||||||
|  | 	// WriteContentType writes custom ContentType. | ||||||
|  | 	WriteContentType(w http.ResponseWriter) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | type GoJsonRender struct { | ||||||
|  | 	Data          any | ||||||
|  | 	NilSafeSlices bool | ||||||
|  | 	NilSafeMaps   bool | ||||||
|  | 	Indent        *IndentOpt | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (r GoJsonRender) Render(w http.ResponseWriter) error { | ||||||
|  | 	header := w.Header() | ||||||
|  | 	if val := header["Content-Type"]; len(val) == 0 { | ||||||
|  | 		header["Content-Type"] = []string{"application/json; charset=utf-8"} | ||||||
|  | 	} | ||||||
|  |  | ||||||
|  | 	jsonBytes, err := MarshalSafeCollections(r.Data, r.NilSafeSlices, r.NilSafeMaps, r.Indent) | ||||||
|  | 	if err != nil { | ||||||
|  | 		panic(err) | ||||||
|  | 	} | ||||||
|  | 	_, err = w.Write(jsonBytes) | ||||||
|  | 	if err != nil { | ||||||
|  | 		panic(err) | ||||||
|  | 	} | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (r GoJsonRender) WriteContentType(w http.ResponseWriter) { | ||||||
|  | 	header := w.Header() | ||||||
|  | 	if val := header["Content-Type"]; len(val) == 0 { | ||||||
|  | 		header["Content-Type"] = []string{"application/json; charset=utf-8"} | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @@ -15,3 +15,11 @@ func ArrToMap[T comparable, V any](a []V, keyfunc func(V) T) map[T]V { | |||||||
| 	} | 	} | ||||||
| 	return result | 	return result | ||||||
| } | } | ||||||
|  |  | ||||||
|  | func CopyMap[K comparable, V any](a map[K]V) map[K]V { | ||||||
|  | 	result := make(map[K]V, len(a)) | ||||||
|  | 	for k, v := range a { | ||||||
|  | 		result[k] = v | ||||||
|  | 	} | ||||||
|  | 	return result | ||||||
|  | } | ||||||
|   | |||||||
							
								
								
									
										71
									
								
								langext/panic.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								langext/panic.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,71 @@ | |||||||
|  | package langext | ||||||
|  |  | ||||||
|  | type PanicWrappedErr struct { | ||||||
|  | 	panic any | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p PanicWrappedErr) Error() string { | ||||||
|  | 	return "A panic occured" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func (p PanicWrappedErr) ReoveredObj() any { | ||||||
|  | 	return p.panic | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func RunPanicSafe(fn func()) (err error) { | ||||||
|  | 	defer func() { | ||||||
|  | 		if rec := recover(); rec != nil { | ||||||
|  | 			err = PanicWrappedErr{panic: rec} | ||||||
|  | 		} | ||||||
|  | 	}() | ||||||
|  |  | ||||||
|  | 	fn() | ||||||
|  |  | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func RunPanicSafeR1(fn func() error) (err error) { | ||||||
|  | 	defer func() { | ||||||
|  | 		if rec := recover(); rec != nil { | ||||||
|  | 			err = PanicWrappedErr{panic: rec} | ||||||
|  | 		} | ||||||
|  | 	}() | ||||||
|  |  | ||||||
|  | 	return fn() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func RunPanicSafeR2[T1 any](fn func() (T1, error)) (r1 T1, err error) { | ||||||
|  | 	defer func() { | ||||||
|  | 		if rec := recover(); rec != nil { | ||||||
|  | 			r1 = *new(T1) | ||||||
|  | 			err = PanicWrappedErr{panic: rec} | ||||||
|  | 		} | ||||||
|  | 	}() | ||||||
|  |  | ||||||
|  | 	return fn() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func RunPanicSafeR3[T1 any, T2 any](fn func() (T1, T2, error)) (r1 T1, r2 T2, err error) { | ||||||
|  | 	defer func() { | ||||||
|  | 		if rec := recover(); rec != nil { | ||||||
|  | 			r1 = *new(T1) | ||||||
|  | 			r2 = *new(T2) | ||||||
|  | 			err = PanicWrappedErr{panic: rec} | ||||||
|  | 		} | ||||||
|  | 	}() | ||||||
|  |  | ||||||
|  | 	return fn() | ||||||
|  | } | ||||||
|  |  | ||||||
|  | func RunPanicSafeR4[T1 any, T2 any, T3 any](fn func() (T1, T2, T3, error)) (r1 T1, r2 T2, r3 T3, err error) { | ||||||
|  | 	defer func() { | ||||||
|  | 		if rec := recover(); rec != nil { | ||||||
|  | 			r1 = *new(T1) | ||||||
|  | 			r2 = *new(T2) | ||||||
|  | 			r3 = *new(T3) | ||||||
|  | 			err = PanicWrappedErr{panic: rec} | ||||||
|  | 		} | ||||||
|  | 	}() | ||||||
|  |  | ||||||
|  | 	return fn() | ||||||
|  | } | ||||||
| @@ -67,7 +67,7 @@ func (t *RFC3339Time) UnmarshalText(data []byte) error { | |||||||
|  |  | ||||||
| func (t *RFC3339Time) UnmarshalBSONValue(bt bsontype.Type, data []byte) error { | func (t *RFC3339Time) UnmarshalBSONValue(bt bsontype.Type, data []byte) error { | ||||||
| 	if bt == bsontype.Null { | 	if bt == bsontype.Null { | ||||||
| 		*t = RFC3339Time{} | 		//t = nil | ||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
| 	if bt != bsontype.DateTime { | 	if bt != bsontype.DateTime { | ||||||
|   | |||||||
| @@ -67,7 +67,7 @@ func (t *RFC3339NanoTime) UnmarshalText(data []byte) error { | |||||||
|  |  | ||||||
| func (t *RFC3339NanoTime) UnmarshalBSONValue(bt bsontype.Type, data []byte) error { | func (t *RFC3339NanoTime) UnmarshalBSONValue(bt bsontype.Type, data []byte) error { | ||||||
| 	if bt == bsontype.Null { | 	if bt == bsontype.Null { | ||||||
| 		*t = RFC3339NanoTime{} | 		//t = nil | ||||||
| 		return nil | 		return nil | ||||||
| 	} | 	} | ||||||
| 	if bt != bsontype.DateTime { | 	if bt != bsontype.DateTime { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user