package jsoner

// |@@| C

import (
	"encoding/json"
	erro "gardening/src/lib/error"
)

type Jsoner struct {
}

func (this *Jsoner) Marshal(v any) (b []byte, err error) {
	b, err = json.Marshal(v)
	if err != nil {
		return b, erro.W("Cannot marshal", err)
	}
	return b, nil
}

func (this *Jsoner) MarshalIndent(v any) ([]byte, error) {
	return json.MarshalIndent(v, "", "    ")
}

func (this *Jsoner) MustMarshal(v any) []byte {
	b, err := this.Marshal(v)
	if err != nil {
		panic(erro.W("Cannot marshal json", err))
	}
	return b
}

func (this *Jsoner) MustMarshalIndent(v any) []byte {
	b, err := this.MarshalIndent(v)
	if err != nil {
		panic(erro.W("Cannot marshal json", err))
	}
	return b
}

func (this *Jsoner) CanUnmarshal(data []byte) bool {
	if data == nil {
		return false
	}
	if string(data) == "" {
		return false
	}
	return true
}

func (this *Jsoner) MustUnmarshal(data []byte, v any) {
	err := this.Unmarshal(data, v)
	if err != nil {
		d := string(data)
		if len(d) > 1000 {
			d = d[0:1000]
		}
		emptyData := false
		if d == "" {
			emptyData = true
		}
		text := "Cannot unmarshal"
		if emptyData == true {
			text += ", as no data is passed"
		}
		panic(erro.W(text, err).KVT("data", d).KVT("empty_data", emptyData))
	}
}

func (this *Jsoner) Unmarshal(data []byte, v any) (err error) {
	err = json.Unmarshal(data, v)
	if err != nil {
		return erro.W("Cannot unmarshal", err)
	}
	return nil
}

func (this *Jsoner) MayUnmarshal(data []byte, v any) error {
	if !this.CanUnmarshal(data) {
		return nil
	}
	return this.Unmarshal(data, v)
}

func (this *Jsoner) MightUnmarshal(data []byte, v any) {
	err := this.MayUnmarshal(data, v)
	if err != nil {
		panic(erro.W("Might not unmarshal", err))
	}
}
