Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ project/plugins/project/
.lib/
.bloop/
.metals/
.bsp/

# Java
*.class
Expand Down Expand Up @@ -55,3 +56,6 @@ project/metals.sbt
# Windows
Desktop.ini
Thumbs.db

# VScode
.vscode/
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1455,7 +1455,7 @@ class ScadaLoadListener(router: Router) extends Actor {
def receive = {
// ScadaLoadReading - from an external service - sends load as a string
// eg, “10.3 MW”, “345 kW”
case msg @ ScadaLoadReading(meterId, time, loadString)
case msg @ ScadaLoadReading(meterId, time, loadString) =>
// Parse the string and on success emit the Squants enabled event to routees
Power(loadString) match {
case Success(p) => router.route(LoadReading(meterId, time, p), sender())
Expand Down
6 changes: 3 additions & 3 deletions project/Build.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ import com.typesafe.sbt.osgi.SbtOsgi
import com.typesafe.sbt.osgi.SbtOsgi.autoImport._

object Versions {
val Scala3 = "3.1.1"
val Scala3 = "3.7.1"
val Scala = Scala3
val ScalaCross =
Seq("2.12.15", "2.13.6", Scala)

val ScalaTest = "3.2.14"
val ScalaCheck = "1.16.0"
val ScalaTest = "3.2.19"
val ScalaCheck = "1.18.1"
}

object Dependencies {
Expand Down
2 changes: 1 addition & 1 deletion project/build.properties
Original file line number Diff line number Diff line change
@@ -1 +1 @@
sbt.version=1.8.0
sbt.version=1.11.2
8 changes: 4 additions & 4 deletions project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.2.0")
addSbtPlugin("org.portable-scala" % "sbt-scala-native-crossproject" % "1.2.0")
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.10.0")
addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.4.9")
addSbtPlugin("org.portable-scala" % "sbt-scalajs-crossproject" % "1.3.2")
addSbtPlugin("org.portable-scala" % "sbt-scala-native-crossproject" % "1.3.2")
addSbtPlugin("org.scala-js" % "sbt-scalajs" % "1.19.0")
addSbtPlugin("org.scala-native" % "sbt-scala-native" % "0.5.8")

addSbtPlugin("org.scalariform" % "sbt-scalariform" % "1.8.3")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ package squants
*
* @tparam A Quantity type
*/
abstract class AbstractQuantityNumeric[A <: Quantity[A]](val unit: UnitOfMeasure[A] with PrimaryUnit) extends Numeric[A] {
abstract class AbstractQuantityNumeric[A <: Quantity[A]](val unit: UnitOfMeasure[A] & PrimaryUnit) extends Numeric[A] {
def plus(x: A, y: A) = x + y
def minus(x: A, y: A) = x - y

Expand Down
32 changes: 16 additions & 16 deletions shared/src/main/scala/squants/Dimension.scala
Original file line number Diff line number Diff line change
Expand Up @@ -35,41 +35,41 @@ trait Dimension[A <: Quantity[A]] {
* The conversionFactor for other units should be set relative to this unit.
* @return
*/
def primaryUnit: UnitOfMeasure[A] with PrimaryUnit
def primaryUnit: UnitOfMeasure[A] & PrimaryUnit

/**
* The International System of Units (SI) Base Unit
* @return
*/
def siUnit: UnitOfMeasure[A] with SiUnit
def siUnit: UnitOfMeasure[A] & SiUnit

/**
* Maps a string representation of a unit symbol into the matching UnitOfMeasure object
* @param symbol String
* @return
*/
def symbolToUnit(symbol: String): Option[UnitOfMeasure[A]] = units.find(u u.symbol == symbol)
def symbolToUnit(symbol: String): Option[UnitOfMeasure[A]] = units.find(u => u.symbol == symbol)

/**
* Tries to map a string or tuple value to Quantity of this Dimension
* @param value the source string (ie, "10 kW") or tuple (ie, (10, "kW"))
* @return Try[A]
*/
protected def parse(value: Any): Try[A] = value match {
case s: String parseString(s)
case (v: Byte, u: String) parseTuple((v, u))
case (v: Short, u: String) parseTuple((v, u))
case (v: Int, u: String) parseTuple((v, u))
case (v: Long, u: String) parseTuple((v, u))
case (v: Float, u: String) parseTuple((v, u))
case (v: Double, u: String) parseTuple((v, u))
case _ Failure(QuantityParseException(s"Unable to parse $name", value.toString))
case s: String => parseString(s)
case (v: Byte, u: String) => parseTuple((v, u))
case (v: Short, u: String) => parseTuple((v, u))
case (v: Int, u: String) => parseTuple((v, u))
case (v: Long, u: String) => parseTuple((v, u))
case (v: Float, u: String) => parseTuple((v, u))
case (v: Double, u: String) => parseTuple((v, u))
case _ => Failure(QuantityParseException(s"Unable to parse $name", value.toString))
}

def parseString(s: String): Try[A] = {
s match {
case QuantityString(value, symbol) Success(symbolToUnit(symbol).get(BigDecimal(value)))
case _ Failure(QuantityParseException(s"Unable to parse $name", s))
case QuantityString(value, symbol) => Success(symbolToUnit(symbol).get(BigDecimal(value)))
case _ => Failure(QuantityParseException(s"Unable to parse $name", s))
}
}

Expand All @@ -79,8 +79,8 @@ trait Dimension[A <: Quantity[A]] {
val value = t._1
val symbol = t._2
symbolToUnit(symbol) match {
case Some(unit) Success(unit(value))
case None Failure(QuantityParseException(s"Unable to identify $name unit ${symbol}", s"(${Platform.crossFormat(num.toDouble(value))},${symbol})"))
case Some(unit) => Success(unit(value))
case None => Failure(QuantityParseException(s"Unable to identify $name unit ${symbol}", s"(${Platform.crossFormat(num.toDouble(value))},${symbol})"))
}
}

Expand All @@ -100,7 +100,7 @@ case class QuantityParseException(message: String, expression: String) extends E
/**
* SI Base Quantity
*/
trait BaseDimension { self: Dimension[_] ⇒
trait BaseDimension { self: Dimension[?] =>
/**
* SI Base Unit for this Quantity
* @return
Expand Down
2 changes: 1 addition & 1 deletion shared/src/main/scala/squants/Dimensionless.scala
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ final class Dimensionless private (val value: Double, val unit: DimensionlessUni
protected[squants] def time = Seconds(1)

def *(that: Dimensionless) = Each(toEach * that.toEach)
def *(that: Quantity[_]) = that * toEach
def *(that: Quantity[?]) = that * toEach

def +(that: Double): Dimensionless = this + Each(that)

Expand Down
22 changes: 11 additions & 11 deletions shared/src/main/scala/squants/Quantity.scala
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import scala.math.BigDecimal.RoundingMode.RoundingMode
* @since 0.1
*
*/
abstract class Quantity[A <: Quantity[A]] extends Serializable with Ordered[A] { self: A
abstract class Quantity[A <: Quantity[A]] extends Serializable with Ordered[A] { self: A =>

/**
* The value of the quantity given the unit
Expand Down Expand Up @@ -104,7 +104,7 @@ abstract class Quantity[A <: Quantity[A]] extends Serializable with Ordered[A] {
* @return (Quantity, Quantity)
*/
def divideAndRemainder(that: Double): (A, A) = BigDecimal(value) /% that match {
case (q, r) (unit(q.toDouble), unit(r.toDouble))
case (q, r) => (unit(q.toDouble), unit(r.toDouble))
}
def /%(that: Double) = divideAndRemainder(that)

Expand All @@ -114,7 +114,7 @@ abstract class Quantity[A <: Quantity[A]] extends Serializable with Ordered[A] {
* @return (Double, Quantity)
*/
def divideAndRemainder(that: A): (Double, A) = BigDecimal(value) /% that.to(unit) match {
case (q, r) (q.toDouble, unit(r.toDouble))
case (q, r) => (q.toDouble, unit(r.toDouble))
}
def /%(that: A) = divideAndRemainder(that)

Expand Down Expand Up @@ -171,8 +171,8 @@ abstract class Quantity[A <: Quantity[A]] extends Serializable with Ordered[A] {
* @return
*/
override def equals(that: Any) = that match {
case x: Quantity[_] if x.dimension == dimension value == x.asInstanceOf[Quantity[A]].to(unit)
case _ false
case x: Quantity[_] if x.dimension == dimension => value == x.asInstanceOf[Quantity[A]].to(unit)
case _ => false
}

/**
Expand All @@ -190,7 +190,7 @@ abstract class Quantity[A <: Quantity[A]] extends Serializable with Ordered[A] {
* @param tolerance Quantity
* @return
*/
def approx(that: A)(implicit tolerance: A) = that within this.plusOrMinus(tolerance)
def approx(that: A)(implicit tolerance: A) = that.within(this.plusOrMinus(tolerance))
/** approx */
def =~(that: A)(implicit tolerance: A) = approx(that)
/** approx */
Expand Down Expand Up @@ -258,8 +258,8 @@ abstract class Quantity[A <: Quantity[A]] extends Serializable with Ordered[A] {
* @return Double
*/
def to(uom: UnitOfMeasure[A]): Double = uom match {
case u if u == this.unit value
case _ uom.convertTo(this.unit.convertFrom(value))
case u if u == this.unit => value
case _ => uom.convertTo(this.unit.convertFrom(value))
}

/**
Expand All @@ -268,8 +268,8 @@ abstract class Quantity[A <: Quantity[A]] extends Serializable with Ordered[A] {
* @return Quantity
*/
def in(uom: UnitOfMeasure[A]) = uom match {
case u if u == this.unit this
case _ uom(uom.convertTo(this.unit.convertFrom(value)))
case u if u == this.unit => this
case _ => uom(uom.convertTo(this.unit.convertFrom(value)))
}

/**
Expand Down Expand Up @@ -311,6 +311,6 @@ abstract class Quantity[A <: Quantity[A]] extends Serializable with Ordered[A] {
* @param f Double => Double function
* @return
*/
def map(f: Double Double): A = unit(f(value))
def map(f: Double => Double): A = unit(f(value))
}

28 changes: 14 additions & 14 deletions shared/src/main/scala/squants/QuantityRange.scala
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ case class QuantityRange[A <: Quantity[A]](lower: A, upper: A) {
def times(multiple: Double): QuantitySeries[A] = {
val remainder = multiple % 1
val count = ((multiple - remainder) / 1).toInt
val ranges = (0 until count).map(n QuantityRange(lower + (toQuantity * n.toDouble), upper + (toQuantity * n.toDouble)))
val ranges = (0 until count).map(n => QuantityRange(lower + (toQuantity * n.toDouble), upper + (toQuantity * n.toDouble)))
if (remainder > 0) ranges :+ QuantityRange(lower + (toQuantity * count.toDouble), lower + (toQuantity * (count + remainder)))
else ranges
}
Expand All @@ -58,7 +58,7 @@ case class QuantityRange[A <: Quantity[A]](lower: A, upper: A) {
@tailrec
def accumulate(acc: QuantitySeries[A], start: A): QuantitySeries[A] = {
if (start >= upper) acc
else accumulate(acc :+ (start to (start + that).min(upper)), start + that)
else accumulate(acc :+ (start.to((start + that).min(upper))), start + that)
}
accumulate(IndexedSeq.empty.asInstanceOf[QuantitySeries[A]], lower)
}
Expand Down Expand Up @@ -89,7 +89,7 @@ case class QuantityRange[A <: Quantity[A]](lower: A, upper: A) {
* @param op the side affecting operation
* @return
*/
def foreach[U](size: A)(op: QuantityRange[A] U) = /(size).foreach(op)
def foreach[U](size: A)(op: QuantityRange[A] => U) = /(size).foreach(op)

/**
* Divides the range into a Seq of `divisor` ranges and applies a f to each element
Expand All @@ -98,7 +98,7 @@ case class QuantityRange[A <: Quantity[A]](lower: A, upper: A) {
* @param op the side affecting operation
* @return
*/
def foreach[U](divisor: Double)(op: QuantityRange[A] U) = /(divisor).foreach(op)
def foreach[U](divisor: Double)(op: QuantityRange[A] => U) = /(divisor).foreach(op)

/**
* Divides the range into a Seq of ranges of `size` each and applies a map operation to each
Expand All @@ -108,7 +108,7 @@ case class QuantityRange[A <: Quantity[A]](lower: A, upper: A) {
* @tparam B the result type of the map operation
* @return
*/
def map[B](size: A)(op: QuantityRange[A] B): Seq[B] = /(size).map(op)
def map[B](size: A)(op: QuantityRange[A] => B): Seq[B] = /(size).map(op)

/**
* Divides the range into a Seq of `divisor` ranges and applies a map operation to each
Expand All @@ -118,7 +118,7 @@ case class QuantityRange[A <: Quantity[A]](lower: A, upper: A) {
* @tparam B the result type of the map operation
* @return
*/
def map[B](divisor: Double)(op: QuantityRange[A] B): Seq[B] = map(toQuantity / divisor)(op)
def map[B](divisor: Double)(op: QuantityRange[A] => B): Seq[B] = map(toQuantity / divisor)(op)

/**
* Divides the range into a Seq of ranges of `size` each and applies a foldLeft operation
Expand All @@ -129,9 +129,9 @@ case class QuantityRange[A <: Quantity[A]](lower: A, upper: A) {
* @tparam B the result type of the binary operator
* @return
*/
def foldLeft[B](size: A, z: B)(op: (B, QuantityRange[A]) B): B = /(size).foldLeft[B](z)(op)
def foldLeft[B](size: A, z: B)(op: (B, QuantityRange[A]) => B): B = /(size).foldLeft[B](z)(op)
/** foldLeft */
def /:[B](size: A, z: B)(op: (B, QuantityRange[A]) B) = foldLeft(size, z)(op)
def /:[B](size: A, z: B)(op: (B, QuantityRange[A]) => B) = foldLeft(size, z)(op)

/**
* Divides the range into a Seq of ranges of `size` each and applies a foldLeft operation
Expand All @@ -142,9 +142,9 @@ case class QuantityRange[A <: Quantity[A]](lower: A, upper: A) {
* @tparam B the result type of the binary operator
* @return
*/
def foldLeft[B](divisor: Double, z: B)(op: (B, QuantityRange[A]) B): B = /(divisor).foldLeft[B](z)(op)
def foldLeft[B](divisor: Double, z: B)(op: (B, QuantityRange[A]) => B): B = /(divisor).foldLeft[B](z)(op)
/** foldLeft */
def /:[B](divisor: Double, z: B)(op: (B, QuantityRange[A]) B) = foldLeft(divisor, z)(op)
def /:[B](divisor: Double, z: B)(op: (B, QuantityRange[A]) => B) = foldLeft(divisor, z)(op)

/**
* Divides the range into a Seq of ranges of `size` each and applies a foldRight operation
Expand All @@ -155,9 +155,9 @@ case class QuantityRange[A <: Quantity[A]](lower: A, upper: A) {
* @tparam B the result type of the binary operator
* @return
*/
def foldRight[B](size: A, z: B)(op: (QuantityRange[A], B) B): B = /(size).foldRight[B](z)(op)
def foldRight[B](size: A, z: B)(op: (QuantityRange[A], B) => B): B = /(size).foldRight[B](z)(op)
/** foldRight */
def :\[B](size: A, z: B)(op: (QuantityRange[A], B) B) = foldRight(size, z)(op)
def :\[B](size: A, z: B)(op: (QuantityRange[A], B) => B) = foldRight(size, z)(op)

/**
* Divides the range into a Seq of ranges of `size` each and applies a foldRight operation
Expand All @@ -168,9 +168,9 @@ case class QuantityRange[A <: Quantity[A]](lower: A, upper: A) {
* @tparam B the result type of the binary operator
* @return
*/
def foldRight[B](divisor: Double, z: B)(op: (QuantityRange[A], B) B): B = /(divisor).foldRight[B](z)(op)
def foldRight[B](divisor: Double, z: B)(op: (QuantityRange[A], B) => B): B = /(divisor).foldRight[B](z)(op)
/** foldRight */
def :\[B](divisor: Double, z: B)(op: (QuantityRange[A], B) B) = foldRight(divisor, z)(op)
def :\[B](divisor: Double, z: B)(op: (QuantityRange[A], B) => B) = foldRight(divisor, z)(op)

/**
* Increments the range's from and to values by an amount equal to the Quantity value of the range
Expand Down
Loading
Loading