1// Copyright 2016 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//      http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15// Package optional provides versions of primitive types that can
16// be nil. These are useful in methods that update some of an API object's
17// fields.
18package optional
19
20import (
21	"fmt"
22	"strings"
23	"time"
24)
25
26type (
27	// Bool is either a bool or nil.
28	Bool interface{}
29
30	// String is either a string or nil.
31	String interface{}
32
33	// Int is either an int or nil.
34	Int interface{}
35
36	// Uint is either a uint or nil.
37	Uint interface{}
38
39	// Float64 is either a float64 or nil.
40	Float64 interface{}
41
42	// Duration is either a time.Duration or nil.
43	Duration interface{}
44)
45
46// ToBool returns its argument as a bool.
47// It panics if its argument is nil or not a bool.
48func ToBool(v Bool) bool {
49	x, ok := v.(bool)
50	if !ok {
51		doPanic("Bool", v)
52	}
53	return x
54}
55
56// ToString returns its argument as a string.
57// It panics if its argument is nil or not a string.
58func ToString(v String) string {
59	x, ok := v.(string)
60	if !ok {
61		doPanic("String", v)
62	}
63	return x
64}
65
66// ToInt returns its argument as an int.
67// It panics if its argument is nil or not an int.
68func ToInt(v Int) int {
69	x, ok := v.(int)
70	if !ok {
71		doPanic("Int", v)
72	}
73	return x
74}
75
76// ToUint returns its argument as a uint.
77// It panics if its argument is nil or not a uint.
78func ToUint(v Uint) uint {
79	x, ok := v.(uint)
80	if !ok {
81		doPanic("Uint", v)
82	}
83	return x
84}
85
86// ToFloat64 returns its argument as a float64.
87// It panics if its argument is nil or not a float64.
88func ToFloat64(v Float64) float64 {
89	x, ok := v.(float64)
90	if !ok {
91		doPanic("Float64", v)
92	}
93	return x
94}
95
96// ToDuration returns its argument as a time.Duration.
97// It panics if its argument is nil or not a time.Duration.
98func ToDuration(v Duration) time.Duration {
99	x, ok := v.(time.Duration)
100	if !ok {
101		doPanic("Duration", v)
102	}
103	return x
104}
105
106func doPanic(capType string, v interface{}) {
107	panic(fmt.Sprintf("optional.%s value should be %s, got %T", capType, strings.ToLower(capType), v))
108}
109