824dbe6e47a7b133fd661712be971c2e2af4218b
[yangtools.git] / common / util / src / main / java / org / opendaylight / yangtools / util / OptionalBoolean.java
1 /*
2  * Copyright (c) 2017 Pantheon Technologies, s.r.o. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.yangtools.util;
9
10 import com.google.common.annotations.Beta;
11 import java.util.Optional;
12 import javax.annotation.Nullable;
13
14 /**
15  * Utility class for storing an optional boolean in a single byte value. This cuts down the memory requirement quite
16  * at very small computational cost.
17  *
18  * <p>
19  * Note: fields do not have to be explicitly initialized, as default initialization value for 'byte', 0, is used to
20  *       represent 'absent' condition.
21  *
22  * @author Robert Varga
23  */
24 @Beta
25 public final class OptionalBoolean {
26     private static final byte ABSENT = 0;
27     private static final byte FALSE = 1;
28     private static final byte TRUE = 2;
29
30     private OptionalBoolean() {
31         throw new UnsupportedOperationException();
32     }
33
34     /**
35      * Check if a field value has been set, just like {@link Optional#isPresent()}.
36      *
37      * @param value field value
38      * @return True if the value is set.
39      * @throws IllegalArgumentException if value is invalid
40      */
41     public static boolean isPresent(final byte value) {
42         switch (value) {
43             case ABSENT:
44                 return false;
45             case FALSE:
46             case TRUE:
47                 return true;
48             default:
49                 throw invalidValue(value);
50         }
51     }
52
53     /**
54      * Decode boolean from a field value, just like {@link Optional#get()}.
55      *
56      * @param value Field value
57      * @return Decoded boolean.
58      * @throws IllegalArgumentException if value is invalid
59      * @throws IllegalStateException if value has not been set
60      */
61     public static boolean get(final byte value) {
62         switch (value) {
63             case ABSENT:
64                 throw new IllegalStateException("Field has not been initialized");
65             case FALSE:
66                 return false;
67             case TRUE:
68                 return true;
69             default:
70                 throw invalidValue(value);
71         }
72     }
73
74     /**
75      * Encode a boolean to a field value, just like {@link Optional#of(Object)}.
76      *
77      * @param bool Boolean value.
78      * @return Field value.
79      */
80     public static byte of(final boolean bool) {
81         return bool ? TRUE : FALSE;
82     }
83
84     /**
85      * Convert a nullable {@link Boolean} into a field value, just like {@link Optional#ofNullable(Object)}.
86      *
87      * @param bool Boolean value.
88      * @return Field value.
89      */
90     public static byte ofNullable(final @Nullable Boolean bool) {
91         return bool == null ? ABSENT : of(bool.booleanValue());
92     }
93
94     /**
95      * Convert a field value to a nullable {@link Boolean}. Similar to {@code Optional.orElse(null)}.
96      *
97      * @param value Fied value.
98      * @return Nullable Boolean.
99      */
100     public static @Nullable Boolean toNullable(final byte value) {
101         switch (value) {
102             case ABSENT:
103                 return null;
104             case FALSE:
105                 return Boolean.FALSE;
106             case TRUE:
107                 return Boolean.TRUE;
108             default:
109                 throw invalidValue(value);
110         }
111     }
112
113     /**
114      * Convert a field value into an {@link Optional} {@link Boolean}.
115      *
116      * @param value Field value.
117      * @return Optional {@link Boolean}.
118      * @throws IllegalArgumentException if value is invalid.
119      */
120     public static Optional<Boolean> toOptional(final byte value) {
121         switch (value) {
122             case ABSENT:
123                 return Optional.empty();
124             case FALSE:
125                 return Optional.of(Boolean.FALSE);
126             case TRUE:
127                 return Optional.of(Boolean.TRUE);
128             default:
129                 throw invalidValue(value);
130         }
131     }
132
133     /**
134      * Convert a field value into a String representation.
135      *
136      * @param value Field value.
137      * @return Boolean-compatible string, or "absent".
138      * @throws IllegalArgumentException if value is invalid.
139      */
140     public static String toString(final byte value) {
141         switch (value) {
142             case ABSENT:
143                 return "absent";
144             case FALSE:
145                 return Boolean.toString(false);
146             case TRUE:
147                 return Boolean.toString(true);
148             default:
149                 throw invalidValue(value);
150         }
151     }
152
153     private static IllegalArgumentException invalidValue(final byte value) {
154         throw new IllegalArgumentException("Invalid field value " + value);
155     }
156 }