step-sequence-generator
Version:
A step sequence generator for figure skating programs
188 lines (187 loc) • 8.19 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MovementFactory = void 0;
const lodash_1 = __importDefault(require("lodash"));
const custom_errors_js_1 = require("../../errors/custom-errors.js");
const Movement_js_1 = require("./Movement.js");
const movement_enums_js_1 = require("../../shared/enums/movement-enums.js");
const turn_absolute_name_enum_1 = require("../../shared/enums/turn-absolute-name.enum");
const { isEqual } = lodash_1.default;
const RIGHT_LEG = 'правая';
const LEFT_LEG = 'левая';
const INNER_EDGE = 'внутреннее';
const OUTER_EDGE = 'наружное';
const TWO_EDGES = 'два ребра';
class MovementFactory {
static createFromExcelData(data, columnName) {
const movementData = {
id: this.parseId(data.get(columnName.ID)),
name: this.parseName(data.get(columnName.NAME)),
transitionDirection: this.parseTransitionDirection(data.get(columnName.TRANSLATION_DIRECTION)),
rotationDirection: this.parseRotationDirection(data.get(columnName.ROTATION_DIRECTION)),
rotationDegree: this.parseRotationDegree(data.get(columnName.ROTATION_DIRECTION)),
startLeg: this.parseLeg(data.get(columnName.START_LEG)),
endLeg: this.parseLeg(data.get(columnName.END_LEG)),
isChangeLeg: this.parseIsChangeLeg(data.get(columnName.START_LEG), data.get(columnName.END_LEG)),
startEdge: this.parseEdge(data.get(columnName.START_EDGE)),
endEdge: this.parseEdge(data.get(columnName.END_EDGE)),
isChangeEdge: this.parseIsChangeEdge(data.get(columnName.START_EDGE), data.get(columnName.END_EDGE)),
isSpeedIncrease: this.parseIsSpeedIncrease(data.get(columnName.IS_SPEED_INCREASE)),
isDifficult: this.parseIsDifficult(data.get(columnName.IS_DIFFICULT)),
type: this.parseType(data.get(columnName.TYPE)),
description: this.parseDescription(data.get(columnName.DESCRIPTION)),
absoluteName: this.parseAbsoluteName(data.get(columnName.ABSOLUTE_NAME)),
distance: this.parseDistance(data.get(columnName.DISTANCE)),
};
return new Movement_js_1.Movement(movementData);
}
// todo написать тесты
static parseId(value) {
return String(value).trim();
}
static parseName(value) {
const formattedValue = this.formatToString(value);
if (formattedValue) {
return String(formattedValue);
}
else {
return 'Неизвестный шаг';
}
}
static parseEdge(value) {
const formatedValue = this.formatToString(value);
this.validateEdge(formatedValue);
if (formatedValue === INNER_EDGE) {
return movement_enums_js_1.Edge.INNER;
}
else if (formatedValue === OUTER_EDGE) {
return movement_enums_js_1.Edge.OUTER;
}
else {
return movement_enums_js_1.Edge.TWO_EDGES;
}
}
static parseIsChangeEdge(startEdge, endEdge) {
const formatedStartEdge = this.formatToString(startEdge);
this.validateEdge(formatedStartEdge);
const formatedEndEdge = this.formatToString(endEdge);
this.validateEdge(formatedEndEdge);
return formatedStartEdge !== formatedEndEdge;
}
static validateEdge(value) {
if (value !== INNER_EDGE && value !== OUTER_EDGE && value !== TWO_EDGES) {
throw new custom_errors_js_1.MovementParserError('wrong value for edge', 'INVALID_EDGE');
}
return true;
}
static parseIsSpeedIncrease(value) {
const formatedValue = this.formatToNumber(value);
if (formatedValue === null)
throw new custom_errors_js_1.MovementParserError('wrong value for speedIncrease', 'INVALID_SPEED_INCREASE');
return Boolean(formatedValue);
}
static parseLeg(value) {
const valueList = this.getLegList(value);
this.validateLegList(valueList);
if (valueList.includes(LEFT_LEG) && valueList.includes(RIGHT_LEG)) {
return movement_enums_js_1.Leg.BOTH;
}
else if (valueList.includes(LEFT_LEG)) {
return movement_enums_js_1.Leg.LEFT;
}
else {
return movement_enums_js_1.Leg.RIGHT;
}
}
static parseIsChangeLeg(startLeg, endLeg) {
const startLegList = this.getLegList(startLeg);
const endLegList = this.getLegList(endLeg);
this.validateLegList(startLegList);
this.validateLegList(endLegList);
return !isEqual(startLegList, endLegList);
}
static validateLegList(value) {
if (!value.includes(LEFT_LEG) && !value.includes(RIGHT_LEG))
throw new custom_errors_js_1.MovementParserError('wrong Leg', 'INVALID_LEG');
return true;
}
static getLegList(value) {
return String(value)
.split(',')
.sort((a, b) => a.localeCompare(b))
.map((item) => item.trim());
}
static parseTransitionDirection(value) {
const formattedValue = this.formatToNumber(value);
if (formattedValue === null) {
return movement_enums_js_1.TransitionDirection.NONE;
}
else if (formattedValue === 0) {
return movement_enums_js_1.TransitionDirection.FORWARD;
}
else {
return movement_enums_js_1.TransitionDirection.BACKWARD;
}
}
static parseRotationDirection(value) {
let direction;
const formatedValue = this.formatToNumber(value);
if (formatedValue === null) {
throw new custom_errors_js_1.MovementParserError('from parseRotationDirection: wrong value for rotationDirection', 'INVALID_ROTATION_DIRECTION');
}
if (formatedValue > 0) {
direction = movement_enums_js_1.RotationDirection.COUNTERCLOCKWISE;
}
else if (formatedValue < 0) {
direction = movement_enums_js_1.RotationDirection.CLOCKWISE;
}
else {
direction = movement_enums_js_1.RotationDirection.NONE;
}
return direction;
}
static parseRotationDegree(value) {
const formatedValue = Math.abs(Number(value));
if (Number.isNaN(formatedValue))
throw new custom_errors_js_1.MovementParserError('from parseRotationDegree: wrong value for rotationDirection', 'INVALID_ROTATION_DIRECTION');
const validDegrees = Object.values(movement_enums_js_1.RotationDegree);
if (!validDegrees.includes(formatedValue)) {
return movement_enums_js_1.RotationDegree.DEGREES_0;
}
else {
return formatedValue;
}
}
static parseIsDifficult(value) {
// note чтобы не проверять на Number.isNaN(value)
return !(value === null || value == 0);
}
static parseType(value) {
return this.straightParseString(value, movement_enums_js_1.MovementCharacter, movement_enums_js_1.MovementCharacter.UNKNOWN);
}
static parseDescription(value) {
return String(value || '');
}
static parseAbsoluteName(value) {
return this.straightParseString(value, turn_absolute_name_enum_1.TurnAbsoluteName, turn_absolute_name_enum_1.TurnAbsoluteName.UNKNOWN);
}
static parseDistance(value) {
const formattedValue = this.formatToNumber(value);
return formattedValue === null ? 1 : formattedValue;
}
static straightParseString(value, enumObj, defaultValue) {
const formattedValue = this.formatToString(value);
const match = Object.values(enumObj).find((val) => val === formattedValue);
return match ?? defaultValue;
}
static formatToString(value) {
return String(value).trim().toLowerCase();
}
static formatToNumber(value) {
return Number.isNaN(Number(value)) || value === null ? null : Number(value);
}
}
exports.MovementFactory = MovementFactory;