Created
July 31, 2013 13:20
-
-
Save icub3d/6121908 to your computer and use it in GitHub Desktop.
Protobuf in Go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main; | |
message Person { | |
required string name = 1; | |
required int32 id = 2; | |
optional string email = 3; | |
enum PhoneType { | |
MOBILE = 0; | |
HOME = 1; | |
WORK = 2; | |
} | |
message PhoneNumber { | |
required string number = 1; | |
optional PhoneType type = 2 [default = HOME]; | |
} | |
repeated PhoneNumber phone = 4; | |
} | |
message AddressBook { | |
repeated Person person = 1; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$ protoc --go_out=. addressbook.proto | |
$ go build | |
$ ./addressbook | |
proto> new | |
ID: 1 | |
Name: josh | |
Email: [email protected] | |
Phone (blank to finish): 801-879-2250 | |
Type (home,work,mobile): mobile | |
Phone (blank to finish): | |
proto> write data | |
proto> quit | |
$ ./addressbook | |
proto> list | |
proto> read data | |
proto> list | |
name:"josh" id:1 email:"[email protected]" phone:<number:"801-879-2250" type:MOBILE > | |
proto> quit |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"bufio" | |
"code.google.com/p/goprotobuf/proto" | |
"fmt" | |
"io/ioutil" | |
"os" | |
"strconv" | |
"strings" | |
) | |
var addressbook AddressBook | |
func main() { | |
scanner := bufio.NewScanner(os.Stdin) | |
quit := false | |
for !quit { | |
fmt.Print("proto> ") | |
if !scanner.Scan() { | |
break | |
} | |
line := scanner.Text() | |
parts := strings.Split(line, " ") | |
cmd := parts[0] | |
args := parts[1:] | |
switch cmd { | |
case "list": | |
for _, p := range addressbook.Person { | |
fmt.Println(p) | |
} | |
case "find": | |
for _, p := range addressbook.Person { | |
if strconv.Itoa(int(*p.Id)) == args[0] { | |
fmt.Println(p) | |
break | |
} | |
} | |
case "new": | |
if !newPerson(scanner) { | |
quit = true | |
break | |
} | |
case "read": | |
if err := read(args[0]); err != nil { | |
fmt.Println(err) | |
} | |
case "write": | |
if err := write(args[0]); err != nil { | |
fmt.Println(err) | |
} | |
case "quit": | |
quit = true | |
default: | |
fmt.Println("unrecognized command:", cmd, args) | |
} | |
} | |
if err := scanner.Err(); err != nil { | |
fmt.Println("reading stdin:", err) | |
} | |
} | |
func write(filename string) error { | |
b, err := proto.Marshal(&addressbook) | |
if err != nil { | |
return fmt.Errorf("encoding addressbook:", err) | |
} | |
return ioutil.WriteFile(filename, b, os.ModePerm) | |
} | |
func read(filename string) error { | |
file, err := os.Open(filename) | |
if err != nil { | |
return fmt.Errorf("opening file:", err) | |
} | |
defer file.Close() | |
b, err := ioutil.ReadAll(file) | |
if err != nil { | |
return fmt.Errorf("reading file:", err) | |
} | |
err = proto.Unmarshal(b, &addressbook) | |
if err != nil { | |
return fmt.Errorf("decoding file:", err) | |
} | |
return nil | |
} | |
func newPerson(scanner *bufio.Scanner) bool { | |
fmt.Print("ID: ") | |
if !scanner.Scan() { | |
return false | |
} | |
i, err := strconv.ParseInt(scanner.Text(), 10, 32) | |
if err != nil { | |
return false | |
} | |
var id int32 = int32(i) | |
fmt.Print("Name: ") | |
if !scanner.Scan() { | |
return false | |
} | |
name := scanner.Text() | |
fmt.Print("Email: ") | |
if !scanner.Scan() { | |
return false | |
} | |
email := scanner.Text() | |
p := &Person{ | |
Id: &id, | |
Name: &name, | |
Email: &email, | |
} | |
for { | |
fmt.Print("Phone (blank to finish): ") | |
if !scanner.Scan() { | |
return false | |
} | |
number := scanner.Text() | |
if number == "" { | |
break | |
} | |
fmt.Print("Type (home,work,mobile): ") | |
if !scanner.Scan() { | |
return false | |
} | |
numberType := Person_HOME | |
switch scanner.Text() { | |
case "work": | |
numberType = Person_WORK | |
case "mobile": | |
numberType = Person_MOBILE | |
case "home": | |
numberType = Person_HOME | |
default: | |
fmt.Println("unrecognized type, using 'home'") | |
} | |
p.Phone = append(p.Phone, &Person_PhoneNumber{ | |
Number: &number, | |
Type: &numberType, | |
}) | |
} | |
addressbook.Person = append(addressbook.Person, p) | |
return true | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment