github.com/gophercloud/gophercloud@v1.11.0/openstack/identity/v3/projects/results.go (about) 1 package projects 2 3 import ( 4 "encoding/json" 5 6 "github.com/gophercloud/gophercloud" 7 "github.com/gophercloud/gophercloud/pagination" 8 ) 9 10 // Option is a specific option defined at the API to enable features 11 // on a project. 12 type Option string 13 14 const ( 15 Immutable Option = "immutable" 16 ) 17 18 type projectResult struct { 19 gophercloud.Result 20 } 21 22 // GetResult is the result of a Get request. Call its Extract method to 23 // interpret it as a Project. 24 type GetResult struct { 25 projectResult 26 } 27 28 // CreateResult is the result of a Create request. Call its Extract method to 29 // interpret it as a Project. 30 type CreateResult struct { 31 projectResult 32 } 33 34 // DeleteResult is the result of a Delete request. Call its ExtractErr method to 35 // determine if the request succeeded or failed. 36 type DeleteResult struct { 37 gophercloud.ErrResult 38 } 39 40 // UpdateResult is the result of an Update request. Call its Extract method to 41 // interpret it as a Project. 42 type UpdateResult struct { 43 projectResult 44 } 45 46 // Project represents an OpenStack Identity Project. 47 type Project struct { 48 // IsDomain indicates whether the project is a domain. 49 IsDomain bool `json:"is_domain"` 50 51 // Description is the description of the project. 52 Description string `json:"description"` 53 54 // DomainID is the domain ID the project belongs to. 55 DomainID string `json:"domain_id"` 56 57 // Enabled is whether or not the project is enabled. 58 Enabled bool `json:"enabled"` 59 60 // ID is the unique ID of the project. 61 ID string `json:"id"` 62 63 // Name is the name of the project. 64 Name string `json:"name"` 65 66 // ParentID is the parent_id of the project. 67 ParentID string `json:"parent_id"` 68 69 // Tags is the list of tags associated with the project. 70 Tags []string `json:"tags,omitempty"` 71 72 // Extra is free-form extra key/value pairs to describe the project. 73 Extra map[string]interface{} `json:"-"` 74 75 // Options are defined options in the API to enable certain features. 76 Options map[Option]interface{} `json:"options,omitempty"` 77 } 78 79 func (r *Project) UnmarshalJSON(b []byte) error { 80 type tmp Project 81 var s struct { 82 tmp 83 Extra map[string]interface{} `json:"extra"` 84 } 85 err := json.Unmarshal(b, &s) 86 if err != nil { 87 return err 88 } 89 *r = Project(s.tmp) 90 91 // Collect other fields and bundle them into Extra 92 // but only if a field titled "extra" wasn't sent. 93 if s.Extra != nil { 94 r.Extra = s.Extra 95 } else { 96 var result interface{} 97 err := json.Unmarshal(b, &result) 98 if err != nil { 99 return err 100 } 101 if resultMap, ok := result.(map[string]interface{}); ok { 102 r.Extra = gophercloud.RemainingKeys(Project{}, resultMap) 103 } 104 } 105 106 return err 107 } 108 109 // ProjectPage is a single page of Project results. 110 type ProjectPage struct { 111 pagination.LinkedPageBase 112 } 113 114 // IsEmpty determines whether or not a page of Projects contains any results. 115 func (r ProjectPage) IsEmpty() (bool, error) { 116 if r.StatusCode == 204 { 117 return true, nil 118 } 119 120 projects, err := ExtractProjects(r) 121 return len(projects) == 0, err 122 } 123 124 // NextPageURL extracts the "next" link from the links section of the result. 125 func (r ProjectPage) NextPageURL() (string, error) { 126 var s struct { 127 Links struct { 128 Next string `json:"next"` 129 Previous string `json:"previous"` 130 } `json:"links"` 131 } 132 err := r.ExtractInto(&s) 133 if err != nil { 134 return "", err 135 } 136 return s.Links.Next, err 137 } 138 139 // ExtractProjects returns a slice of Projects contained in a single page of 140 // results. 141 func ExtractProjects(r pagination.Page) ([]Project, error) { 142 var s struct { 143 Projects []Project `json:"projects"` 144 } 145 err := (r.(ProjectPage)).ExtractInto(&s) 146 return s.Projects, err 147 } 148 149 // Extract interprets any projectResults as a Project. 150 func (r projectResult) Extract() (*Project, error) { 151 var s struct { 152 Project *Project `json:"project"` 153 } 154 err := r.ExtractInto(&s) 155 return s.Project, err 156 }