github.com/gophercloud/gophercloud@v1.11.0/openstack/sharedfilesystems/v2/sharetransfers/results.go (about)

     1  package sharetransfers
     2  
     3  import (
     4  	"encoding/json"
     5  	"net/url"
     6  	"strconv"
     7  	"time"
     8  
     9  	"github.com/gophercloud/gophercloud"
    10  	"github.com/gophercloud/gophercloud/pagination"
    11  )
    12  
    13  const (
    14  	invalidMarker = "-1"
    15  )
    16  
    17  // Transfer represents a Share Transfer record.
    18  type Transfer struct {
    19  	ID                   string              `json:"id"`
    20  	Accepted             bool                `json:"accepted"`
    21  	AuthKey              string              `json:"auth_key"`
    22  	Name                 string              `json:"name"`
    23  	SourceProjectID      string              `json:"source_project_id"`
    24  	DestinationProjectID string              `json:"destination_project_id"`
    25  	ResourceID           string              `json:"resource_id"`
    26  	ResourceType         string              `json:"resource_type"`
    27  	CreatedAt            time.Time           `json:"-"`
    28  	ExpiresAt            time.Time           `json:"-"`
    29  	Links                []map[string]string `json:"links"`
    30  }
    31  
    32  // UnmarshalJSON is our unmarshalling helper.
    33  func (r *Transfer) UnmarshalJSON(b []byte) error {
    34  	type tmp Transfer
    35  	var s struct {
    36  		tmp
    37  		CreatedAt gophercloud.JSONRFC3339MilliNoZ `json:"created_at"`
    38  		ExpiresAt gophercloud.JSONRFC3339MilliNoZ `json:"expires_at"`
    39  	}
    40  	err := json.Unmarshal(b, &s)
    41  	if err != nil {
    42  		return err
    43  	}
    44  	*r = Transfer(s.tmp)
    45  
    46  	r.CreatedAt = time.Time(s.CreatedAt)
    47  	r.ExpiresAt = time.Time(s.ExpiresAt)
    48  
    49  	return err
    50  }
    51  
    52  type commonResult struct {
    53  	gophercloud.Result
    54  }
    55  
    56  // Extract will get the Transfer object out of the commonResult object.
    57  func (r commonResult) Extract() (*Transfer, error) {
    58  	var s Transfer
    59  	err := r.ExtractInto(&s)
    60  	return &s, err
    61  }
    62  
    63  // ExtractInto converts our response data into a transfer struct.
    64  func (r commonResult) ExtractInto(v interface{}) error {
    65  	return r.Result.ExtractIntoStructPtr(v, "transfer")
    66  }
    67  
    68  // CreateResult contains the response body and error from a Create request.
    69  type CreateResult struct {
    70  	commonResult
    71  }
    72  
    73  // GetResult contains the response body and error from a Get request.
    74  type GetResult struct {
    75  	commonResult
    76  }
    77  
    78  // DeleteResult contains the response body and error from a Delete request.
    79  type DeleteResult struct {
    80  	gophercloud.ErrResult
    81  }
    82  
    83  // AcceptResult contains the response body and error from an Accept request.
    84  type AcceptResult struct {
    85  	gophercloud.ErrResult
    86  }
    87  
    88  // ExtractTransfers extracts and returns Transfers. It is used while iterating over a transfers.List call.
    89  func ExtractTransfers(r pagination.Page) ([]Transfer, error) {
    90  	var s []Transfer
    91  	err := ExtractTransfersInto(r, &s)
    92  	return s, err
    93  }
    94  
    95  // ExtractTransfersInto similar to ExtractInto but operates on a `list` of transfers
    96  func ExtractTransfersInto(r pagination.Page, v interface{}) error {
    97  	return r.(TransferPage).Result.ExtractIntoSlicePtr(v, "transfers")
    98  }
    99  
   100  // TransferPage is a pagination.pager that is returned from a call to the List function.
   101  type TransferPage struct {
   102  	pagination.MarkerPageBase
   103  }
   104  
   105  // NextPageURL generates the URL for the page of results after this one.
   106  func (r TransferPage) NextPageURL() (string, error) {
   107  	currentURL := r.URL
   108  	mark, err := r.Owner.LastMarker()
   109  	if err != nil {
   110  		return "", err
   111  	}
   112  	if mark == invalidMarker {
   113  		return "", nil
   114  	}
   115  
   116  	q := currentURL.Query()
   117  	q.Set("offset", mark)
   118  	currentURL.RawQuery = q.Encode()
   119  	return currentURL.String(), nil
   120  }
   121  
   122  // LastMarker returns the last offset in a ListResult.
   123  func (r TransferPage) LastMarker() (string, error) {
   124  	replicas, err := ExtractTransfers(r)
   125  	if err != nil {
   126  		return invalidMarker, err
   127  	}
   128  	if len(replicas) == 0 {
   129  		return invalidMarker, nil
   130  	}
   131  
   132  	u, err := url.Parse(r.URL.String())
   133  	if err != nil {
   134  		return invalidMarker, err
   135  	}
   136  	queryParams := u.Query()
   137  	offset := queryParams.Get("offset")
   138  	limit := queryParams.Get("limit")
   139  
   140  	// Limit is not present, only one page required
   141  	if limit == "" {
   142  		return invalidMarker, nil
   143  	}
   144  
   145  	iOffset := 0
   146  	if offset != "" {
   147  		iOffset, err = strconv.Atoi(offset)
   148  		if err != nil {
   149  			return invalidMarker, err
   150  		}
   151  	}
   152  	iLimit, err := strconv.Atoi(limit)
   153  	if err != nil {
   154  		return invalidMarker, err
   155  	}
   156  	iOffset = iOffset + iLimit
   157  	offset = strconv.Itoa(iOffset)
   158  
   159  	return offset, nil
   160  }
   161  
   162  // IsEmpty satisifies the IsEmpty method of the Page interface.
   163  func (r TransferPage) IsEmpty() (bool, error) {
   164  	if r.StatusCode == 204 {
   165  		return true, nil
   166  	}
   167  
   168  	replicas, err := ExtractTransfers(r)
   169  	return len(replicas) == 0, err
   170  }