github.com/vnpaycloud-console/gophercloud/v2@v2.0.5/openstack/objectstorage/v1/containers/results.go (about) 1 package containers 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "strconv" 7 "strings" 8 "time" 9 10 "github.com/vnpaycloud-console/gophercloud/v2" 11 "github.com/vnpaycloud-console/gophercloud/v2/pagination" 12 ) 13 14 // Container represents a container resource. 15 type Container struct { 16 // The total number of bytes stored in the container. 17 Bytes int64 `json:"bytes"` 18 19 // The total number of objects stored in the container. 20 Count int64 `json:"count"` 21 22 // The name of the container. 23 Name string `json:"name"` 24 } 25 26 // ContainerPage is the page returned by a pager when traversing over a 27 // collection of containers. 28 type ContainerPage struct { 29 pagination.MarkerPageBase 30 } 31 32 // IsEmpty returns true if a ListResult contains no container names. 33 func (r ContainerPage) IsEmpty() (bool, error) { 34 if r.StatusCode == 204 { 35 return true, nil 36 } 37 38 names, err := ExtractNames(r) 39 return len(names) == 0, err 40 } 41 42 // LastMarker returns the last container name in a ListResult. 43 func (r ContainerPage) LastMarker() (string, error) { 44 names, err := ExtractNames(r) 45 if err != nil { 46 return "", err 47 } 48 if len(names) == 0 { 49 return "", nil 50 } 51 return names[len(names)-1], nil 52 } 53 54 // ExtractInfo is a function that takes a ListResult and returns the 55 // containers' information. 56 func ExtractInfo(r pagination.Page) ([]Container, error) { 57 var s []Container 58 err := (r.(ContainerPage)).ExtractInto(&s) 59 return s, err 60 } 61 62 // ExtractNames is a function that takes a ListResult and returns the 63 // containers' names. 64 func ExtractNames(page pagination.Page) ([]string, error) { 65 casted := page.(ContainerPage) 66 ct := casted.Header.Get("Content-Type") 67 68 switch { 69 case strings.HasPrefix(ct, "application/json"): 70 parsed, err := ExtractInfo(page) 71 if err != nil { 72 return nil, err 73 } 74 75 names := make([]string, 0, len(parsed)) 76 for _, container := range parsed { 77 names = append(names, container.Name) 78 } 79 return names, nil 80 case strings.HasPrefix(ct, "text/plain") || ct == "": 81 names := make([]string, 0, 50) 82 83 body := string(page.(ContainerPage).Body.([]uint8)) 84 for _, name := range strings.Split(body, "\n") { 85 if len(name) > 0 { 86 names = append(names, name) 87 } 88 } 89 90 return names, nil 91 default: 92 return nil, fmt.Errorf("Cannot extract names from response with content-type: [%s]", ct) 93 } 94 } 95 96 // GetHeader represents the headers returned in the response from a Get request. 97 type GetHeader struct { 98 AcceptRanges string `json:"Accept-Ranges"` 99 BytesUsed int64 `json:"X-Container-Bytes-Used,string"` 100 ContentLength int64 `json:"Content-Length,string"` 101 ContentType string `json:"Content-Type"` 102 Date time.Time `json:"-"` 103 ObjectCount int64 `json:"X-Container-Object-Count,string"` 104 Read []string `json:"-"` 105 TransID string `json:"X-Trans-Id"` 106 VersionsLocation string `json:"X-Versions-Location"` 107 HistoryLocation string `json:"X-History-Location"` 108 Write []string `json:"-"` 109 StoragePolicy string `json:"X-Storage-Policy"` 110 TempURLKey string `json:"X-Container-Meta-Temp-URL-Key"` 111 TempURLKey2 string `json:"X-Container-Meta-Temp-URL-Key-2"` 112 Timestamp float64 `json:"X-Timestamp,string"` 113 VersionsEnabled bool `json:"-"` 114 SyncKey string `json:"X-Sync-Key"` 115 SyncTo string `json:"X-Sync-To"` 116 } 117 118 func (r *GetHeader) UnmarshalJSON(b []byte) error { 119 type tmp GetHeader 120 var s struct { 121 tmp 122 Write string `json:"X-Container-Write"` 123 Read string `json:"X-Container-Read"` 124 Date gophercloud.JSONRFC1123 `json:"Date"` 125 VersionsEnabled string `json:"X-Versions-Enabled"` 126 } 127 128 err := json.Unmarshal(b, &s) 129 if err != nil { 130 return err 131 } 132 133 *r = GetHeader(s.tmp) 134 135 r.Read = strings.Split(s.Read, ",") 136 r.Write = strings.Split(s.Write, ",") 137 138 r.Date = time.Time(s.Date) 139 140 if s.VersionsEnabled != "" { 141 // custom unmarshaller here is required to handle boolean value 142 // that starts with a capital letter 143 r.VersionsEnabled, err = strconv.ParseBool(s.VersionsEnabled) 144 } 145 146 return err 147 } 148 149 // GetResult represents the result of a get operation. 150 type GetResult struct { 151 gophercloud.HeaderResult 152 } 153 154 // Extract will return a struct of headers returned from a call to Get. 155 func (r GetResult) Extract() (*GetHeader, error) { 156 var s GetHeader 157 err := r.ExtractInto(&s) 158 return &s, err 159 } 160 161 // ExtractMetadata is a function that takes a GetResult (of type *http.Response) 162 // and returns the custom metadata associated with the container. 163 func (r GetResult) ExtractMetadata() (map[string]string, error) { 164 if r.Err != nil { 165 return nil, r.Err 166 } 167 metadata := make(map[string]string) 168 for k, v := range r.Header { 169 if strings.HasPrefix(k, "X-Container-Meta-") { 170 key := strings.TrimPrefix(k, "X-Container-Meta-") 171 metadata[key] = v[0] 172 } 173 } 174 return metadata, nil 175 } 176 177 // CreateHeader represents the headers returned in the response from a Create 178 // request. 179 type CreateHeader struct { 180 ContentLength int64 `json:"Content-Length,string"` 181 ContentType string `json:"Content-Type"` 182 Date time.Time `json:"-"` 183 TransID string `json:"X-Trans-Id"` 184 } 185 186 func (r *CreateHeader) UnmarshalJSON(b []byte) error { 187 type tmp CreateHeader 188 var s struct { 189 tmp 190 Date gophercloud.JSONRFC1123 `json:"Date"` 191 } 192 err := json.Unmarshal(b, &s) 193 if err != nil { 194 return err 195 } 196 197 *r = CreateHeader(s.tmp) 198 199 r.Date = time.Time(s.Date) 200 201 return err 202 } 203 204 // CreateResult represents the result of a create operation. To extract the 205 // the headers from the HTTP response, call its Extract method. 206 type CreateResult struct { 207 gophercloud.HeaderResult 208 } 209 210 // Extract will return a struct of headers returned from a call to Create. 211 // To extract the headers from the HTTP response, call its Extract method. 212 func (r CreateResult) Extract() (*CreateHeader, error) { 213 var s CreateHeader 214 err := r.ExtractInto(&s) 215 return &s, err 216 } 217 218 // UpdateHeader represents the headers returned in the response from a Update 219 // request. 220 type UpdateHeader struct { 221 ContentLength int64 `json:"Content-Length,string"` 222 ContentType string `json:"Content-Type"` 223 Date time.Time `json:"-"` 224 TransID string `json:"X-Trans-Id"` 225 } 226 227 func (r *UpdateHeader) UnmarshalJSON(b []byte) error { 228 type tmp UpdateHeader 229 var s struct { 230 tmp 231 Date gophercloud.JSONRFC1123 `json:"Date"` 232 } 233 err := json.Unmarshal(b, &s) 234 if err != nil { 235 return err 236 } 237 238 *r = UpdateHeader(s.tmp) 239 240 r.Date = time.Time(s.Date) 241 242 return err 243 } 244 245 // UpdateResult represents the result of an update operation. To extract the 246 // the headers from the HTTP response, call its Extract method. 247 type UpdateResult struct { 248 gophercloud.HeaderResult 249 } 250 251 // Extract will return a struct of headers returned from a call to Update. 252 func (r UpdateResult) Extract() (*UpdateHeader, error) { 253 var s UpdateHeader 254 err := r.ExtractInto(&s) 255 return &s, err 256 } 257 258 // DeleteHeader represents the headers returned in the response from a Delete 259 // request. 260 type DeleteHeader struct { 261 ContentLength int64 `json:"Content-Length,string"` 262 ContentType string `json:"Content-Type"` 263 Date time.Time `json:"-"` 264 TransID string `json:"X-Trans-Id"` 265 } 266 267 func (r *DeleteHeader) UnmarshalJSON(b []byte) error { 268 type tmp DeleteHeader 269 var s struct { 270 tmp 271 Date gophercloud.JSONRFC1123 `json:"Date"` 272 } 273 err := json.Unmarshal(b, &s) 274 if err != nil { 275 return err 276 } 277 278 *r = DeleteHeader(s.tmp) 279 280 r.Date = time.Time(s.Date) 281 282 return err 283 } 284 285 // DeleteResult represents the result of a delete operation. To extract the 286 // headers from the HTTP response, call its Extract method. 287 type DeleteResult struct { 288 gophercloud.HeaderResult 289 } 290 291 // Extract will return a struct of headers returned from a call to Delete. 292 func (r DeleteResult) Extract() (*DeleteHeader, error) { 293 var s DeleteHeader 294 err := r.ExtractInto(&s) 295 return &s, err 296 } 297 298 type BulkDeleteResponse struct { 299 ResponseStatus string `json:"Response Status"` 300 ResponseBody string `json:"Response Body"` 301 Errors [][]string `json:"Errors"` 302 NumberDeleted int `json:"Number Deleted"` 303 NumberNotFound int `json:"Number Not Found"` 304 } 305 306 // BulkDeleteResult represents the result of a bulk delete operation. To extract 307 // the response object from the HTTP response, call its Extract method. 308 type BulkDeleteResult struct { 309 gophercloud.Result 310 } 311 312 // Extract will return a BulkDeleteResponse struct returned from a BulkDelete 313 // call. 314 func (r BulkDeleteResult) Extract() (*BulkDeleteResponse, error) { 315 var s BulkDeleteResponse 316 err := r.ExtractInto(&s) 317 return &s, err 318 }