import static com.google.common.base.Preconditions.checkArgument;
-import com.google.common.annotations.Beta;
import java.io.Serializable;
-import java.util.Objects;
import org.checkerframework.checker.index.qual.NonNegative;
import org.eclipse.jdt.annotation.NonNull;
/**
* A single version according to <a href="http://semver.org/">Semantic Versioning</a>.
+ *
+ * @param major Major version number
+ * @param minor Minor version number
+ * @param patch Patch version number
*/
-@Beta
-public final class SemVer implements Comparable<SemVer>, Serializable {
+public record SemVer(@NonNegative int major, @NonNegative int minor, @NonNegative int patch)
+ implements Comparable<SemVer>, Serializable {
+ @java.io.Serial
private static final long serialVersionUID = 1L;
- private final int major;
- private final int minor;
- private final int patch;
-
- private SemVer(final int major, final int minor, final int patch) {
- checkArgument(major >= 0);
- this.major = major;
- checkArgument(minor >= 0);
- this.minor = minor;
- checkArgument(patch >= 0);
- this.patch = patch;
- }
- public static @NonNull SemVer create(final @NonNegative int major) {
- return create(major, 0);
+ public SemVer {
+ checkArgument(major >= 0, "Major version has to be non-negative");
+ checkArgument(minor >= 0, "Minor version has to be non-negative");
+ checkArgument(patch >= 0, "Patch version has to be non-negative");
}
- public static @NonNull SemVer create(final @NonNegative int major, final @NonNegative int minor) {
- return create(major, minor, 0);
+ public SemVer(final @NonNegative int major) {
+ this(major, 0);
}
- public static @NonNull SemVer create(final @NonNegative int major, final @NonNegative int minor,
- final @NonNegative int patch) {
- return new SemVer(major, minor, patch);
+ public SemVer(final @NonNegative int major, final @NonNegative int minor) {
+ this(major, minor, 0);
}
public static @NonNull SemVer valueOf(final @NonNull String str) {
final int minorIdx = str.indexOf('.');
if (minorIdx == -1) {
- return create(Integer.parseInt(str));
+ return new SemVer(Integer.parseInt(str));
}
final String minorStr;
final int patchIdx = str.indexOf('.', minorIdx + 1);
if (patchIdx == -1) {
minorStr = str.substring(minorIdx + 1);
- return create(Integer.parseInt(str.substring(0, minorIdx), 10), Integer.parseInt(minorStr, 10));
+ return new SemVer(Integer.parseInt(str.substring(0, minorIdx), 10), Integer.parseInt(minorStr, 10));
}
minorStr = str.substring(minorIdx + 1, patchIdx);
- return create(Integer.parseInt(str.substring(0, minorIdx), 10), Integer.parseInt(minorStr, 10),
+ return new SemVer(Integer.parseInt(str.substring(0, minorIdx), 10), Integer.parseInt(minorStr, 10),
Integer.parseInt(str.substring(patchIdx + 1), 10));
}
- /**
- * Return the major version number.
- *
- * @return major version number
- */
- public int getMajor() {
- return major;
- }
-
- /**
- * Return the minor version number.
- *
- * @return minor version number
- */
- public int getMinor() {
- return minor;
- }
-
- /**
- * Return the patch version number.
- *
- * @return patch version number
- */
- public int getPatch() {
- return patch;
- }
-
@Override
public int compareTo(final SemVer other) {
int cmp = Integer.compare(major, other.major);
if (cmp == 0) {
cmp = Integer.compare(minor, other.minor);
if (cmp == 0) {
- return Integer.compare(patch, other.patch);
+ cmp = Integer.compare(patch, other.patch);
}
}
-
return cmp;
}
- @Override
- public int hashCode() {
- return Objects.hash(major, minor, patch);
- }
-
- @Override
- public boolean equals(final Object obj) {
- return this == obj || obj instanceof SemVer other && major == other.major && minor == other.minor
- && patch == other.patch;
- }
-
@Override
public String toString() {
return major + "." + minor + "." + patch;
@Test
void testSemVer() {
- final var semVer = SemVer.create(5);
+ final var semVer = new SemVer(5);
assertNotNull(semVer);
- assertEquals(5, semVer.getMajor());
- assertEquals(0, semVer.getMinor());
- assertEquals(0, semVer.getPatch());
+ assertEquals(5, semVer.major());
+ assertEquals(0, semVer.minor());
+ assertEquals(0, semVer.patch());
final var semVer2 = SemVer.valueOf("1.2.3");
assertNotNull(semVer2);
- assertEquals(1, semVer2.getMajor());
- assertEquals(2, semVer2.getMinor());
- assertEquals(3, semVer2.getPatch());
+ assertEquals(1, semVer2.major());
+ assertEquals(2, semVer2.minor());
+ assertEquals(3, semVer2.patch());
final var semVer3 = SemVer.valueOf("1");
assertNotNull(semVer3);
- assertEquals(1, semVer3.getMajor());
- assertEquals(0, semVer3.getMinor());
- assertEquals(0, semVer3.getPatch());
+ assertEquals(1, semVer3.major());
+ assertEquals(0, semVer3.minor());
+ assertEquals(0, semVer3.patch());
final var semVer4 = SemVer.valueOf("1.2");
assertNotNull(semVer4);
- assertEquals(1, semVer4.getMajor());
- assertEquals(2, semVer4.getMinor());
- assertEquals(0, semVer4.getPatch());
+ assertEquals(1, semVer4.major());
+ assertEquals(2, semVer4.minor());
+ assertEquals(0, semVer4.patch());
assertEquals(1, semVer2.compareTo(semVer3));
assertEquals(-1, semVer3.compareTo(semVer2));
final byte[] bytes;
try (var bos = new ByteArrayOutputStream()) {
try (var oos = new ObjectOutputStream(bos)) {
- oos.writeObject(SemVer.create(1, 2, 3));
+ oos.writeObject(new SemVer(1, 2, 3));
}
bytes = bos.toByteArray();
}
try (var oos = new ObjectInputStream(new ByteArrayInputStream(HEX_FORMAT.parseHex(SERIALIZED)))) {
value = oos.readObject();
}
- assertEquals(SemVer.create(1, 2, 3), value);
+ assertEquals(new SemVer(1, 2, 3), value);
}
}