go.chromium.org/luci@v0.0.0-20240309015107-7cdc2e660f33/analysis/internal/pagination/page_token.go (about) 1 // Copyright 2022 The LUCI Authors. 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 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package pagination 16 17 import ( 18 "encoding/base64" 19 20 "google.golang.org/grpc/codes" 21 "google.golang.org/protobuf/proto" 22 23 "go.chromium.org/luci/grpc/appstatus" 24 25 paginationpb "go.chromium.org/luci/analysis/internal/pagination/proto" 26 ) 27 28 // ParseToken extracts a string slice position from the given page token. 29 // May return an appstatus-annotated error. 30 func ParseToken(token string) ([]string, error) { 31 if token == "" { 32 return nil, nil 33 } 34 35 tokBytes, err := base64.StdEncoding.DecodeString(token) 36 if err != nil { 37 return nil, InvalidToken(err) 38 } 39 40 msg := &paginationpb.PageToken{} 41 if err := proto.Unmarshal(tokBytes, msg); err != nil { 42 return nil, InvalidToken(err) 43 } 44 return msg.Position, nil 45 } 46 47 // Token converts an string slice representing page token position to an opaque 48 // token string. 49 func Token(pos ...string) string { 50 if pos == nil { 51 return "" 52 } 53 54 msgBytes, err := proto.Marshal(&paginationpb.PageToken{Position: pos}) 55 if err != nil { 56 panic(err) 57 } 58 return base64.StdEncoding.EncodeToString(msgBytes) 59 } 60 61 // InvalidToken annotates the error with InvalidArgument appstatus. 62 func InvalidToken(err error) error { 63 return appstatus.Attachf(err, codes.InvalidArgument, "invalid page_token") 64 }