Building a Currency Converter in Go

Introduction

In this post, we'll create a practical currency converter Command-Line Interface app using Go. It enables you to swiftly convert between currencies without leaving your terminal.

Setting Up

Before diving into the code, make sure you have Go installed on your system. Additionally, we'll be using Cobra, a popular Go library for building CLI applications. You can install it using the following command:
go get -u github.com/spf13/cobra/cobra.

Designing the Currency Converter

Our currency converter CLI will take three arguments: the amount to convert, the source currency, and the target currency. It will fetch exchange rates from an external API and perform the conversion.

var rootCmd = &cobra.Command{
        Use:   "[amount] [source currency code] [target currency code]",
        Short: "convert amount to any currency",
        Long:  "convert amount from any currency to any other currency",
        Args:  cobra.ExactArgs(3),
        Run: func(cmd *cobra.Command, args []string) {
            amount, err := validateAmount(args[0])
            if err != nil {
                log.Fatal(err)
            }

            sourceCurrency, targetCurrency, err := validateCurrencyCodes(args[1], args[2])
            if err != nil {
                log.Fatal(err)
            }

            result, err := convertCurrency(amount, sourceCurrency, targetCurrency)
            if err != nil {
                log.Fatal(err)
            }

            log.Printf("%f %v is %f %v", amount, sourceCurrency, result, targetCurrency)
        },
    }

Validating User Input

We've included input validation to ensure that the user provides the correct number format for the amount and valid three-character currency codes for source and target currencies.

func validateAmount(amountInput string) (float64, error) {
    amount, err := strconv.ParseFloat(amountInput, 64)
    if err != nil {
        return 0, errors.New("Invalid amount. Please provide a valid number.")
    }

    return amount, nil
}

func validateCurrencyCodes(sourceCurrency string, targetCurrency string) (string, string, error) {
    re := regexp.MustCompile("^[a-zA-Z]{3}$")
    if !re.Match([]byte(sourceCurrency)) || !re.Match([]byte(targetCurrency)) {
        return "", "", errors.New("Invalid currency code(s). Currency codes must be 3 characters long (e.g., USD).")
    }

    return strings.ToUpper(sourceCurrency), strings.ToUpper(targetCurrency), nil
}

Fetching Exchange Rates

The convertCurrency function fetches exchange rates from an external API (ExchangeRate-API in this example) based on the source currency.

Performing Currency Conversion

Once we have the exchange rates, we can easily convert the amount from the source currency to the target currency using a simple formula.

func convertCurrency(amount float64, from string, to string) (float64, error) {
    res, err := http.Get("https://open.er-api.com/v6/latest/" + from)
    if err != nil {
        return 0, errors.New("Failed to retrieve exchange rates. Please try again later.")
    }

    defer res.Body.Close()

    body, err := io.ReadAll(res.Body)
    if err != nil {
        return 0, errors.New("Failed to read response body")
    }

    var exchangeRates ExchangeRates

    err = json.Unmarshal(body, &exchangeRates)
    if err != nil {
        return 0, errors.New("Failed to unmarshal json")
    }

    if exchangeRates.Result != "success" {
        return 0, errors.New("Exchange rate api failed to get the rates")
    }

    return amount * exchangeRates.Rates[to], nil
}

Usage

You can build and execute the script with the provided command, providing the amount, source currency and target currency. The converter will display the converted amount in the target currency.

./currency-switch 10 eur aed

Conclusion

In conclusion, we've created a simple yet effective currency converter CLI app in Go, enabling you to handle currency conversions with ease right from your terminal. Feel free to customize it to meet your specific requirements and take control of your currency conversions. Happy coding!

You can find the source code in this GitHub Repository.