JeremiahRo
JeremiahRo

Reputation: 15

Reuse a method on a struct

I have a method that takes a URL to a yaml file and unmarshals it into a struct. There's nothing unique about it so I'd like to use it on another struct.

type SWConfig struct {
    Name      string `yaml:"name"`
    Version   string `yaml:"version"`
    BuildType string `yaml:"buildType"`
}

func (c *SWConfig) getConfiguration(url string) {
    resp, err := http.Get(url)
    if err != nil {
        log.Fatalf("ERROR: GET request failed: %s\n", err.Error())
    }
    if resp.StatusCode != http.StatusOK {
        log.Fatalf("ERROR: %v:  %s\n", resp.Status, url)
    }
    source, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        log.Fatalf("ERROR: could not read response: %s\n", err.Error())
    }
    err = yaml.Unmarshal(source, c)
    if err != nil {
        log.Fatalf("ERROR: could not read YAML: %s\n", err.Error())
    }
}

var swConfig SWConfig
swConfig.getConfiguration(swURL)
fmt.Println(swConfig.Name)

The other struct would have different fields, but again that shouldn't matter for this method. Is it possible to reuse this method or do I need to convert it to a function?

Upvotes: 0

Views: 113

Answers (1)

iragoden
iragoden

Reputation: 66

Use this utility function. It works with a pointer to any type.

// fetchYAML unmarshals the YAML document at url to the value 
// pointed to by v.
func fetchYAML(url string, v interface{}) error {
    resp, err := http.Get(url)
    if err != nil {
        return err
    }
    if resp.StatusCode != http.StatusOK {
        return fmt.Errorf("bad status: %v:  %s\n", resp.Status, url)
    }
    source, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        return err
    }
    err = yaml.Unmarshal(source, v)
    return err
}

Call it like this:

func (c *SWConfig) getConfiguration(url string) {
    if err := fetchYAML(url, c); err != nil {
        log.Fatalf("ERROR: get value failed: %s\n", err.Error())
    }
}

Upvotes: 5

Related Questions