DecVer (Decimal Version)
It requires the just-semver-decver module.
"io.kevinlee" %% "just-semver-decver" % "1.1.1"
"io.kevinlee" %%% "just-semver-decver" % "1.1.1"
DecVer.parse
import just.decver.DecVer
val v = DecVer.parse("1.0")
// v: Either[DecVer.ParseError, DecVer] = Right(
//   value = DecVer(
//     major = Major(value = 1),
//     minor = Minor(value = 0),
//     pre = None,
//     buildMetadata = None
//   )
// )
// To render it to `String`,
v.map(_.render)
// res1: Either[DecVer.ParseError, String] = Right(value = "1.0")
// Invalid version
DecVer.parse("a1.0")
// res2: Either[DecVer.ParseError, DecVer] = Left(
//   value = Invalid(version = "a1.0")
// )
// Invalid version
DecVer.parse("a1.0.0")
// res3: Either[DecVer.ParseError, DecVer] = Left(
//   value = Invalid(version = "a1.0.0")
// )
DecVer.unsafeParse
import just.decver.DecVer
// parse unsafe - NOT RECOMMENDED!!!
val v = DecVer.unsafeParse("1.0")
// v: DecVer = DecVer(
//   major = Major(value = 1),
//   minor = Minor(value = 0),
//   pre = None,
//   buildMetadata = None
// )
// to String
v.render
// res5: String = "1.0"
// Invalid version
DecVer.unsafeParse("a1.0")
// just.decver.DecVer$ParseError$Invalid: Invalid version: a1.0
// 	at just.decver.DecVer$ParseError$.invalid(DecVer.scala:191)
// 	at just.decver.DecVer$.$anonfun$parse$4(DecVer.scala:132)
// 	at scala.util.Either.flatMap(Either.scala:360)
// 	at just.decver.DecVer$.parse(DecVer.scala:104)
// 	at just.decver.DecVer$.unsafeParse(DecVer.scala:137)
// 	at repl.MdocSession$MdocApp4$$anonfun$2.apply(decver.md:45)
// 	at repl.MdocSession$MdocApp4$$anonfun$2.apply(decver.md:45)
DecVer with pre-release info
import just.decver.DecVer
DecVer.parse("1.0-beta1")
// res7: Either[DecVer.ParseError, DecVer] = Right(
//   value = DecVer(
//     major = Major(value = 1),
//     minor = Minor(value = 0),
//     pre = Some(
//       value = PreRelease(
//         identifier = List(
//           Dsv(values = List(Alphabet(value = "beta"), Num(value = "1")))
//         )
//       )
//     ),
//     buildMetadata = None
//   )
// )
val v = DecVer.parse("1.0-3.123.9a")
// v: Either[DecVer.ParseError, DecVer] = Right(
//   value = DecVer(
//     major = Major(value = 1),
//     minor = Minor(value = 0),
//     pre = Some(
//       value = PreRelease(
//         identifier = List(
//           Dsv(values = List(Num(value = "3"))),
//           Dsv(values = List(Num(value = "123"))),
//           Dsv(values = List(Num(value = "9"), Alphabet(value = "a")))
//         )
//       )
//     ),
//     buildMetadata = None
//   )
// )
v.map(_.render)
// res8: Either[DecVer.ParseError, String] = Right(value = "1.0-3.123.9a")
DecVer with build meta-info
import just.decver.DecVer
val v = DecVer.parse("1.0+100.0.12abc")
// v: Either[DecVer.ParseError, DecVer] = Right(
//   value = DecVer(
//     major = Major(value = 1),
//     minor = Minor(value = 0),
//     pre = None,
//     buildMetadata = Some(
//       value = BuildMetaInfo(
//         identifier = List(
//           Dsv(values = List(Num(value = "100"))),
//           Dsv(values = List(Num(value = "0"))),
//           Dsv(values = List(Num(value = "12"), Alphabet(value = "abc")))
//         )
//       )
//     )
//   )
// )
v.map(_.render)
// res10: Either[DecVer.ParseError, String] = Right(value = "1.0+100.0.12abc")
DecVer with pre-release info and build meta-info
import just.decver.DecVer
DecVer.parse("1.0-beta1")
// res12: Either[DecVer.ParseError, DecVer] = Right(
//   value = DecVer(
//     major = Major(value = 1),
//     minor = Minor(value = 0),
//     pre = Some(
//       value = PreRelease(
//         identifier = List(
//           Dsv(values = List(Alphabet(value = "beta"), Num(value = "1")))
//         )
//       )
//     ),
//     buildMetadata = None
//   )
// )
val v = DecVer.parse("1.0-3.123.9a+100.0.12abc")
// v: Either[DecVer.ParseError, DecVer] = Right(
//   value = DecVer(
//     major = Major(value = 1),
//     minor = Minor(value = 0),
//     pre = Some(
//       value = PreRelease(
//         identifier = List(
//           Dsv(values = List(Num(value = "3"))),
//           Dsv(values = List(Num(value = "123"))),
//           Dsv(values = List(Num(value = "9"), Alphabet(value = "a")))
//         )
//       )
//     ),
//     buildMetadata = Some(
//       value = BuildMetaInfo(
//         identifier = List(
//           Dsv(values = List(Num(value = "100"))),
//           Dsv(values = List(Num(value = "0"))),
//           Dsv(values = List(Num(value = "12"), Alphabet(value = "abc")))
//         )
//       )
//     )
//   )
// )
v.map(_.render)
// res13: Either[DecVer.ParseError, String] = Right(
//   value = "1.0-3.123.9a+100.0.12abc"
// )
Compare DecVer
import just.decver.DecVer
for {
 a <- DecVer.parse("1.0")
 b <- DecVer.parse("1.1")
} yield a < b
// res15: Either[DecVer.ParseError, Boolean] = Right(value = true)
for {
 a <- DecVer.parse("1.1")
 b <- DecVer.parse("1.0")
} yield a < b
// res16: Either[DecVer.ParseError, Boolean] = Right(value = false)
for {
 a <- DecVer.parse("1.0")
 b <- DecVer.parse("1.1")
} yield a <= b
// res17: Either[DecVer.ParseError, Boolean] = Right(value = true)
for {
 a <- DecVer.parse("1.0")
 b <- DecVer.parse("1.0")
} yield a <= b
// res18: Either[DecVer.ParseError, Boolean] = Right(value = true)
for {
 a <- DecVer.parse("1.0")
 b <- DecVer.parse("1.0")
} yield a == b
// res19: Either[DecVer.ParseError, Boolean] = Right(value = true)
for {
 a <- DecVer.parse("1.1")
 b <- DecVer.parse("1.0")
} yield a > b
// res20: Either[DecVer.ParseError, Boolean] = Right(value = true)
for {
 a <- DecVer.parse("1.0")
 b <- DecVer.parse("1.1")
} yield a > b
// res21: Either[DecVer.ParseError, Boolean] = Right(value = false)
for {
 a <- DecVer.parse("1.0")
 b <- DecVer.parse("1.1")
} yield a >= b
// res22: Either[DecVer.ParseError, Boolean] = Right(value = false)
for {
 a <- DecVer.parse("1.0")
 b <- DecVer.parse("1.0")
} yield a >= b
// res23: Either[DecVer.ParseError, Boolean] = Right(value = true)
for {
 a <- DecVer.parse("1.1")
 b <- DecVer.parse("1.0")
} yield a >= b
// res24: Either[DecVer.ParseError, Boolean] = Right(value = true)
Matchers
DecVer.unsafeParse("1.0").unsafeMatches("1.0 - 2.0")
// res25: Boolean = true
DecVer.unsafeParse("1.5").unsafeMatches("1.0 - 2.0")
// res26: Boolean = true
DecVer.unsafeParse("2.0").unsafeMatches("1.0 - 2.0")
// res27: Boolean = true
DecVer.unsafeParse("0.9").unsafeMatches("1.0 - 2.0")
// res28: Boolean = false
DecVer.unsafeParse("2.1").unsafeMatches("1.0 - 2.0")
// res29: Boolean = false
DecVer.unsafeParse("1.0").unsafeMatches(">1.0 <2.0")
// res30: Boolean = false
DecVer.unsafeParse("1.0").unsafeMatches(">=1.0 <=2.0")
// res31: Boolean = true
DecVer.unsafeParse("1.5").unsafeMatches(">1.0 <2.0")
// res32: Boolean = true
DecVer.unsafeParse("2.0").unsafeMatches(">1.0 <2.0")
// res33: Boolean = false
DecVer.unsafeParse("2.0").unsafeMatches(">=1.0 <=2.0")
// res34: Boolean = true
DecVer.unsafeParse("0.9").unsafeMatches(">=1.0 <=2.0")
// res35: Boolean = false
DecVer.unsafeParse("2.1").unsafeMatches(">=1.0 <=2.0")
// res36: Boolean = false
DecVer.unsafeParse("1.0").unsafeMatches("1.0 - 2.0 || >3.0 <4.0")
// res37: Boolean = true
DecVer.unsafeParse("2.0").unsafeMatches("1.0 - 2.0 || >3.0 <4.0")
// res38: Boolean = true
DecVer.unsafeParse("3.0").unsafeMatches("1.0 - 2.0 || >3.0 <=4.0")
// res39: Boolean = false
DecVer.unsafeParse("3.1").unsafeMatches("1.0 - 2.0 || >3.0 <=4.0")
// res40: Boolean = true
DecVer.unsafeParse("4.0").unsafeMatches("1.0 - 2.0 || >3.0 <=4.0")
// res41: Boolean = true