encoder.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. package exporter
  2. import (
  3. "encoding"
  4. "github.com/opencost/opencost/core/pkg/util/json"
  5. )
  6. // Encoder[T] is a generic interface for encoding an instance of a T type into a byte slice.
  7. type Encoder[T any] interface {
  8. Encode(*T) ([]byte, error)
  9. // FileExt returns the file extension for the encoded data. This can be used by a pathing strategy
  10. // to append the file extension when exporting the data. Returning an empty string will typically
  11. // omit the file extension completely.
  12. FileExt() string
  13. }
  14. // BinaryMarshalerPtr[T] is a generic constraint to ensure types passed to the encoder implement
  15. // encoding.BinaryMarshaler and are pointers to T.
  16. type BinaryMarshalerPtr[T any] interface {
  17. encoding.BinaryMarshaler
  18. *T
  19. }
  20. // BingenEncoder[T, U] is a generic encoder that uses the BinaryMarshaler interface to encode data.
  21. // It supports any type T that implements the encoding.BinaryMarshaler interface.
  22. type BingenEncoder[T any, U BinaryMarshalerPtr[T]] struct{}
  23. // NewBingenEncoder creates an `Encoder[T]` implementation which supports binary encoding for the `T`
  24. // type.
  25. func NewBingenEncoder[T any, U BinaryMarshalerPtr[T]]() Encoder[T] {
  26. return new(BingenEncoder[T, U])
  27. }
  28. // Encode encodes the provided data of type T into a byte slice using the BinaryMarshaler interface.
  29. func (b *BingenEncoder[T, U]) Encode(data *T) ([]byte, error) {
  30. var bingenData U = data
  31. return bingenData.MarshalBinary()
  32. }
  33. // FileExt returns the file extension for the encoded data. In this case, it returns an empty string
  34. // to indicate that there is no specific file extension for the binary encoded data.
  35. func (b *BingenEncoder[T, U]) FileExt() string {
  36. return ""
  37. }
  38. // JSONEncoder[T] is a generic encoder that uses the JSON encoding format to encode data.
  39. type JSONEncoder[T any] struct{}
  40. // NewJSONEncoder creates an `Encoder[T]` implementation which supports JSON encoding for the `T`
  41. // type.
  42. func NewJSONEncoder[T any]() Encoder[T] {
  43. return new(JSONEncoder[T])
  44. }
  45. // Encode encodes the provided data of type T into a byte slice using JSON encoding.
  46. func (j *JSONEncoder[T]) Encode(data *T) ([]byte, error) {
  47. return json.Marshal(data)
  48. }
  49. // FileExt returns the file extension for the encoded data. In this case, it returns "json" to indicate
  50. // that the data is in JSON format.
  51. func (j *JSONEncoder[T]) FileExt() string {
  52. return "json"
  53. }