libellule 0.1.4

Unofficial implementation of the PRONOTE protocol
Documentation
use crate::error::ConversionError;
use crate::model;
use crate::protocol;

pub(crate) fn timetable(
    raw: protocol::Timetable,
    parameters: &model::Parameters,
) -> Result<model::Timetable, ConversionError> {
    let mut lessons: Vec<model::Lesson> = raw
        .lessons
        .into_iter()
        .map(|lesson| self::lesson(lesson, parameters, raw.start_place))
        .collect::<Result<_, _>>()?;

    lessons.sort_by_key(|lesson| lesson.start);

    let lunch_break_start = parameters.place_to_time(raw.lunch_break_start - raw.start_place);
    let lunch_break_end = parameters.place_to_time(raw.lunch_break_end - raw.start_place);

    let lunch_break = model::LunchBreak {
        start: lunch_break_start,
        end: lunch_break_end,
    };

    Ok(model::Timetable {
        lessons,
        lunch_break,
    })
}

fn lesson(
    raw: protocol::Lesson,
    parameters: &model::Parameters,
    start: u32,
) -> Result<model::Lesson, ConversionError> {
    let start = parameters.place_to_time(raw.start - start);
    let end = start + parameters.instance.place_duration * raw.length;

    let mut teachers = Vec::new();
    let mut subject = None;
    let mut locations = Vec::new();
    let mut groups = Vec::new();

    for information in raw.information.value.into_iter() {
        match information.kind {
            2 => groups.push(model::Group {
                id: information.id.unwrap(),
                name: information.label,
            }),
            3 => teachers.push(information.label),
            16 => {
                subject = Some(model::TimetableSubject {
                    id: information.id.unwrap(),
                    name: information.label,
                })
            }
            17 => locations.push(model::Location {
                id: information.id.unwrap(),
                name: information.label,
            }),
            _ => return Err(ConversionError::Parse),
        };
    }

    Ok(model::Lesson {
        id: raw.id,
        kind: raw.kind,
        start,
        end,
        teachers,
        subject: subject.unwrap(),
        locations,
        groups,
        color: raw.color,
        cancelled: raw.cancelled,
    })
}