79 lines
1.4 KiB
Go
79 lines
1.4 KiB
Go
package tariff
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
|
|
"github.com/traefik/yaegi/interp"
|
|
"github.com/traefik/yaegi/stdlib"
|
|
)
|
|
|
|
type embed struct {
|
|
Charges float64 `mapstructure:"charges"`
|
|
Tax float64 `mapstructure:"tax"`
|
|
Formula string `mapstructure:"formula"`
|
|
|
|
calc func(float64) (float64, error)
|
|
}
|
|
|
|
func (t *embed) init() error {
|
|
if t.Formula == "" {
|
|
return nil
|
|
}
|
|
|
|
vm := interp.New(interp.Options{})
|
|
if err := vm.Use(stdlib.Symbols); err != nil {
|
|
return err
|
|
}
|
|
|
|
if _, err := vm.Eval(`import "math"`); err != nil {
|
|
return err
|
|
}
|
|
|
|
if _, err := vm.Eval("var price, charges, tax float64"); err != nil {
|
|
return err
|
|
}
|
|
|
|
if _, err := vm.Eval(fmt.Sprintf("charges = %f", t.Charges)); err != nil {
|
|
return err
|
|
}
|
|
|
|
if _, err := vm.Eval(fmt.Sprintf("tax = %f", t.Tax)); err != nil {
|
|
return err
|
|
}
|
|
|
|
prg, err := vm.Compile(t.Formula)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
t.calc = func(price float64) (float64, error) {
|
|
if _, err := vm.Eval(fmt.Sprintf("price = %f", price)); err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
res, err := vm.Execute(prg)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
if !res.CanFloat() {
|
|
return 0, errors.New("formula did not return a float value")
|
|
}
|
|
|
|
return res.Float(), nil
|
|
}
|
|
|
|
// test the formula
|
|
_, err = t.calc(0)
|
|
|
|
return err
|
|
}
|
|
|
|
func (t *embed) totalPrice(price float64) float64 {
|
|
if t.calc != nil {
|
|
res, _ := t.calc(price)
|
|
return res
|
|
}
|
|
return (price + t.Charges) * (1 + t.Tax)
|
|
}
|