"Fossies" - the Fresh Open Source Software Archive

Member "protobuf-3.21.1/examples/go/cmd/add_person/add_person.go" (27 May 2022, 3363 Bytes) of package /linux/misc/protobuf-all-3.21.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Go source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

    1 package main
    2 
    3 import (
    4     "bufio"
    5     "fmt"
    6     "io"
    7     "io/ioutil"
    8     "log"
    9     "os"
   10     "strings"
   11 
   12     pb "github.com/protocolbuffers/protobuf/examples/go/tutorialpb"
   13     "google.golang.org/protobuf/proto"
   14 )
   15 
   16 func promptForAddress(r io.Reader) (*pb.Person, error) {
   17     // A protocol buffer can be created like any struct.
   18     p := &pb.Person{}
   19 
   20     rd := bufio.NewReader(r)
   21     fmt.Print("Enter person ID number: ")
   22     // An int32 field in the .proto file is represented as an int32 field
   23     // in the generated Go struct.
   24     if _, err := fmt.Fscanf(rd, "%d\n", &p.Id); err != nil {
   25         return p, err
   26     }
   27 
   28     fmt.Print("Enter name: ")
   29     name, err := rd.ReadString('\n')
   30     if err != nil {
   31         return p, err
   32     }
   33     // A string field in the .proto file results in a string field in Go.
   34     // We trim the whitespace because rd.ReadString includes the trailing
   35     // newline character in its output.
   36     p.Name = strings.TrimSpace(name)
   37 
   38     fmt.Print("Enter email address (blank for none): ")
   39     email, err := rd.ReadString('\n')
   40     if err != nil {
   41         return p, err
   42     }
   43     p.Email = strings.TrimSpace(email)
   44 
   45     for {
   46         fmt.Print("Enter a phone number (or leave blank to finish): ")
   47         phone, err := rd.ReadString('\n')
   48         if err != nil {
   49             return p, err
   50         }
   51         phone = strings.TrimSpace(phone)
   52         if phone == "" {
   53             break
   54         }
   55         // The PhoneNumber message type is nested within the Person
   56         // message in the .proto file.  This results in a Go struct
   57         // named using the name of the parent prefixed to the name of
   58         // the nested message.  Just as with pb.Person, it can be
   59         // created like any other struct.
   60         pn := &pb.Person_PhoneNumber{
   61             Number: phone,
   62         }
   63 
   64         fmt.Print("Is this a mobile, home, or work phone? ")
   65         ptype, err := rd.ReadString('\n')
   66         if err != nil {
   67             return p, err
   68         }
   69         ptype = strings.TrimSpace(ptype)
   70 
   71         // A proto enum results in a Go constant for each enum value.
   72         switch ptype {
   73         case "mobile":
   74             pn.Type = pb.Person_MOBILE
   75         case "home":
   76             pn.Type = pb.Person_HOME
   77         case "work":
   78             pn.Type = pb.Person_WORK
   79         default:
   80             fmt.Printf("Unknown phone type %q.  Using default.\n", ptype)
   81         }
   82 
   83         // A repeated proto field maps to a slice field in Go.  We can
   84         // append to it like any other slice.
   85         p.Phones = append(p.Phones, pn)
   86     }
   87 
   88     return p, nil
   89 }
   90 
   91 // Main reads the entire address book from a file, adds one person based on
   92 // user input, then writes it back out to the same file.
   93 func main() {
   94     if len(os.Args) != 2 {
   95         log.Fatalf("Usage:  %s ADDRESS_BOOK_FILE\n", os.Args[0])
   96     }
   97     fname := os.Args[1]
   98 
   99     // Read the existing address book.
  100     in, err := ioutil.ReadFile(fname)
  101     if err != nil {
  102         if os.IsNotExist(err) {
  103             fmt.Printf("%s: File not found.  Creating new file.\n", fname)
  104         } else {
  105             log.Fatalln("Error reading file:", err)
  106         }
  107     }
  108 
  109     // [START marshal_proto]
  110     book := &pb.AddressBook{}
  111     // [START_EXCLUDE]
  112     if err := proto.Unmarshal(in, book); err != nil {
  113         log.Fatalln("Failed to parse address book:", err)
  114     }
  115 
  116     // Add an address.
  117     addr, err := promptForAddress(os.Stdin)
  118     if err != nil {
  119         log.Fatalln("Error with address:", err)
  120     }
  121     book.People = append(book.People, addr)
  122     // [END_EXCLUDE]
  123 
  124     // Write the new address book back to disk.
  125     out, err := proto.Marshal(book)
  126     if err != nil {
  127         log.Fatalln("Failed to encode address book:", err)
  128     }
  129     if err := ioutil.WriteFile(fname, out, 0644); err != nil {
  130         log.Fatalln("Failed to write address book:", err)
  131     }
  132     // [END marshal_proto]
  133 }