configreader_yaml.rs 3.12 KB
Newer Older
Robert Czechowski's avatar
Robert Czechowski committed
1
use db_objects::{Contest, Task, Taskgroup};
2
3
4

use serde_yaml;

Robert Czechowski's avatar
Robert Czechowski committed
5
6
7
8
9
10
11
#[derive(Debug, Deserialize)]
struct ContestYaml {
    name: Option<String>,
    participation_start: Option<String>,
    participation_end: Option<String>,
    duration_minutes: Option<u32>,
    public_listing: Option<bool>,
Robert Czechowski's avatar
Robert Czechowski committed
12

Robert Czechowski's avatar
Robert Czechowski committed
13
14
15
    tasks: Option<serde_yaml::Mapping>,
}

16
17
// The task path is stored relatively to the contest.yaml for easier identificationy
// Concatenation happens in functions::show_task
Robert Czechowski's avatar
Robert Czechowski committed
18
19
20
pub fn parse_yaml(content: &str, filename: &str, directory: &str) -> Option<Contest> {
    let config: ContestYaml = serde_yaml::from_str(&content).unwrap();

Robert Czechowski's avatar
Robert Czechowski committed
21
22
23
24
25
26
27
    let mut contest = Contest::new(directory.to_string(),
                                   filename.to_string(),
                                   config.name?,
                                   config.duration_minutes?,
                                   config.public_listing.unwrap_or(false),
                                   None,
                                   None);
Robert Czechowski's avatar
Robert Czechowski committed
28
29
30
31
32
33

    for (name, info) in config.tasks? {
        if let serde_yaml::Value::String(name) = name {
            let mut taskgroup = Taskgroup::new(name);
            match info {
                serde_yaml::Value::String(taskdir) => {
34
                    let task = Task::new(taskdir, 3);
Robert Czechowski's avatar
Robert Czechowski committed
35
                    taskgroup.tasks.push(task);
Robert Czechowski's avatar
Robert Czechowski committed
36
                }
Robert Czechowski's avatar
Robert Czechowski committed
37
38
39
40
                serde_yaml::Value::Sequence(taskdirs) => {
                    let mut stars = 2;
                    for taskdir in taskdirs {
                        if let serde_yaml::Value::String(taskdir) = taskdir {
41
                            let task = Task::new(taskdir, stars);
Robert Czechowski's avatar
Robert Czechowski committed
42
                            taskgroup.tasks.push(task);
Robert Czechowski's avatar
Robert Czechowski committed
43
                        } else {
Robert Czechowski's avatar
Robert Czechowski committed
44
45
                            panic!("Invalid contest YAML: {}{} (a)", directory, filename)
                        }
Robert Czechowski's avatar
Robert Czechowski committed
46

Robert Czechowski's avatar
Robert Czechowski committed
47
48
49
50
51
52
                        stars += 1;
                    }
                }
                serde_yaml::Value::Mapping(taskdirs) => {
                    let mut stars = 2;
                    for (taskdir, taskinfo) in taskdirs {
Robert Czechowski's avatar
Robert Czechowski committed
53
54
55
56
57
58
                        if let (serde_yaml::Value::String(taskdir), serde_yaml::Value::Mapping(taskinfo)) =
                            (taskdir, taskinfo)
                        {
                            if let Some(serde_yaml::Value::Number(cstars)) =
                                taskinfo.get(&serde_yaml::Value::String("stars".to_string()))
                            {
59
                                stars = cstars.as_u64().unwrap() as i8;
Robert Czechowski's avatar
Robert Czechowski committed
60
                            }
61
                            let task = Task::new(taskdir, stars);
Robert Czechowski's avatar
Robert Czechowski committed
62
63
                            taskgroup.tasks.push(task);
                            stars += 1;
Robert Czechowski's avatar
Robert Czechowski committed
64
                        } else {
Robert Czechowski's avatar
Robert Czechowski committed
65
66
67
68
                            panic!("Invalid contest YAML: {}{} (b)", directory, filename)
                        }
                    }
                }
Robert Czechowski's avatar
Robert Czechowski committed
69
                _ => panic!("Invalid contest YAML: {}{} (c)", directory, filename),
Robert Czechowski's avatar
Robert Czechowski committed
70
71
            }
            contest.taskgroups.push(taskgroup);
Robert Czechowski's avatar
Robert Czechowski committed
72
        } else {
Robert Czechowski's avatar
Robert Czechowski committed
73
74
75
76
77
78
            panic!("Invalid contest YAML: {}{} (d)", directory, filename)
        }
    }

    Some(contest)
}