From deacd0dfc195bca41af631114804d29937337cd8 Mon Sep 17 00:00:00 2001 From: nsfisis Date: Wed, 17 Jan 2024 02:11:31 +0900 Subject: . --- .../app/src/Models/AggregatedExecutionStatus.php | 54 +++++++++ services/app/src/Models/Answer.php | 69 +++++++++++ services/app/src/Models/ExecutionStatus.php | 83 +++++++++++++ services/app/src/Models/Quiz.php | 133 +++++++++++++++++++++ services/app/src/Models/Testcase.php | 29 +++++ services/app/src/Models/TestcaseExecution.php | 32 +++++ services/app/src/Models/User.php | 26 ++++ 7 files changed, 426 insertions(+) create mode 100644 services/app/src/Models/AggregatedExecutionStatus.php create mode 100644 services/app/src/Models/Answer.php create mode 100644 services/app/src/Models/ExecutionStatus.php create mode 100644 services/app/src/Models/Quiz.php create mode 100644 services/app/src/Models/Testcase.php create mode 100644 services/app/src/Models/TestcaseExecution.php create mode 100644 services/app/src/Models/User.php (limited to 'services/app/src/Models') diff --git a/services/app/src/Models/AggregatedExecutionStatus.php b/services/app/src/Models/AggregatedExecutionStatus.php new file mode 100644 index 0000000..82b19e4 --- /dev/null +++ b/services/app/src/Models/AggregatedExecutionStatus.php @@ -0,0 +1,54 @@ + '実行待機中', + self::Pending => '実行待機中', + self::Failed => '失敗', + self::OK => 'OK', + }; + } + + public function showLoadingIndicator(): bool + { + return match ($this) { + self::UpdateNeeded => true, + self::Pending => true, + self::Failed => false, + self::OK => false, + }; + } + + public function toInt(): int + { + return match ($this) { + self::UpdateNeeded => 0, + self::Pending => 1, + self::Failed => 2, + self::OK => 3, + }; + } + + public static function fromInt(int $n): self + { + // @phpstan-ignore-next-line + return match ($n) { + 0 => self::UpdateNeeded, + 1 => self::Pending, + 2 => self::Failed, + 3 => self::OK, + }; + } +} diff --git a/services/app/src/Models/Answer.php b/services/app/src/Models/Answer.php new file mode 100644 index 0000000..6cb8006 --- /dev/null +++ b/services/app/src/Models/Answer.php @@ -0,0 +1,69 @@ + '実行待機中', + self::Running => '実行中', + self::IE => '内部エラー', + self::RE => '実行時エラー', + self::WA => '不正解', + self::TLE => '時間制限超過', + self::AC => 'OK', + }; + } + + public function showLoadingIndicator(): bool + { + return match ($this) { + self::Pending => true, + self::Running => true, + self::IE => false, + self::RE => false, + self::WA => false, + self::TLE => false, + self::AC => false, + }; + } + + public function toInt(): int + { + return match ($this) { + self::Pending => 0, + self::Running => 1, + self::IE => 2, + self::RE => 3, + self::WA => 4, + self::TLE => 5, + self::AC => 6, + }; + } + + public static function fromInt(int $n): self + { + // @phpstan-ignore-next-line + return match ($n) { + 0 => self::Pending, + 1 => self::Running, + 2 => self::IE, + 3 => self::RE, + 4 => self::WA, + 5 => self::TLE, + 6 => self::AC, + }; + } + + public static function fromString(string $s): self + { + // @phpstan-ignore-next-line + return match ($s) { + 'Pending' => self::Pending, + 'Running' => self::Running, + 'IE' => self::IE, + 'RE' => self::RE, + 'WA' => self::WA, + 'TLE' => self::TLE, + 'AC' => self::AC, + }; + } +} diff --git a/services/app/src/Models/Quiz.php b/services/app/src/Models/Quiz.php new file mode 100644 index 0000000..5546646 --- /dev/null +++ b/services/app/src/Models/Quiz.php @@ -0,0 +1,133 @@ +started_at <= $now; + } + + public function isFinished(?DateTimeImmutable $now = null): bool + { + if ($now === null) { + $now = new DateTimeImmutable('now', new DateTimeZone('UTC')); + } + return $this->finished_at <= $now; + } + + public function isOpenToAnswer(?DateTimeImmutable $now = null): bool + { + return $this->isStarted($now) && !$this->isFinished($now); + } + + public function isClosedToAnswer(?DateTimeImmutable $now = null): bool + { + return !$this->isOpenToAnswer($now); + } + + public function isRankingHidden(?DateTimeImmutable $now = null): bool + { + if ($now === null) { + $now = new DateTimeImmutable('now', new DateTimeZone('UTC')); + } + return $this->ranking_hidden_at <= $now && !$this->isFinished($now); + } + + public static function create( + string $title, + string $slug, + string $description, + string $example_code, + ?int $birdie_code_size, + DateTimeImmutable $started_at, + DateTimeImmutable $ranking_hidden_at, + DateTimeImmutable $finished_at, + ): self { + self::validate( + $title, + $slug, + $description, + $example_code, + $birdie_code_size, + $started_at, + $ranking_hidden_at, + $finished_at, + ); + $quiz = new self( + quiz_id: 0, + created_at: new DateTimeImmutable(), // dummy + started_at: $started_at, + ranking_hidden_at: $ranking_hidden_at, + finished_at: $finished_at, + title: $title, + slug: $slug, + description: $description, + example_code: $example_code, + birdie_code_size: $birdie_code_size, + ); + return $quiz; + } + + public static function validate( + string $title, + string $slug, + string $description, + string $example_code, + ?int $birdie_code_size, + DateTimeImmutable $started_at, + DateTimeImmutable $ranking_hidden_at, + DateTimeImmutable $finished_at, + ): void { + $errors = []; + if (strlen($slug) < 1) { + $errors['slug'] = 'スラグは必須です'; + } + if (32 < strlen($slug)) { + $errors['slug'] = 'スラグは32文字以下である必要があります'; + } + if (strlen($description) < 1) { + $errors['description'] = '説明は必須です'; + } + if (strlen($example_code) < 1) { + $errors['example_code'] = '実装例は必須です'; + } + if ($birdie_code_size !== null && $birdie_code_size < 1) { + $errors['birdie_code_size'] = 'バーディになるコードサイズは 1 byte 以上である必要があります'; + } + if ($ranking_hidden_at < $started_at) { + $errors['ranking_hidden_at'] = 'ランキングが非表示になる日時は開始日時より後である必要があります'; + } + if ($finished_at < $ranking_hidden_at) { + $errors['finished_at'] = '終了日時はランキングが非表示になる日時より後である必要があります'; + } + + if (0 < count($errors)) { + throw new EntityValidationException(errors: $errors); + } + } +} diff --git a/services/app/src/Models/Testcase.php b/services/app/src/Models/Testcase.php new file mode 100644 index 0000000..68ee891 --- /dev/null +++ b/services/app/src/Models/Testcase.php @@ -0,0 +1,29 @@ +