Skip to content
Permalink
Browse files

Added Version class to represent a version

  • Loading branch information
darkfrog26 committed Dec 16, 2019
1 parent c01db73 commit 0e17dbef1aa3eb97964524af6277860bd931001e
Showing with 91 additions and 1 deletion.
  1. +1 −1 build.sbt
  2. +90 −0 core/shared/src/main/scala/io/youi/Version.scala
@@ -4,7 +4,7 @@ import sbtcrossproject.CrossType

name := "youi"
organization in ThisBuild := "io.youi"
version in ThisBuild := "0.12.11"
version in ThisBuild := "0.12.12-SNAPSHOT"
scalaVersion in ThisBuild := "2.13.1"
crossScalaVersions in ThisBuild := List("2.13.1", "2.12.10")
resolvers in ThisBuild ++= Seq(
@@ -0,0 +1,90 @@
package io.youi

import io.circe.Decoder.Result
import io.circe.{Decoder, Encoder, HCursor, Json}

import scala.util.matching.Regex

/**
* Version represents a version numbering.
*/
case class Version(major: Int = 1,
minor: Int = 0,
maintenance: Int = 0,
build: Int = 0,
extra: Option[String] = None,
original: Option[String] = None) extends Ordered[Version] {
private lazy val string = {
val b = new StringBuilder
b.append(general)
if (build > 0) {
b.append('.')
b.append(build)
}
extra match {
case Some(e) => b.append(s"-$e")
case None => // No extra
}
b.toString()
}

lazy val general = s"$major.$minor.$maintenance"

def snapshot: Boolean = {
extra.map(_.toUpperCase).getOrElse("").contains("SNAPSHOT")
}

override def toString: String = original.getOrElse(string)

def compare(that: Version): Int = if (major != that.major) {
major.compare(that.major)
} else if (minor != that.minor) {
minor.compare(that.minor)
} else if (maintenance != that.maintenance) {
maintenance.compare(that.maintenance)
} else if (build != that.build) {
build.compare(that.build)
} else if (extra != that.extra && extra != null) {
extra.getOrElse("").compare(that.extra.getOrElse(""))
} else if (extra != that.extra && that.extra != null) {
-1
} else {
0
}
}

object Version {
val Zero = Version(0)
private val Matcher: Regex = """(\d+)[.]?(\d*)[.]?(\d*)[.]?(\d*)[-]?(.*)""".r

implicit val encoder: Encoder[Version] = new Encoder[Version] {
override def apply(a: Version): Json = Json.fromString(a.toString)
}
implicit val decoder: Decoder[Version] = new Decoder[Version] {
override def apply(c: HCursor): Result[Version] = c.value.asString match {
case Some(value) => Right(Version(value))
case None => {
val original = (c.value \\ "original").head.asString.getOrElse(throw new RuntimeException(s"Unable to decode Version: ${c.value}"))
Right(Version(original))
}
}
}

def apply(version: String): Version = version match {
case Version(v) => v
case _ => Version(major = 0, original = Option(version))
}

def unapply(version: String): Option[Version] = version match {
case null | "" => None
case Matcher(major, minor, maintenance, build, extra) => {
Some(Version(n(major), n(minor), n(maintenance), n(build), if (extra != null && extra.nonEmpty) Some(extra) else None, Some(version)))
}
case _ => None
}

private def n(s: String) = s match {
case "" => 0
case _ => s.toInt
}
}

0 comments on commit 0e17dbe

Please sign in to comment.
You can’t perform that action at this time.