github.com/cosmos/cosmos-proto@v1.0.0-beta.3/support/timepb/cmp.go (about)

     1  package timepb
     2  
     3  import (
     4  	"fmt"
     5  	"time"
     6  
     7  	durpb "google.golang.org/protobuf/types/known/durationpb"
     8  	tspb "google.golang.org/protobuf/types/known/timestamppb"
     9  )
    10  
    11  // IsZero returns true only when t is nil
    12  func IsZero(t *tspb.Timestamp) bool {
    13  	return t == nil
    14  }
    15  
    16  // Commpare t1 and t2 and returns -1 when t1 < t2, 0 when t1 == t2 and 1 otherwise.
    17  // Returns false if t1 or t2 is nil
    18  func Compare(t1, t2 *tspb.Timestamp) int {
    19  	if t1 == nil || t2 == nil {
    20  		panic(fmt.Sprint("Can't compare nil time, t1=", t1, "t2=", t2))
    21  	}
    22  	if t1.Seconds == t2.Seconds && t1.Nanos == t2.Nanos {
    23  		return 0
    24  	}
    25  	if t1.Seconds < t2.Seconds || t1.Seconds == t2.Seconds && t1.Nanos < t2.Nanos {
    26  		return -1
    27  	}
    28  	return 1
    29  }
    30  
    31  // DurationIsNegative returns true if the duration is negative. It assumes that d is valid
    32  // (d..CheckValid() is nil).
    33  func DurationIsNegative(d *durpb.Duration) bool {
    34  	return d.Seconds < 0 || d.Seconds == 0 && d.Nanos < 0
    35  }
    36  
    37  // AddStd returns a new timestamp with value t + d, where d is stdlib Duration.
    38  // If t is nil then nil is returned.
    39  // Panics on overflow.
    40  func AddStd(t *tspb.Timestamp, d time.Duration) *tspb.Timestamp {
    41  	if t == nil {
    42  		return nil
    43  	}
    44  	if d == 0 {
    45  		t2 := *t
    46  		return &t2
    47  	}
    48  	t2 := tspb.New(t.AsTime().Add(d))
    49  	overflowPanic(t, t2, d < 0)
    50  	return t2
    51  }
    52  
    53  func overflowPanic(t1, t2 *tspb.Timestamp, negative bool) {
    54  	cmp := Compare(t1, t2)
    55  	if negative {
    56  		if cmp < 0 {
    57  			panic("time overflow")
    58  		}
    59  	} else {
    60  		if cmp > 0 {
    61  			panic("time overflow")
    62  		}
    63  	}
    64  }
    65  
    66  const second = int32(time.Second)
    67  
    68  // Add returns a new timestamp with value t + d, where d is protobuf Duration
    69  // If t is nil then nil is returned. Panics on overflow.
    70  // Note: d must be a valid PB Duration (d..CheckValid() is nil).
    71  func Add(t *tspb.Timestamp, d *durpb.Duration) *tspb.Timestamp {
    72  	if t == nil {
    73  		return nil
    74  	}
    75  	if d.Seconds == 0 && d.Nanos == 0 {
    76  		t2 := *t
    77  		return &t2
    78  	}
    79  	t2 := tspb.Timestamp{
    80  		Seconds: t.Seconds + d.Seconds,
    81  		Nanos:   t.Nanos + d.Nanos,
    82  	}
    83  	if t2.Nanos >= second {
    84  		t2.Nanos -= second
    85  		t2.Seconds++
    86  	} else if t2.Nanos <= -second {
    87  		t2.Nanos += second
    88  		t2.Seconds--
    89  	}
    90  	overflowPanic(t, &t2, DurationIsNegative(d))
    91  	return &t2
    92  }