Making server action result types more consistent
diff --git a/_site/openstack/identity/v3/tokens/results.go b/_site/openstack/identity/v3/tokens/results.go
new file mode 100644
index 0000000..1be98cb
--- /dev/null
+++ b/_site/openstack/identity/v3/tokens/results.go
@@ -0,0 +1,75 @@
+package tokens
+
+import (
+ "net/http"
+ "time"
+
+ "github.com/mitchellh/mapstructure"
+ "github.com/rackspace/gophercloud"
+)
+
+// commonResult is the deferred result of a Create or a Get call.
+type commonResult struct {
+ gophercloud.CommonResult
+
+ // header stores the headers from the original HTTP response because token responses are returned in an X-Subject-Token header.
+ header http.Header
+}
+
+// Extract interprets a commonResult as a Token.
+func (r commonResult) Extract() (*Token, error) {
+ if r.Err != nil {
+ return nil, r.Err
+ }
+
+ var response struct {
+ Token struct {
+ ExpiresAt string `mapstructure:"expires_at"`
+ } `mapstructure:"token"`
+ }
+
+ var token Token
+
+ // Parse the token itself from the stored headers.
+ token.ID = r.header.Get("X-Subject-Token")
+
+ err := mapstructure.Decode(r.Resp, &response)
+ if err != nil {
+ return nil, err
+ }
+
+ // Attempt to parse the timestamp.
+ token.ExpiresAt, err = time.Parse(gophercloud.RFC3339Milli, response.Token.ExpiresAt)
+
+ return &token, err
+}
+
+// CreateResult is the deferred response from a Create call.
+type CreateResult struct {
+ commonResult
+}
+
+// createErr quickly creates a CreateResult that reports an error.
+func createErr(err error) CreateResult {
+ return CreateResult{
+ commonResult: commonResult{
+ CommonResult: gophercloud.CommonResult{Err: err},
+ header: nil,
+ },
+ }
+}
+
+// GetResult is the deferred response from a Get call.
+type GetResult struct {
+ commonResult
+}
+
+// Token is a string that grants a user access to a controlled set of services in an OpenStack provider.
+// Each Token is valid for a set length of time.
+type Token struct {
+ // ID is the issued token.
+ ID string
+
+ // ExpiresAt is the timestamp at which this token will no longer be accepted.
+ ExpiresAt time.Time
+}