github.com/seeker-insurance/kit@v0.0.13/db/null/bool.go (about)

     1  package null
     2  
     3  import (
     4  	"database/sql"
     5  	"encoding/json"
     6  	"errors"
     7  	"fmt"
     8  	"reflect"
     9  )
    10  
    11  // Bool is a nullable bool.
    12  // It does not consider false values to be null.
    13  // It will decode to null, not false, if null.
    14  type Bool struct {
    15  	sql.NullBool
    16  }
    17  
    18  // NewBool creates a new Bool
    19  func NewBool(b bool, valid bool) Bool {
    20  	return Bool{
    21  		NullBool: sql.NullBool{
    22  			Bool:  b,
    23  			Valid: valid,
    24  		},
    25  	}
    26  }
    27  
    28  // BoolFrom creates a new Bool that will always be valid.
    29  func BoolFrom(b bool) Bool {
    30  	return NewBool(b, true)
    31  }
    32  
    33  // BoolFromPtr creates a new Bool that will be null if f is nil.
    34  func BoolFromPtr(b *bool) Bool {
    35  	if b == nil {
    36  		return NewBool(false, false)
    37  	}
    38  	return NewBool(*b, true)
    39  }
    40  
    41  // ValueOrZero returns the inner value if valid, otherwise false.
    42  func (b Bool) ValueOrZero() bool {
    43  	return b.Valid && b.Bool
    44  }
    45  
    46  // UnmarshalJSON implements json.Unmarshaler.
    47  // It supports number and null input.
    48  // 0 will not be considered a null Bool.
    49  // It also supports unmarshalling a sql.NullBool.
    50  func (b *Bool) UnmarshalJSON(data []byte) error {
    51  	var err error
    52  	var v interface{}
    53  	if err = json.Unmarshal(data, &v); err != nil {
    54  		return err
    55  	}
    56  	switch x := v.(type) {
    57  	case bool:
    58  		b.Bool = x
    59  	case map[string]interface{}:
    60  		err = json.Unmarshal(data, &b.NullBool)
    61  	case nil:
    62  		b.Valid = false
    63  		return nil
    64  	default:
    65  		err = fmt.Errorf("json: cannot unmarshal %v into Go value of type null.Bool", reflect.TypeOf(v).Name())
    66  	}
    67  	b.Valid = err == nil
    68  	return err
    69  }
    70  
    71  // UnmarshalText implements encoding.TextUnmarshaler.
    72  // It will unmarshal to a null Bool if the input is a blank or not an integer.
    73  // It will return an error if the input is not an integer, blank, or "null".
    74  func (b *Bool) UnmarshalText(text []byte) error {
    75  	str := string(text)
    76  	switch str {
    77  	case "", "null":
    78  		b.Valid = false
    79  		return nil
    80  	case "true":
    81  		b.Bool = true
    82  	case "false":
    83  		b.Bool = false
    84  	default:
    85  		b.Valid = false
    86  		return errors.New("invalid input:" + str)
    87  	}
    88  	b.Valid = true
    89  	return nil
    90  }
    91  
    92  // MarshalJSON implements json.Marshaler.
    93  // It will encode null if this Bool is null.
    94  func (b Bool) MarshalJSON() ([]byte, error) {
    95  	if !b.Valid {
    96  		return []byte("null"), nil
    97  	}
    98  	if !b.Bool {
    99  		return []byte("false"), nil
   100  	}
   101  	return []byte("true"), nil
   102  }
   103  
   104  // MarshalText implements encoding.TextMarshaler.
   105  // It will encode a blank string if this Bool is null.
   106  func (b Bool) MarshalText() ([]byte, error) {
   107  	if !b.Valid {
   108  		return []byte{}, nil
   109  	}
   110  	if !b.Bool {
   111  		return []byte("false"), nil
   112  	}
   113  	return []byte("true"), nil
   114  }
   115  
   116  // SetValid changes this Bool's value and also sets it to be non-null.
   117  func (b *Bool) SetValid(v bool) {
   118  	b.Bool = v
   119  	b.Valid = true
   120  }
   121  
   122  // Ptr returns a pointer to this Bool's value, or a nil pointer if this Bool is null.
   123  func (b Bool) Ptr() *bool {
   124  	if !b.Valid {
   125  		return nil
   126  	}
   127  	return &b.Bool
   128  }
   129  
   130  // IsZero returns true for invalid Bools, for future omitempty support (Go 1.4?)
   131  // A non-null Bool with a 0 value will not be considered zero.
   132  func (b Bool) IsZero() bool {
   133  	return !b.Valid
   134  }