github.com/prebid/prebid-server@v0.275.0/currency/rates.go (about)

     1  package currency
     2  
     3  import (
     4  	"errors"
     5  
     6  	"golang.org/x/text/currency"
     7  )
     8  
     9  // Rates holds data as represented on https://cdn.jsdelivr.net/gh/prebid/currency-file@1/latest.json
    10  // note that `DataAsOfRaw` field is needed when parsing remote JSON as the date format if not standard and requires
    11  // custom parsing to be properly set as Golang time.Time
    12  type Rates struct {
    13  	Conversions map[string]map[string]float64 `json:"conversions"`
    14  }
    15  
    16  // NewRates creates a new Rates object holding currencies rates
    17  func NewRates(conversions map[string]map[string]float64) *Rates {
    18  	return &Rates{
    19  		Conversions: conversions,
    20  	}
    21  }
    22  
    23  // GetRate returns the conversion rate between two currencies or:
    24  //   - An error if one of the currency strings is not well-formed
    25  //   - An error if any of the currency strings is not a recognized currency code.
    26  //   - A ConversionNotFoundError in case the conversion rate between the two
    27  //     given currencies is not in the currencies rates map
    28  func (r *Rates) GetRate(from, to string) (float64, error) {
    29  	var err error
    30  	fromUnit, err := currency.ParseISO(from)
    31  	if err != nil {
    32  		return 0, err
    33  	}
    34  	toUnit, err := currency.ParseISO(to)
    35  	if err != nil {
    36  		return 0, err
    37  	}
    38  	if fromUnit.String() == toUnit.String() {
    39  		return 1, nil
    40  	}
    41  	if r.Conversions != nil {
    42  		if conversion, present := r.Conversions[fromUnit.String()][toUnit.String()]; present {
    43  			// In case we have an entry FROM -> TO
    44  			return conversion, nil
    45  		} else if conversion, present := r.Conversions[toUnit.String()][fromUnit.String()]; present {
    46  			// In case we have an entry TO -> FROM
    47  			return 1 / conversion, nil
    48  		}
    49  		return 0, ConversionNotFoundError{FromCur: fromUnit.String(), ToCur: toUnit.String()}
    50  	}
    51  	return 0, errors.New("rates are nil")
    52  }
    53  
    54  // GetRates returns current rates
    55  func (r *Rates) GetRates() *map[string]map[string]float64 {
    56  	return &r.Conversions
    57  }