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  }