You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Stone supports [struct inheritance](https://github.com/dropbox/stone/blob/master/doc/lang_ref.rst#inheritance). In Go, we support this via [embedding](https://golang.org/doc/effective_go.html#embedding)
62
+
63
+
```
64
+
struct BasicAccount extends Account
65
+
"Basic information about any account."
66
+
67
+
is_teammate Boolean
68
+
"Whether this user is a teammate of the current user. If this account
69
+
is the current user's account, then this will be :val:`true`."
70
+
```
71
+
72
+
```go
73
+
// Basic information about any account.
74
+
typeBasicAccountstruct {
75
+
Account
76
+
// Whether this user is a teammate of the current user. If this account is
77
+
// the current user's account, then this will be `True`.
78
+
IsTeammatebool`json:"is_teammate"`
79
+
```
80
+
59
81
### Unions
60
82
61
-
Stone https://github.com/dropbox/stone/blob/master/doc/lang_ref.rst#union[unions] are bit more complex as Go doesn't have native support for union types (tagged or otherwise). We declare a union as a Go struct with all the possible fields as pointer types, and then use the tag value to populate the correct field during deserialization. This necessitates the use of an intermedia wrapper struct for the deserialization to work correctly, see below for a concrete example.
83
+
Stone https://github.com/dropbox/stone/blob/master/doc/lang_ref.rst#union[unions] are bit more complex as Go doesn't have native support for union types (tagged or otherwise). We declare a union as a Go struct with all the possible fields as pointer types, and then use the tag value to populate the correct field during deserialization. This necessitates the use of an intermediate wrapper struct for the deserialization to work correctly, see below for a concrete example.
62
84
63
85
```
64
86
union SpaceAllocation
@@ -72,101 +94,144 @@ union SpaceAllocation
72
94
73
95
```go
74
96
// Space is allocated differently based on the type of account.
75
-
typeSpaceAllocationstruct {// <1>
76
-
Tagstring`json:".tag"`// <2>
77
-
// The user's space allocation applies only to their individual account.
<2> The tag value is used to determine which field is actually set
115
-
<3> Possible values are represented as pointer types. Note the `omitempty` in the JSON tag; this is so values not set are automatically elided during serialization.
116
-
<4> We generate a custom `UnmarshalJSON` method for union types
117
-
<5> An intermedia wrapper struct is used to help with deserialization
118
-
<6> Note that members of the wrapper struct are of type `RawMessage` so we can capture the body without deserializing it right away
119
-
<7> When we deserialize response into the wrapper struct, it should get the tag value and the raw JSON as part of the members.
120
-
<8> We then use the tag value to deserialize the `RawMessage` into the appropriate member of the union type
121
140
122
141
### Struct with Enumerated Subtypes
123
142
124
143
Per the https://github.com/dropbox/stone/blob/master/doc/lang_ref.rst#struct-polymorphism[spec], structs with enumerated subtypes are a mechanism of inheritance:
125
144
126
-
> If a struct enumerates its subtypes, an instance of any subtype will satisfy the type constraint.
145
+
> If a struct enumerates its subtypes, an instance of any subtype will satisfy the type constraint. This is useful when wanting to discriminate amongst types that are part of the same hierarchy while simultaneously being able to avoid discriminating when accessing common fields.
127
146
128
-
So to represent structs with enumerated subtypes in Go, we use a strategy similar to unions. The _base_ struct (the one that defines the subtypes) is represented like we represent a union above. The _subtype_ is represented as a struct that essentially duplicates all fields of the base type and includes fields specific to that subtype. Here's an example:
147
+
To represent structs with enumerated subtypes in Go, we use a combination of Go interface types and unions as implemented above. Considering the following:
129
148
130
149
```
131
150
structMetadata
132
-
"Metadata for a file or folder."
133
-
134
151
union
135
152
file FileMetadata
136
153
folder FolderMetadata
137
154
deleted DeletedMetadata # Used by list_folder* and search
138
155
139
-
name String #<1>
140
-
"The last component of the path (including extension).
141
-
This never contains a slash."
142
-
143
-
...
156
+
name String
157
+
path_lower String?
158
+
path_display String?
159
+
parent_shared_folder_id common.SharedFolderId?
160
+
144
161
structFileMetadata extends Metadata
145
-
id Id? #<2>
146
-
...
162
+
id Id
163
+
client_modified common.DropboxTimestamp
164
+
...
147
165
```
148
-
<1> Field common to all subtypes
149
-
<2> Field specific to `FileMetadata`
150
166
167
+
In this case, `FileMetadata`, `FolderMetadata` etc are subtypes of `Metadata`. Specifically, any subtype can be used where a parent type is expected. Thus, if `list_folder` returns a list of `Metadata`s, we should be able to parse and "upcast" to one of the enumerated subtypes.
168
+
169
+
First, we define structs to represent the base and enumerated types as we did for inherited structs above:
0 commit comments