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

     1  package zero
     2  
     3  import (
     4  	"database/sql"
     5  	"encoding/json"
     6  	"errors"
     7  	"fmt"
     8  	"reflect"
     9  )
    10  
    11  // Bool is a nullable bool. False input is considered null.
    12  // JSON marshals to false if null.
    13  // Considered null to SQL unmarshaled from a false value.
    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 be null if false.
    29  func BoolFrom(b bool) Bool {
    30  	return NewBool(b, b)
    31  }
    32  
    33  // BoolFromPtr creates a new Bool that be null if b 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  // UnmarshalJSON implements json.Unmarshaler.
    42  // "false" will be considered a null Bool.
    43  // It also supports unmarshalling a sql.NullBool.
    44  func (b *Bool) UnmarshalJSON(data []byte) error {
    45  	var err error
    46  	var v interface{}
    47  	if err = json.Unmarshal(data, &v); err != nil {
    48  		return err
    49  	}
    50  	switch x := v.(type) {
    51  	case bool:
    52  		b.Bool = x
    53  	case map[string]interface{}:
    54  		err = json.Unmarshal(data, &b.NullBool)
    55  	case nil:
    56  		b.Valid = false
    57  		return nil
    58  	default:
    59  		err = fmt.Errorf("json: cannot unmarshal %v into Go value of type zero.Bool", reflect.TypeOf(v).Name())
    60  	}
    61  	b.Valid = (err == nil) && b.Bool
    62  	return err
    63  }
    64  
    65  // UnmarshalText implements encoding.TextUnmarshaler.
    66  // It will unmarshal to a null Bool if the input is a false or not a bool.
    67  // It will return an error if the input is not a float, blank, or "null".
    68  func (b *Bool) UnmarshalText(text []byte) error {
    69  	str := string(text)
    70  	switch str {
    71  	case "", "null":
    72  		b.Valid = false
    73  		return nil
    74  	case "true":
    75  		b.Bool = true
    76  	case "false":
    77  		b.Bool = false
    78  	default:
    79  		b.Valid = false
    80  		return errors.New("invalid input:" + str)
    81  	}
    82  	b.Valid = b.Bool
    83  	return nil
    84  }
    85  
    86  // MarshalJSON implements json.Marshaler.
    87  // It will encode null if this Bool is null.
    88  func (b Bool) MarshalJSON() ([]byte, error) {
    89  	if !b.Valid || !b.Bool {
    90  		return []byte("false"), nil
    91  	}
    92  	return []byte("true"), nil
    93  }
    94  
    95  // MarshalText implements encoding.TextMarshaler.
    96  // It will encode a zero if this Bool is null.
    97  func (b Bool) MarshalText() ([]byte, error) {
    98  	if !b.Valid || !b.Bool {
    99  		return []byte("false"), nil
   100  	}
   101  	return []byte("true"), nil
   102  }
   103  
   104  // SetValid changes this Bool's value and also sets it to be non-null.
   105  func (b *Bool) SetValid(v bool) {
   106  	b.Bool = v
   107  	b.Valid = true
   108  }
   109  
   110  // Ptr returns a poBooler to this Bool's value, or a nil poBooler if this Bool is null.
   111  func (b Bool) Ptr() *bool {
   112  	if !b.Valid {
   113  		return nil
   114  	}
   115  	return &b.Bool
   116  }
   117  
   118  // IsZero returns true for null or zero Bools, for future omitempty support (Go 1.4?)
   119  func (b Bool) IsZero() bool {
   120  	return !b.Valid || !b.Bool
   121  }