Source release 18.1.0
This commit is contained in:
133
third_party/protobuf/examples/go/cmd/add_person/add_person.go
vendored
Normal file
133
third_party/protobuf/examples/go/cmd/add_person/add_person.go
vendored
Normal file
@@ -0,0 +1,133 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
pb "github.com/protocolbuffers/protobuf/examples/go/tutorialpb"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
func promptForAddress(r io.Reader) (*pb.Person, error) {
|
||||
// A protocol buffer can be created like any struct.
|
||||
p := &pb.Person{}
|
||||
|
||||
rd := bufio.NewReader(r)
|
||||
fmt.Print("Enter person ID number: ")
|
||||
// An int32 field in the .proto file is represented as an int32 field
|
||||
// in the generated Go struct.
|
||||
if _, err := fmt.Fscanf(rd, "%d\n", &p.Id); err != nil {
|
||||
return p, err
|
||||
}
|
||||
|
||||
fmt.Print("Enter name: ")
|
||||
name, err := rd.ReadString('\n')
|
||||
if err != nil {
|
||||
return p, err
|
||||
}
|
||||
// A string field in the .proto file results in a string field in Go.
|
||||
// We trim the whitespace because rd.ReadString includes the trailing
|
||||
// newline character in its output.
|
||||
p.Name = strings.TrimSpace(name)
|
||||
|
||||
fmt.Print("Enter email address (blank for none): ")
|
||||
email, err := rd.ReadString('\n')
|
||||
if err != nil {
|
||||
return p, err
|
||||
}
|
||||
p.Email = strings.TrimSpace(email)
|
||||
|
||||
for {
|
||||
fmt.Print("Enter a phone number (or leave blank to finish): ")
|
||||
phone, err := rd.ReadString('\n')
|
||||
if err != nil {
|
||||
return p, err
|
||||
}
|
||||
phone = strings.TrimSpace(phone)
|
||||
if phone == "" {
|
||||
break
|
||||
}
|
||||
// The PhoneNumber message type is nested within the Person
|
||||
// message in the .proto file. This results in a Go struct
|
||||
// named using the name of the parent prefixed to the name of
|
||||
// the nested message. Just as with pb.Person, it can be
|
||||
// created like any other struct.
|
||||
pn := &pb.Person_PhoneNumber{
|
||||
Number: phone,
|
||||
}
|
||||
|
||||
fmt.Print("Is this a mobile, home, or work phone? ")
|
||||
ptype, err := rd.ReadString('\n')
|
||||
if err != nil {
|
||||
return p, err
|
||||
}
|
||||
ptype = strings.TrimSpace(ptype)
|
||||
|
||||
// A proto enum results in a Go constant for each enum value.
|
||||
switch ptype {
|
||||
case "mobile":
|
||||
pn.Type = pb.Person_MOBILE
|
||||
case "home":
|
||||
pn.Type = pb.Person_HOME
|
||||
case "work":
|
||||
pn.Type = pb.Person_WORK
|
||||
default:
|
||||
fmt.Printf("Unknown phone type %q. Using default.\n", ptype)
|
||||
}
|
||||
|
||||
// A repeated proto field maps to a slice field in Go. We can
|
||||
// append to it like any other slice.
|
||||
p.Phones = append(p.Phones, pn)
|
||||
}
|
||||
|
||||
return p, nil
|
||||
}
|
||||
|
||||
// Main reads the entire address book from a file, adds one person based on
|
||||
// user input, then writes it back out to the same file.
|
||||
func main() {
|
||||
if len(os.Args) != 2 {
|
||||
log.Fatalf("Usage: %s ADDRESS_BOOK_FILE\n", os.Args[0])
|
||||
}
|
||||
fname := os.Args[1]
|
||||
|
||||
// Read the existing address book.
|
||||
in, err := ioutil.ReadFile(fname)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
fmt.Printf("%s: File not found. Creating new file.\n", fname)
|
||||
} else {
|
||||
log.Fatalln("Error reading file:", err)
|
||||
}
|
||||
}
|
||||
|
||||
// [START marshal_proto]
|
||||
book := &pb.AddressBook{}
|
||||
// [START_EXCLUDE]
|
||||
if err := proto.Unmarshal(in, book); err != nil {
|
||||
log.Fatalln("Failed to parse address book:", err)
|
||||
}
|
||||
|
||||
// Add an address.
|
||||
addr, err := promptForAddress(os.Stdin)
|
||||
if err != nil {
|
||||
log.Fatalln("Error with address:", err)
|
||||
}
|
||||
book.People = append(book.People, addr)
|
||||
// [END_EXCLUDE]
|
||||
|
||||
// Write the new address book back to disk.
|
||||
out, err := proto.Marshal(book)
|
||||
if err != nil {
|
||||
log.Fatalln("Failed to encode address book:", err)
|
||||
}
|
||||
if err := ioutil.WriteFile(fname, out, 0644); err != nil {
|
||||
log.Fatalln("Failed to write address book:", err)
|
||||
}
|
||||
// [END marshal_proto]
|
||||
}
|
||||
58
third_party/protobuf/examples/go/cmd/add_person/add_person_test.go
vendored
Normal file
58
third_party/protobuf/examples/go/cmd/add_person/add_person_test.go
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
pb "github.com/protocolbuffers/protobuf/examples/go/tutorialpb"
|
||||
"google.golang.org/protobuf/proto"
|
||||
)
|
||||
|
||||
func TestPromptForAddressReturnsAddress(t *testing.T) {
|
||||
in := `12345
|
||||
Example Name
|
||||
name@example.com
|
||||
123-456-7890
|
||||
home
|
||||
222-222-2222
|
||||
mobile
|
||||
111-111-1111
|
||||
work
|
||||
777-777-7777
|
||||
unknown
|
||||
|
||||
`
|
||||
got, err := promptForAddress(strings.NewReader(in))
|
||||
if err != nil {
|
||||
t.Fatalf("promptForAddress(%q) had unexpected error: %s", in, err.Error())
|
||||
}
|
||||
if got.Id != 12345 {
|
||||
t.Errorf("promptForAddress(%q) got %d, want ID %d", in, got.Id, 12345)
|
||||
}
|
||||
if got.Name != "Example Name" {
|
||||
t.Errorf("promptForAddress(%q) => want name %q, got %q", in, "Example Name", got.Name)
|
||||
}
|
||||
if got.Email != "name@example.com" {
|
||||
t.Errorf("promptForAddress(%q) => want email %q, got %q", in, "name@example.com", got.Email)
|
||||
}
|
||||
|
||||
want := []*pb.Person_PhoneNumber{
|
||||
{Number: "123-456-7890", Type: pb.Person_HOME},
|
||||
{Number: "222-222-2222", Type: pb.Person_MOBILE},
|
||||
{Number: "111-111-1111", Type: pb.Person_WORK},
|
||||
{Number: "777-777-7777", Type: pb.Person_MOBILE},
|
||||
}
|
||||
if len(got.Phones) != len(want) {
|
||||
t.Errorf("want %d phone numbers, got %d", len(want), len(got.Phones))
|
||||
}
|
||||
phones := len(got.Phones)
|
||||
if phones > len(want) {
|
||||
phones = len(want)
|
||||
}
|
||||
for i := 0; i < phones; i++ {
|
||||
if !proto.Equal(got.Phones[i], want[i]) {
|
||||
t.Errorf("want phone %q, got %q", want[i], got.Phones[i])
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user