5
\$\begingroup\$

A Translator in the Terminal using Golang. It uses Google's API. Currently, it only translates en (English) to es (Spanish).

package main

import (
    "bufio"
    "encoding/json"
    "fmt"
    "io/ioutil"
    "net/http"
    "net/url"
    "os"
)

func (item *Result) UnmarshalJSON(data []byte) error {
    var v []interface{}
    if err := json.Unmarshal(data, &v); err != nil {
        fmt.Println(err)
        return err
    }
    item.Data = v[0].(interface{}).([]interface{})[0].([]interface{})[0].(string)
    return nil
}

type Result struct {
    Data interface{}
}

func main() {
    fmt.Printf("\nEnter text\t: ")
    scanner := bufio.NewScanner(os.Stdin)
    scanner.Scan()
    query := scanner.Text()
    response, err := http.Get("https://translate.googleapis.com/translate_a/single?client=gtx&sl=en&tl=es&dt=t&q=" + url.QueryEscape(query))
    if err != nil {
        fmt.Println(err)
        os.Exit(1)
    } else {
        defer response.Body.Close()
        bytes, err := ioutil.ReadAll(response.Body)
        if err != nil {
            fmt.Println(err)
            os.Exit(1)
        }
        var result Result
        if err := json.Unmarshal(bytes, &result); err != nil {
            fmt.Println(err)
        }
        value := result.Data
        fmt.Printf("Translation\t: %s\n", value)
    }
}
\$\endgroup\$
4
\$\begingroup\$

In several places you use fmt.Println followed by os.Exit. You may create your own Exit function to write error message to stderr and terminate.

Note: it is common practice to write error messages to stderr. stdout is for program output - translated text in your case.


item.Data = v[0].(interface{}).([]interface{})[0].([]interface{})[0].(string)

This statement will trigger a panic someday. I bet you need some recover.


if err := json.Unmarshal(bytes, &result); err != nil {

Hm, you've shaded previous err. Do you need one more error variable? When you use := operator, it will declare all missing variables on the left that doesnt present in current scope. Example:

str := "What??"
if str != "" {
    str := ""
    fmt.Printf("str is '%s'\n", str)
}
if str != "" { panic(str) }

Other notes:

  • I see you've used bufio.Scanner to get first line from input. You may consider reading all via ioutil.ReadAll. This way one may pipe some text to your program: cat ./text.txt | go-translate
  • No need for else branch in main function
  • value variable is used only once. You may pass result.Data directly to fmt.Printf call.

Example:

func Exit(err interface{}) {
    fmt.Fprint(os.Stderr, err)
    os.Exit(1)
}

func main() {
    fmt.Fprint(os.Stderr, "\nEnter text\t: ")

    scanner := bufio.NewScanner(os.Stdin)
    scanner.Scan()
    query := scanner.Text()

    response, err := http.Get("https://translate.googleapis.com/translate_a/single?client=gtx&sl=en&tl=es&dt=t&q=" + url.QueryEscape(query))
    if err != nil {
       Exit(err)
    }
    defer response.Body.Close()

    bytes, err := ioutil.ReadAll(response.Body)
    if err != nil {
        Exit(err)
    }

    var result Result
    if err = json.Unmarshal(bytes, &result); err != nil {
         Exit(err)
    }

    fmt.Printf("Translation\t: %s\n", result.Data)
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.