Add intermediate type for autoscale policies
diff --git a/rackspace/autoscale/v1/policies/fixtures.go b/rackspace/autoscale/v1/policies/fixtures.go
index ac54268..67967b0 100644
--- a/rackspace/autoscale/v1/policies/fixtures.go
+++ b/rackspace/autoscale/v1/policies/fixtures.go
@@ -130,19 +130,21 @@
 var (
 	// WebhookPolicy is a Policy corresponding to the first result in PolicyListBody.
 	WebhookPolicy = Policy{
-		ID:            "2b48d247-0282-4b9d-8775-5c4b67e8e649",
-		Name:          "webhook policy",
-		Type:          Webhook,
-		Cooldown:      300,
-		ChangePercent: 3.3,
+		ID:              "2b48d247-0282-4b9d-8775-5c4b67e8e649",
+		Name:            "webhook policy",
+		Type:            Webhook,
+		Cooldown:        300,
+		AdjustmentType:  ChangePercent,
+		AdjustmentValue: 3.3,
 	}
 
 	// OneTimePolicy is a Policy corresponding to the second result in PolicyListBody.
 	OneTimePolicy = Policy{
-		ID:     "c175c31e-65f9-41de-8b15-918420d3253e",
-		Name:   "one time",
-		Type:   Schedule,
-		Change: float64(-1),
+		ID:              "c175c31e-65f9-41de-8b15-918420d3253e",
+		Name:            "one time",
+		Type:            Schedule,
+		AdjustmentType:  Change,
+		AdjustmentValue: float64(-1),
 		Args: map[string]interface{}{
 			"at": "2020-04-01T23:00:00.000Z",
 		},
@@ -153,7 +155,8 @@
 		ID:              "e785e3e7-af9e-4f3c-99ae-b80a532e1663",
 		Name:            "sunday afternoon",
 		Type:            Schedule,
-		DesiredCapacity: float64(2),
+		AdjustmentType:  DesiredCapacity,
+		AdjustmentValue: float64(2),
 		Args: map[string]interface{}{
 			"cron": "59 15 * * 0",
 		},
diff --git a/rackspace/autoscale/v1/policies/requests.go b/rackspace/autoscale/v1/policies/requests.go
index 25747b8..bc7a8fe 100644
--- a/rackspace/autoscale/v1/policies/requests.go
+++ b/rackspace/autoscale/v1/policies/requests.go
@@ -31,16 +31,6 @@
 	ToPolicyCreateMap() ([]map[string]interface{}, error)
 }
 
-// AdjustmentType represents the way in which a policy will change a group.
-type AdjustmentType string
-
-// Valid types of adjustments for a policy.
-const (
-	Change          AdjustmentType = "change"
-	ChangePercent   AdjustmentType = "changePercent"
-	DesiredCapacity AdjustmentType = "desiredCapacity"
-)
-
 // CreateOpts is a slice of CreateOpt structs that allow the user to create
 // multiple policies in a single operation.
 type CreateOpts []CreateOpt
diff --git a/rackspace/autoscale/v1/policies/results.go b/rackspace/autoscale/v1/policies/results.go
index b304e9d..95d03ca 100644
--- a/rackspace/autoscale/v1/policies/results.go
+++ b/rackspace/autoscale/v1/policies/results.go
@@ -18,12 +18,16 @@
 	}
 
 	var response struct {
-		Policy Policy `mapstructure:"policy"`
+		Policy policy `mapstructure:"policy"`
 	}
 
-	err := mapstructure.Decode(r.Body, &response)
+	if err := mapstructure.Decode(r.Body, &response); err != nil {
+		return nil, err
+	}
 
-	return &response.Policy, err
+	policy := response.Policy.toExported()
+
+	return &policy, nil
 }
 
 // CreateResult represents the result of a create operation.
@@ -62,33 +66,6 @@
 	gophercloud.ErrResult
 }
 
-// Policy represents a scaling policy.
-type Policy struct {
-	// UUID for the policy.
-	ID string `mapstructure:"id" json:"id"`
-
-	// Name of the policy.
-	Name string `mapstructure:"name" json:"name"`
-
-	// Type of scaling policy.
-	Type Type `mapstructure:"type" json:"type"`
-
-	// Cooldown period, in seconds.
-	Cooldown int `mapstructure:"cooldown" json:"cooldown"`
-
-	// Number of servers added or, if negative, removed.
-	Change interface{} `mapstructure:"change" json:"change"`
-
-	// Percent change to make in the number of servers.
-	ChangePercent interface{} `mapstructure:"changePercent" json:"changePercent"`
-
-	// Desired capacity of the of the associated group.
-	DesiredCapacity interface{} `mapstructure:"desiredCapacity" json:"desiredCapacity"`
-
-	// Additional configuration options for some types of policy.
-	Args map[string]interface{} `mapstructure:"args" json:"args"`
-}
-
 // Type represents a type of scaling policy.
 type Type string
 
@@ -100,6 +77,83 @@
 	Webhook Type = "webhook"
 )
 
+// AdjustmentType represents the way in which a policy will change a group.
+type AdjustmentType string
+
+// Valid types of adjustments for a policy.
+const (
+	Change          AdjustmentType = "change"
+	ChangePercent   AdjustmentType = "changePercent"
+	DesiredCapacity AdjustmentType = "desiredCapacity"
+)
+
+// Policy represents a scaling policy.
+type Policy struct {
+	// UUID for the policy.
+	ID string
+
+	// Name of the policy.
+	Name string
+
+	// Type of scaling policy.
+	Type Type
+
+	// Cooldown period, in seconds.
+	Cooldown int
+
+	// The type of adjustment in capacity to be made.
+	AdjustmentType AdjustmentType
+
+	// The numeric value of the adjustment in capacity.
+	AdjustmentValue float64
+
+	// Additional configuration options for some types of policy.
+	Args map[string]interface{}
+}
+
+// This is an intermediate representation of the exported Policy type.  The
+// fields in API responses vary by policy type and configuration.  This lets us
+// decode responses then normalize them into a Policy.
+type policy struct {
+	ID       string `mapstructure:"id"`
+	Name     string `mapstructure:"name"`
+	Type     Type   `mapstructure:"type"`
+	Cooldown int    `mapstructure:"cooldown"`
+
+	// The API will respond with exactly one of these omitting the others.
+	Change          interface{} `mapstructure:"change"`
+	ChangePercent   interface{} `mapstructure:"changePercent"`
+	DesiredCapacity interface{} `mapstructure:"desiredCapacity"`
+
+	// Additional configuration options for schedule policies.
+	Args map[string]interface{} `mapstructure:"args"`
+}
+
+// Assemble a Policy from the intermediate policy struct.
+func (p policy) toExported() Policy {
+	policy := Policy{}
+
+	policy.ID = p.ID
+	policy.Name = p.Name
+	policy.Type = p.Type
+	policy.Cooldown = p.Cooldown
+
+	policy.Args = p.Args
+
+	if v, ok := p.Change.(float64); ok {
+		policy.AdjustmentType = Change
+		policy.AdjustmentValue = v
+	} else if v, ok := p.ChangePercent.(float64); ok {
+		policy.AdjustmentType = ChangePercent
+		policy.AdjustmentValue = v
+	} else if v, ok := p.DesiredCapacity.(float64); ok {
+		policy.AdjustmentType = DesiredCapacity
+		policy.AdjustmentValue = v
+	}
+
+	return policy
+}
+
 // PolicyPage is the page returned by a pager when traversing over a collection
 // of scaling policies.
 type PolicyPage struct {
@@ -125,7 +179,7 @@
 
 func commonExtractPolicies(body interface{}) ([]Policy, error) {
 	var response struct {
-		Policies []Policy `mapstructure:"policies"`
+		Policies []policy `mapstructure:"policies"`
 	}
 
 	err := mapstructure.Decode(body, &response)
@@ -134,5 +188,11 @@
 		return nil, err
 	}
 
-	return response.Policies, err
+	policies := make([]Policy, len(response.Policies))
+
+	for i, p := range response.Policies {
+		policies[i] = p.toExported()
+	}
+
+	return policies, nil
 }