github.com/lyft/flytestdlib@v0.3.12-0.20210213045714-8cdd111ecda1/config/port.go (about)

     1  package config
     2  
     3  import (
     4  	"encoding/json"
     5  	"errors"
     6  	"fmt"
     7  	"strconv"
     8  )
     9  
    10  // A common port struct that supports Json marshal/unmarshal into/from simple strings/floats.
    11  type Port struct {
    12  	Port int `json:"port,omitempty"`
    13  }
    14  
    15  func (p Port) String() string {
    16  	return strconv.Itoa(p.Port)
    17  }
    18  
    19  func (p Port) MarshalJSON() ([]byte, error) {
    20  	return json.Marshal(p.Port)
    21  }
    22  
    23  func (p *Port) UnmarshalJSON(b []byte) error {
    24  	var v interface{}
    25  	if err := json.Unmarshal(b, &v); err != nil {
    26  		return err
    27  	}
    28  
    29  	switch value := v.(type) {
    30  	case string:
    31  		u, err := parsePortString(value)
    32  		if err != nil {
    33  			return err
    34  		}
    35  
    36  		p.Port = u
    37  		return nil
    38  	case float64:
    39  		if !validPortRange(value) {
    40  			return fmt.Errorf("port must be a valid number between 0 and 65535, inclusive")
    41  		}
    42  
    43  		p.Port = int(value)
    44  		return nil
    45  	default:
    46  		return errors.New("invalid port")
    47  	}
    48  }
    49  
    50  func parsePortString(port string) (int, error) {
    51  	if portInt, err := strconv.Atoi(port); err == nil && validPortRange(float64(portInt)) {
    52  		return portInt, nil
    53  	}
    54  
    55  	return 0, fmt.Errorf("port must be a valid number between 1 and 65535, inclusive")
    56  }
    57  
    58  func validPortRange(port float64) bool {
    59  	return 0 <= port && port <= 65535
    60  }