Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Find a way to have such marshallers but allow users to support their own through... #235

Open
github-actions bot opened this issue Aug 24, 2022 · 0 comments
Labels

Comments

@github-actions
Copy link

Find a way to have such marshallers but allow users to support their own through plugins

// TODO: Find a way to have such marshallers but allow users to support their own through plugins

	FilterAnd
)

func (o FilterOperator) String() string {
	switch o {
	case FilterEqual:
		return "FilterEqual"
	case FilterNEqual:
		return "FilterNEqual"
	case FilterGreaterThan:
		return "FilterGreaterThan"
	case FilterGreaterThanEqual:
		return "FilterGreaterThanEqual"
	case FilterLessThan:
		return "FilterLessThan"
	case FilterLessThanEqual:
		return "FilterLessThanEqual"
	case FilterIn:
		return "FilterIn"
	case FilterNotIn:
		return "FilterNotIn"
	case FilterBetween:
		return "FilterNotIn"
	case FilterNotBetween:
		return "FilterBetweenEqual"
	case FilterLike:
		return "FilterLike"
	case FilterNotLike:
		return "FilterNotLike"
	case FilterOr:
		return "FilterOr"
	case FilterAnd:
		return "FilterAnd"
	default:
		return ""
	}
}

func FilterOperatorFromString(s string) FilterOperator {
	switch s {
	case "FilterEqual":
		return FilterEqual
	case "FilterNEqual":
		return FilterNEqual
	case "FilterGreaterThan":
		return FilterGreaterThan
	case "FilterGreaterThanEqual":
		return FilterGreaterThanEqual
	case "FilterLessThan":
		return FilterLessThan
	case "FilterLessThanEqual":
		return FilterLessThanEqual
	case "FilterIn":
		return FilterIn
	case "FilterNotIn":
		return FilterNotIn
	case "FilterBetween":
		return FilterBetween
	case "FilterNotBetween":
		return FilterNotBetween
	case "FilterLike":
		return FilterLike
	case "FilterNotLike":
		return FilterNotLike
	case "FilterOr":
		return FilterOr
	case "FilterAnd":
		return FilterAnd
	default:
		return 0
	}
}

func (s FilterOperator) MarshalJSON() ([]byte, error) {
	buffer := bytes.NewBufferString(`"`)
	buffer.WriteString(s.String())
	buffer.WriteString(`"`)

	return buffer.Bytes(), nil
}

func (s *FilterOperator) UnmarshalJSON(b []byte) error {
	var j string

	err := json.Unmarshal(b, &j)
	if err != nil {
		return err
	}

	*s = FilterOperatorFromString(j)

	return nil
}

type ScalarOperand[T any] struct {
	Operand T `json:"operand" toml:"operand" yaml:"operand"`
}

type RangeOperand[T any] struct {
	Start T `json:"start" toml:"start" yaml:"start"`
	End   T `json:"end" toml:"end" yaml:"end"`
}

type ListOperand[T any] struct {
	Operands []T `json:"operands" toml:"operands" yaml:"operands"`
}

type CompoundOperand[T any] struct {
	LHS FilterOperation[T] `json:"lhs" toml:"lhs" yaml:"lhs"`
	RHS FilterOperation[T] `json:"rhs" toml:"rhs" yaml:"rhs"`
}

type Operand[T any] interface {
	OperandDummyMethod()
}

// TODO: Find a way to have such marshallers but allow users to support their own through plugins

func (s *FilterOperation[T]) UnmarshalJSON(b []byte) error {
	tmpOperation := map[string]json.RawMessage{}
	tmpOperand := map[string]json.RawMessage{}

	err := json.Unmarshal(b, &tmpOperation)
	if err != nil {
		return err
	}

	err = json.Unmarshal(tmpOperation["operator"], &s.Operator)
	if err != nil {
		return err
	}
	err = json.Unmarshal(tmpOperation["operand"], &tmpOperand)
	if err != nil {
		return err
	}

	if _, ok := tmpOperand["operand"]; ok {
		operand := ScalarOperand[T]{}

		err = json.Unmarshal(tmpOperation["operand"], &operand)
		if err != nil {
			return err
		}

		s.Operand = operand

	} else if _, ok := tmpOperand["start"]; ok {
		operand := RangeOperand[T]{}
		err = json.Unmarshal(tmpOperation["operand"], &operand)
		if err != nil {
			return err
		}

		s.Operand = operand
	} else if _, ok := tmpOperand["operands"]; ok {
		operand := ListOperand[T]{}
		err = json.Unmarshal(tmpOperation["operand"], &operand)
		if err != nil {
			return err
		}

		s.Operand = operand
	} else if _, ok := tmpOperand["lhs"]; ok {
		operand := CompoundOperand[T]{}
		err = json.Unmarshal(tmpOperation["operand"], &operand)
		if err != nil {
			return err
		}

		s.Operand = operand
	}

	return nil
}

func (o ScalarOperand[T]) OperandDummyMethod()   {}
func (o RangeOperand[T]) OperandDummyMethod()    {}
func (o ListOperand[T]) OperandDummyMethod()     {}
func (o CompoundOperand[T]) OperandDummyMethod() {}

type FilterOperation[T any] struct {
	Operand  Operand[T]     `json:"operand" toml:"operand" yaml:"operand"`
	Operator FilterOperator `json:"operator" toml:"operator" yaml:"operator"`
}

func ConvertFilter[TOut any, TIn any](from FilterOperation[TIn], operandConverter func(fromOperator TIn) (TOut, error)) (FilterOperation[TOut], error) {

2262e6247cc52c677cf3989b33bb76ec84543177

@github-actions github-actions bot added the todo label Aug 24, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

0 participants