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