github.com/cgcardona/r-subnet-evm@v0.1.5/accounts/url.go (about)

     1  // (c) 2019-2020, Ava Labs, Inc.
     2  //
     3  // This file is a derived work, based on the go-ethereum library whose original
     4  // notices appear below.
     5  //
     6  // It is distributed under a license compatible with the licensing terms of the
     7  // original code from which it is derived.
     8  //
     9  // Much love to the original authors for their work.
    10  // **********
    11  // Copyright 2017 The go-ethereum Authors
    12  // This file is part of the go-ethereum library.
    13  //
    14  // The go-ethereum library is free software: you can redistribute it and/or modify
    15  // it under the terms of the GNU Lesser General Public License as published by
    16  // the Free Software Foundation, either version 3 of the License, or
    17  // (at your option) any later version.
    18  //
    19  // The go-ethereum library is distributed in the hope that it will be useful,
    20  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    21  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    22  // GNU Lesser General Public License for more details.
    23  //
    24  // You should have received a copy of the GNU Lesser General Public License
    25  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    26  
    27  package accounts
    28  
    29  import (
    30  	"encoding/json"
    31  	"errors"
    32  	"fmt"
    33  	"strings"
    34  )
    35  
    36  // URL represents the canonical identification URL of a wallet or account.
    37  //
    38  // It is a simplified version of url.URL, with the important limitations (which
    39  // are considered features here) that it contains value-copyable components only,
    40  // as well as that it doesn't do any URL encoding/decoding of special characters.
    41  //
    42  // The former is important to allow an account to be copied without leaving live
    43  // references to the original version, whereas the latter is important to ensure
    44  // one single canonical form opposed to many allowed ones by the RFC 3986 spec.
    45  //
    46  // As such, these URLs should not be used outside of the scope of an Ethereum
    47  // wallet or account.
    48  type URL struct {
    49  	Scheme string // Protocol scheme to identify a capable account backend
    50  	Path   string // Path for the backend to identify a unique entity
    51  }
    52  
    53  // parseURL converts a user supplied URL into the accounts specific structure.
    54  func parseURL(url string) (URL, error) {
    55  	parts := strings.Split(url, "://")
    56  	if len(parts) != 2 || parts[0] == "" {
    57  		return URL{}, errors.New("protocol scheme missing")
    58  	}
    59  	return URL{
    60  		Scheme: parts[0],
    61  		Path:   parts[1],
    62  	}, nil
    63  }
    64  
    65  // String implements the stringer interface.
    66  func (u URL) String() string {
    67  	if u.Scheme != "" {
    68  		return fmt.Sprintf("%s://%s", u.Scheme, u.Path)
    69  	}
    70  	return u.Path
    71  }
    72  
    73  // TerminalString implements the log.TerminalStringer interface.
    74  func (u URL) TerminalString() string {
    75  	url := u.String()
    76  	if len(url) > 32 {
    77  		return url[:31] + ".."
    78  	}
    79  	return url
    80  }
    81  
    82  // MarshalJSON implements the json.Marshaller interface.
    83  func (u URL) MarshalJSON() ([]byte, error) {
    84  	return json.Marshal(u.String())
    85  }
    86  
    87  // UnmarshalJSON parses url.
    88  func (u *URL) UnmarshalJSON(input []byte) error {
    89  	var textURL string
    90  	err := json.Unmarshal(input, &textURL)
    91  	if err != nil {
    92  		return err
    93  	}
    94  	url, err := parseURL(textURL)
    95  	if err != nil {
    96  		return err
    97  	}
    98  	u.Scheme = url.Scheme
    99  	u.Path = url.Path
   100  	return nil
   101  }
   102  
   103  // Cmp compares x and y and returns:
   104  //
   105  //	-1 if x <  y
   106  //	 0 if x == y
   107  //	+1 if x >  y
   108  func (u URL) Cmp(url URL) int {
   109  	if u.Scheme == url.Scheme {
   110  		return strings.Compare(u.Path, url.Path)
   111  	}
   112  	return strings.Compare(u.Scheme, url.Scheme)
   113  }