# 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`](http://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.

```go
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.

```go
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**](https://www.exchangerate-api.com/) 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.

```go
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**](https://github.com/awabcodes/currency-switch).
