| package pagination | 
 |  | 
 | import ( | 
 | 	"fmt" | 
 | 	"reflect" | 
 |  | 
 | 	"gerrit.mcp.mirantis.net/debian/gophercloud.git" | 
 | ) | 
 |  | 
 | // LinkedPageBase may be embedded to implement a page that provides navigational "Next" and "Previous" links within its result. | 
 | type LinkedPageBase struct { | 
 | 	PageResult | 
 |  | 
 | 	// LinkPath lists the keys that should be traversed within a response to arrive at the "next" pointer. | 
 | 	// If any link along the path is missing, an empty URL will be returned. | 
 | 	// If any link results in an unexpected value type, an error will be returned. | 
 | 	// When left as "nil", []string{"links", "next"} will be used as a default. | 
 | 	LinkPath []string | 
 | } | 
 |  | 
 | // NextPageURL extracts the pagination structure from a JSON response and returns the "next" link, if one is present. | 
 | // It assumes that the links are available in a "links" element of the top-level response object. | 
 | // If this is not the case, override NextPageURL on your result type. | 
 | func (current LinkedPageBase) NextPageURL() (string, error) { | 
 | 	var path []string | 
 | 	var key string | 
 |  | 
 | 	if current.LinkPath == nil { | 
 | 		path = []string{"links", "next"} | 
 | 	} else { | 
 | 		path = current.LinkPath | 
 | 	} | 
 |  | 
 | 	submap, ok := current.Body.(map[string]interface{}) | 
 | 	if !ok { | 
 | 		err := gophercloud.ErrUnexpectedType{} | 
 | 		err.Expected = "map[string]interface{}" | 
 | 		err.Actual = fmt.Sprintf("%v", reflect.TypeOf(current.Body)) | 
 | 		return "", err | 
 | 	} | 
 |  | 
 | 	for { | 
 | 		key, path = path[0], path[1:len(path)] | 
 |  | 
 | 		value, ok := submap[key] | 
 | 		if !ok { | 
 | 			return "", nil | 
 | 		} | 
 |  | 
 | 		if len(path) > 0 { | 
 | 			submap, ok = value.(map[string]interface{}) | 
 | 			if !ok { | 
 | 				err := gophercloud.ErrUnexpectedType{} | 
 | 				err.Expected = "map[string]interface{}" | 
 | 				err.Actual = fmt.Sprintf("%v", reflect.TypeOf(value)) | 
 | 				return "", err | 
 | 			} | 
 | 		} else { | 
 | 			if value == nil { | 
 | 				// Actual null element. | 
 | 				return "", nil | 
 | 			} | 
 |  | 
 | 			url, ok := value.(string) | 
 | 			if !ok { | 
 | 				err := gophercloud.ErrUnexpectedType{} | 
 | 				err.Expected = "string" | 
 | 				err.Actual = fmt.Sprintf("%v", reflect.TypeOf(value)) | 
 | 				return "", err | 
 | 			} | 
 |  | 
 | 			return url, nil | 
 | 		} | 
 | 	} | 
 | } | 
 |  | 
 | // IsEmpty satisifies the IsEmpty method of the Page interface | 
 | func (current LinkedPageBase) IsEmpty() (bool, error) { | 
 | 	if b, ok := current.Body.([]interface{}); ok { | 
 | 		return len(b) == 0, nil | 
 | 	} | 
 | 	err := gophercloud.ErrUnexpectedType{} | 
 | 	err.Expected = "[]interface{}" | 
 | 	err.Actual = fmt.Sprintf("%v", reflect.TypeOf(current.Body)) | 
 | 	return true, err | 
 | } | 
 |  | 
 | // GetBody returns the linked page's body. This method is needed to satisfy the | 
 | // Page interface. | 
 | func (current LinkedPageBase) GetBody() interface{} { | 
 | 	return current.Body | 
 | } |