github.com/sberex/go-sberex@v1.8.2-0.20181113200658-ed96ac38f7d7/accounts/url.go (about) 1 // This file is part of the go-sberex library. The go-sberex library is 2 // free software: you can redistribute it and/or modify it under the terms 3 // of the GNU Lesser General Public License as published by the Free 4 // Software Foundation, either version 3 of the License, or (at your option) 5 // any later version. 6 // 7 // The go-sberex library is distributed in the hope that it will be useful, 8 // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser 10 // General Public License <http://www.gnu.org/licenses/> for more details. 11 12 package accounts 13 14 import ( 15 "encoding/json" 16 "errors" 17 "fmt" 18 "strings" 19 ) 20 21 // URL represents the canonical identification URL of a wallet or account. 22 // 23 // It is a simplified version of url.URL, with the important limitations (which 24 // are considered features here) that it contains value-copyable components only, 25 // as well as that it doesn't do any URL encoding/decoding of special characters. 26 // 27 // The former is important to allow an account to be copied without leaving live 28 // references to the original version, whereas the latter is important to ensure 29 // one single canonical form opposed to many allowed ones by the RFC 3986 spec. 30 // 31 // As such, these URLs should not be used outside of the scope of an Sberex 32 // wallet or account. 33 type URL struct { 34 Scheme string // Protocol scheme to identify a capable account backend 35 Path string // Path for the backend to identify a unique entity 36 } 37 38 // parseURL converts a user supplied URL into the accounts specific structure. 39 func parseURL(url string) (URL, error) { 40 parts := strings.Split(url, "://") 41 if len(parts) != 2 || parts[0] == "" { 42 return URL{}, errors.New("protocol scheme missing") 43 } 44 return URL{ 45 Scheme: parts[0], 46 Path: parts[1], 47 }, nil 48 } 49 50 // String implements the stringer interface. 51 func (u URL) String() string { 52 if u.Scheme != "" { 53 return fmt.Sprintf("%s://%s", u.Scheme, u.Path) 54 } 55 return u.Path 56 } 57 58 // TerminalString implements the log.TerminalStringer interface. 59 func (u URL) TerminalString() string { 60 url := u.String() 61 if len(url) > 32 { 62 return url[:31] + "…" 63 } 64 return url 65 } 66 67 // MarshalJSON implements the json.Marshaller interface. 68 func (u URL) MarshalJSON() ([]byte, error) { 69 return json.Marshal(u.String()) 70 } 71 72 // Cmp compares x and y and returns: 73 // 74 // -1 if x < y 75 // 0 if x == y 76 // +1 if x > y 77 // 78 func (u URL) Cmp(url URL) int { 79 if u.Scheme == url.Scheme { 80 return strings.Compare(u.Path, url.Path) 81 } 82 return strings.Compare(u.Scheme, url.Scheme) 83 }