You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
70 lines
2.3 KiB
70 lines
2.3 KiB
package com.github.mgifos.workouts.model
|
|
|
|
import play.api.libs.json.{ JsValue, Json }
|
|
import Workout._
|
|
|
|
trait Workout {
|
|
def json: JsValue
|
|
}
|
|
|
|
case class WorkoutDef(sport: String, name: String, steps: Seq[Step] = Nil) extends Workout {
|
|
def toRef: WorkoutRef = WorkoutRef(name)
|
|
def withStep(step: Step): WorkoutDef = WorkoutDef(sport, name, steps :+ step)
|
|
def json: JsValue = Json.obj(
|
|
"sportType" -> Json.obj(
|
|
"sportTypeId" -> sportId(sport),
|
|
"sportTypeKey" -> sportTypeKey(sport)),
|
|
"workoutName" -> name,
|
|
"workoutSegments" -> Json.arr(
|
|
Json.obj(
|
|
"segmentOrder" -> 1,
|
|
"sportType" -> Json.obj(
|
|
"sportTypeId" -> sportId(sport),
|
|
"sportTypeKey" -> sport),
|
|
"workoutSteps" -> steps.zipWithIndex.map { case (s, i) => s.json(i + 1) })))
|
|
}
|
|
|
|
case class WorkoutRef(name: String) extends Workout {
|
|
def json: JsValue = Json.obj()
|
|
}
|
|
|
|
case class WorkoutNote(note: String) extends Workout {
|
|
def json: JsValue = Json.obj()
|
|
}
|
|
|
|
object Workout {
|
|
|
|
private val WorkoutHeader = """^(running|cycling|custom):\s([\u0020-\u007F]+)(([\r\n]+\s*\-\s[a-z]+:.*)*)$""".r
|
|
private val NextStepRx = """^((-\s\w*:\s.*)(([\r\n]+\s{1,}-\s.*)*))(([\s].*)*)$""".r
|
|
|
|
def parseDef(x: String)(implicit msys: MeasurementSystems.MeasurementSystem): Either[String, WorkoutDef] = {
|
|
def loop(w: WorkoutDef, steps: String): Either[String, WorkoutDef] = steps match {
|
|
case NextStepRx(next, _, _, _, rest, _) =>
|
|
val newWorkout = w.withStep(Step.parse(next.trim))
|
|
if (rest.trim.isEmpty) Right(newWorkout)
|
|
else loop(newWorkout, rest.trim)
|
|
case _ => Left(s"Input string cannot be parsed to Workout: $steps")
|
|
}
|
|
x match {
|
|
case WorkoutHeader(sport, name, steps, _) => loop(WorkoutDef(sport, name), steps.trim)
|
|
case _ => Left(s"Input string cannot be parsed to Workout: $x")
|
|
}
|
|
}
|
|
|
|
def parseRef(x: String): WorkoutRef = x match {
|
|
case WorkoutHeader(_, name, _, _) => WorkoutRef(name)
|
|
case _ => WorkoutRef(x.trim)
|
|
}
|
|
|
|
def sportId(sport: String) = sport match {
|
|
case "running" => 1
|
|
case "cycling" => 2
|
|
case "custom" => 3
|
|
case _ => throw new IllegalArgumentException("Only running, cycling and 'custom' workouts are supported.")
|
|
}
|
|
|
|
def sportTypeKey(sport: String) = sport match {
|
|
case "custom" => "other"
|
|
case _ => sport
|
|
}
|
|
}
|
|
|