github.com/graemephi/kahugo@v0.62.3-0.20211121071557-d78c0423784d/resources/page/pages.go (about)

     1  // Copyright 2019 The Hugo Authors. All rights reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  // http://www.apache.org/licenses/LICENSE-2.0
     7  //
     8  // Unless required by applicable law or agreed to in writing, software
     9  // distributed under the License is distributed on an "AS IS" BASIS,
    10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package page
    15  
    16  import (
    17  	"fmt"
    18  	"math/rand"
    19  
    20  	"github.com/gohugoio/hugo/compare"
    21  
    22  	"github.com/gohugoio/hugo/resources/resource"
    23  )
    24  
    25  var (
    26  	_ resource.ResourcesConverter = Pages{}
    27  	_ compare.ProbablyEqer        = Pages{}
    28  )
    29  
    30  // Pages is a slice of pages. This is the most common list type in Hugo.
    31  type Pages []Page
    32  
    33  func (ps Pages) String() string {
    34  	return fmt.Sprintf("Pages(%d)", len(ps))
    35  }
    36  
    37  // Used in tests.
    38  func (ps Pages) shuffle() {
    39  	for i := range ps {
    40  		j := rand.Intn(i + 1)
    41  		ps[i], ps[j] = ps[j], ps[i]
    42  	}
    43  }
    44  
    45  // ToResources wraps resource.ResourcesConverter
    46  func (pages Pages) ToResources() resource.Resources {
    47  	r := make(resource.Resources, len(pages))
    48  	for i, p := range pages {
    49  		r[i] = p
    50  	}
    51  	return r
    52  }
    53  
    54  // ToPages tries to convert seq into Pages.
    55  func ToPages(seq interface{}) (Pages, error) {
    56  	if seq == nil {
    57  		return Pages{}, nil
    58  	}
    59  
    60  	switch v := seq.(type) {
    61  	case Pages:
    62  		return v, nil
    63  	case *Pages:
    64  		return *(v), nil
    65  	case WeightedPages:
    66  		return v.Pages(), nil
    67  	case PageGroup:
    68  		return v.Pages, nil
    69  	case []Page:
    70  		pages := make(Pages, len(v))
    71  		for i, vv := range v {
    72  			pages[i] = vv
    73  		}
    74  		return pages, nil
    75  	case []interface{}:
    76  		pages := make(Pages, len(v))
    77  		success := true
    78  		for i, vv := range v {
    79  			p, ok := vv.(Page)
    80  			if !ok {
    81  				success = false
    82  				break
    83  			}
    84  			pages[i] = p
    85  		}
    86  		if success {
    87  			return pages, nil
    88  		}
    89  	}
    90  
    91  	return nil, fmt.Errorf("cannot convert type %T to Pages", seq)
    92  }
    93  
    94  func (p Pages) Group(key interface{}, in interface{}) (interface{}, error) {
    95  	pages, err := ToPages(in)
    96  	if err != nil {
    97  		return nil, err
    98  	}
    99  	return PageGroup{Key: key, Pages: pages}, nil
   100  }
   101  
   102  // Len returns the number of pages in the list.
   103  func (p Pages) Len() int {
   104  	return len(p)
   105  }
   106  
   107  // ProbablyEq wraps compare.ProbablyEqer
   108  func (pages Pages) ProbablyEq(other interface{}) bool {
   109  	otherPages, ok := other.(Pages)
   110  	if !ok {
   111  		return false
   112  	}
   113  
   114  	if len(pages) != len(otherPages) {
   115  		return false
   116  	}
   117  
   118  	step := 1
   119  
   120  	for i := 0; i < len(pages); i += step {
   121  		if !pages[i].Eq(otherPages[i]) {
   122  			return false
   123  		}
   124  
   125  		if i > 50 {
   126  			// This is most likely the same.
   127  			step = 50
   128  		}
   129  	}
   130  
   131  	return true
   132  }
   133  
   134  func (ps Pages) removeFirstIfFound(p Page) Pages {
   135  	ii := -1
   136  	for i, pp := range ps {
   137  		if p.Eq(pp) {
   138  			ii = i
   139  			break
   140  		}
   141  	}
   142  
   143  	if ii != -1 {
   144  		ps = append(ps[:ii], ps[ii+1:]...)
   145  	}
   146  	return ps
   147  }
   148  
   149  // PagesFactory somehow creates some Pages.
   150  // We do a lot of lazy Pages initialization in Hugo, so we need a type.
   151  type PagesFactory func() Pages