Skip to content

Instantly share code, notes, and snippets.

@alco
Created July 4, 2014 02:00
Show Gist options
  • Save alco/7e9941aa4833855bcade to your computer and use it in GitHub Desktop.
Save alco/7e9941aa4833855bcade to your computer and use it in GitHub Desktop.
package main
import (
"fmt"
"log"
"reflect"
"time"
)
// User facing API. THE MOST IMPORTANT THING
type User struct {
Name string
Height float64
}
type Repository struct {
ID int `json:"id"`
Owner User `json:"owner"`
Name string `json:"name"`
Description string `json:"description"`
CreatedAt time.Time `json:"created_at"`
PushedAt time.Time `json:"pushed_at"`
UpdatedAt time.Time `json:"updated_at"`
}
// API for editing
type EditableRepository struct {
Repository
fields_to_update []string
}
// These are easily generated
func (r *EditableRepository) SetID(id int) {
r.ID = id
r.fields_to_update = append(r.fields_to_update, "ID")
}
func (r *EditableRepository) SetName(name string) {
r.Name = name
r.fields_to_update = append(r.fields_to_update, "Name")
}
func (r *EditableRepository) SetCreatedAt(date time.Time) {
r.CreatedAt = date
r.fields_to_update = append(r.fields_to_update, "CreatedAt")
}
// Get the type once
var rtype = reflect.TypeOf(Repository{})
func edit(user string, repo string, to_edit *EditableRepository) map[string]interface{} {
json := make(map[string]interface{})
for _, field := range to_edit.fields_to_update {
sfield, found := rtype.FieldByName(field)
if !found {
log.Fatal("You didn't write that code by hand, did you?")
}
json_field := sfield.Tag.Get("json")
rval := reflect.ValueOf(to_edit.Repository)
json[json_field] = rval.FieldByName(field).Interface()
}
return json
}
func main() {
r := EditableRepository{}
r.SetID(123)
r.SetName("name")
r.SetCreatedAt(time.Now())
result := edit("user", "repo", &r)
fmt.Printf("%#v\n", result)
}
map[string]interface {}{"id":123, "name":"name", "created_at":time.Time{sec:63540035905, nsec:0x107a2e5b, loc:(*time.Location)(0x170c00)}}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment