173 lines
4.4 KiB
Rust
173 lines
4.4 KiB
Rust
//! Request bodies and path parameters, kept apart from the domain models so the public
|
|
//! contract does not change every time a domain model does.
|
|
|
|
use chrono::{DateTime, NaiveTime, Utc};
|
|
use schemars::JsonSchema;
|
|
use serde::Deserialize;
|
|
|
|
use crate::core::models::{
|
|
course::{CourseData, CourseId, CourseKind},
|
|
course_file::CourseFileId,
|
|
focus::TimetaggerRecord,
|
|
grade::{GradeData, GradeId},
|
|
tag::TagId,
|
|
task::{TaskData, TaskId},
|
|
time_slot::{TimeSlotData, TimeSlotId},
|
|
};
|
|
|
|
#[derive(Deserialize, JsonSchema)]
|
|
pub struct CoursePath {
|
|
pub id: CourseId,
|
|
}
|
|
|
|
#[derive(Deserialize, JsonSchema)]
|
|
pub struct SlotPath {
|
|
/// Id of the course
|
|
pub id: CourseId,
|
|
pub slot_id: TimeSlotId,
|
|
}
|
|
|
|
#[derive(Deserialize, JsonSchema)]
|
|
pub struct GradePath {
|
|
pub id: GradeId,
|
|
}
|
|
|
|
#[derive(Deserialize, JsonSchema)]
|
|
pub struct TaskPath {
|
|
pub id: TaskId,
|
|
}
|
|
|
|
#[derive(Deserialize, JsonSchema)]
|
|
pub struct LectureNotePath {
|
|
pub id: CourseFileId,
|
|
}
|
|
|
|
/// Period `[from, to[`, at most 62 days
|
|
#[derive(Deserialize, JsonSchema)]
|
|
pub struct PeriodQuery {
|
|
pub from: DateTime<Utc>,
|
|
pub to: DateTime<Utc>,
|
|
}
|
|
|
|
/// A course or an association, without its slots: they are added and removed one by one
|
|
#[derive(Deserialize, JsonSchema)]
|
|
pub struct CourseBody {
|
|
/// `course` by default. Cannot be changed once created.
|
|
pub kind: Option<CourseKind>,
|
|
pub name: String,
|
|
pub code: Option<String>,
|
|
/// At least one for a course
|
|
#[serde(default)]
|
|
pub teachers: Vec<String>,
|
|
/// http(s) url of the main page of the course
|
|
pub main_page_url: Option<String>,
|
|
}
|
|
|
|
#[derive(Deserialize, JsonSchema)]
|
|
pub struct TimeSlotBody {
|
|
pub tag_id: TagId,
|
|
/// ISO weekday: 1 = monday ... 5 = friday
|
|
pub weekday: u8,
|
|
/// Between 08:00 and 19:00, before `end_time`
|
|
pub start_time: NaiveTime,
|
|
pub end_time: NaiveTime,
|
|
}
|
|
|
|
/// A grade on any scale, e.g. 20 out of 100
|
|
#[derive(Deserialize, JsonSchema)]
|
|
pub struct GradeBody {
|
|
pub name: String,
|
|
/// Between 0 and `max_score`
|
|
pub score: f64,
|
|
/// Positive
|
|
pub max_score: f64,
|
|
/// Positive, relative to the other grades of the course
|
|
pub weight: f64,
|
|
}
|
|
|
|
#[derive(Deserialize, JsonSchema)]
|
|
pub struct TaskBody {
|
|
pub name: String,
|
|
pub description: Option<String>,
|
|
/// http(s) urls
|
|
#[serde(default)]
|
|
pub links: Vec<String>,
|
|
pub deadline: Option<DateTime<Utc>>,
|
|
#[serde(default)]
|
|
pub done: bool,
|
|
/// At least one for a task, optional for a subtask
|
|
#[serde(default)]
|
|
pub tag_ids: Vec<TagId>,
|
|
}
|
|
|
|
#[derive(Deserialize, JsonSchema)]
|
|
pub struct CreateTaskBody {
|
|
/// Creates a subtask of this task, which must be a task of the same course
|
|
pub parent_id: Option<TaskId>,
|
|
#[serde(flatten)]
|
|
pub task: TaskBody,
|
|
}
|
|
|
|
/// End (or pause) of a focus session
|
|
#[derive(Deserialize, JsonSchema)]
|
|
pub struct FocusStopBody {
|
|
/// Length of the session, at most 24 hours
|
|
pub seconds: u32,
|
|
/// Record returned when the session started, to stop it
|
|
pub timetagger: Option<TimetaggerRecord>,
|
|
}
|
|
|
|
#[derive(Deserialize, JsonSchema)]
|
|
pub struct LectureNoteBody {
|
|
/// Subtitle of the pdf, e.g. "Lecture 2 Notes: Memory subsystem"
|
|
pub title: String,
|
|
/// Markdown, without front matter: it is generated from the course
|
|
pub content: String,
|
|
}
|
|
|
|
impl From<CourseBody> for CourseData {
|
|
fn from(value: CourseBody) -> Self {
|
|
CourseData {
|
|
kind: value.kind.unwrap_or(CourseKind::Course),
|
|
name: value.name,
|
|
code: value.code,
|
|
teachers: value.teachers,
|
|
main_page_url: value.main_page_url,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<TimeSlotBody> for TimeSlotData {
|
|
fn from(value: TimeSlotBody) -> Self {
|
|
TimeSlotData {
|
|
tag_id: value.tag_id,
|
|
weekday: value.weekday,
|
|
start_time: value.start_time,
|
|
end_time: value.end_time,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<GradeBody> for GradeData {
|
|
fn from(value: GradeBody) -> Self {
|
|
GradeData {
|
|
name: value.name,
|
|
score: value.score,
|
|
max_score: value.max_score,
|
|
weight: value.weight,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl From<TaskBody> for TaskData {
|
|
fn from(value: TaskBody) -> Self {
|
|
TaskData {
|
|
name: value.name,
|
|
description: value.description,
|
|
links: value.links,
|
|
deadline: value.deadline,
|
|
done: value.done,
|
|
tag_ids: value.tag_ids,
|
|
}
|
|
}
|
|
}
|