JSON ==== While implementing your client app, you will want perform a variety of operations on data represented by Go stucts. For example, save/load data to/from :doc:`/servers/datastore`, or using any of the provided :doc:`/crypto/index`. All of these functions require byte slices and cannot operate directly on Go structs. To transform a Go struct into a byte slice, you will serialize the Go struct into JSON using the `Go JSON library`_, which is already imported into proj2.go_. In particular, you will want to use the following these two functions: .. function:: json.Marshal(v interface{}) ([]byte, err) * Converts an arbitrary Go value into a byte slice containing the JSON representation of the struct. * Only public fields are converted. Private fields (fields starting with a lowercase letter) are not marshaled into the output. * This function will automatically follow pointers and nested pointers when marshalling. :param v: Value to be converted into JSON. This can be any data type. :type v: interface{} :rtype: []byte, err **Examples:** .. code-block:: go uid := uuid.New() d, _ := json.Marshal(uid) // d is a []byte which can be converted easily back into a UUID .. code-block:: go type User struct { Username string Password string secret int } alice := &User{ "alice", "password", 42, } bytes, _ := json.Marshal(alice) userlib.DebugMsg("%s\n", string(bytes)) // {"Username":"alice","Password":"password"} .. function:: json.Unmarshal(v []byte, obj interface{}) (error) * Converts a byte slice generated by json.Marshal back into a Go struct. * Public fields are restored if present, and private fields will be default-initialized. * This function automatically generates nested pointers where needed to generate a valid struct. * This function will return an error if there is a type mismatch between the JSON and the struct (e.g. storing a string into a number field in a struct). :param v: Output from a call to json.Marshal :type v: []byte :param obj: Pointer to the Go struct where values will be loaded :type obj: interface{} :rtype: error **Examples:** .. code-block:: go uid := uuid.New() d, _ := json.Marshal(uid) var result UUID err := json.Unmarshal(d, &result) if err != nil { // Error! handle me } // Now you can use result as with any other struct variable in Go. .. code-block:: go type User struct { Username string Password string secret int } bytes := []byte("{\"Username\":\"alice\",\"Password\":\"password\"}") var alice User; json.Unmarshal(bytes, &alice) userlib.DebugMsg("%v\n", alice) // {alice password 0} .. _GO JSON library: https://golang.org/pkg/encoding/json/ .. _proj2.go: https://github.com/cs161-staff/project2-starter-code/blob/main/proj2.go