aboutsummaryrefslogtreecommitdiffstats
path: root/backend/src/snippet.rs
blob: a6732b968fc9e095f285fdb9b453fa2e506b2ecc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
use rustc_serialize::json::{self, ToJson, Json};
use std::collections::BTreeMap;
use std::fs;
use time;
use error::PoeError;
use std::io::{Read, Write};
use run_result;
use config;
use utils;

#[derive(RustcDecodable, RustcEncodable, Debug)]
pub struct SnippetMetadata {
    pub lang: String,
    pub created: i64,
}

#[derive(Debug)]
pub struct Snippet {
    pub id: String,
    pub metadata: SnippetMetadata,
}

impl Snippet {
    pub fn create(lang: &str, code: &str) -> Result<Snippet, PoeError> {
        if config::compilers(&lang).is_none() {
            return Err(PoeError::NotFound);
        }
        let id = utils::uuid();
        let created = time::now_utc().to_timespec().sec;

        let snip_meta = SnippetMetadata { lang: lang.to_string(), created: created };
        let snip = Snippet { id: id, metadata: snip_meta };

        try!(fs::create_dir(snip.basedir()));
        try!(fs::create_dir(snip.basedir() + "/results"));
        let mut metafile = try!(fs::File::create(snip.basedir() + "/metadata.json"));
        try!(metafile.write(json::encode(&snip.metadata).unwrap().as_bytes()));
        let mut codefile = try!(fs::File::create(snip.code_file()));
        try!(codefile.write(code.as_bytes()));

        Ok(snip)
    }

    pub fn find(id: &str) -> Result<Snippet, PoeError> {
        let metafile_path = config::datadir() + "/snippets/" + &id + "/metadata.json";
        let mut metafile = try!(fs::File::open(metafile_path));
        let mut encoded = String::new();
        try!(metafile.read_to_string(&mut encoded));
        Ok(Snippet { id: id.to_string(), metadata: try!(json::decode(&encoded)) })
    }

    pub fn code_file(&self) -> String {
        self.basedir() + "/code"
    }

    pub fn basedir(&self) -> String {
        config::datadir() + "/snippets/" + &self.id
    }

    pub fn render(&self) -> Json {
        let mut map = BTreeMap::new();
        map.insert("id".to_string(), self.id.to_json());
        map.insert("lang".to_string(), self.metadata.lang.to_json());
        map.insert("created".to_string(), self.metadata.created.to_json());
        map.insert("code".to_string(), self.read_code().to_json());
        map.insert("results".to_string(), self.render_results());
        Json::Object(map)
    }

    fn read_code(&self) -> String {
        let mut codefile = fs::File::open(config::datadir() + "/snippets/" + &self.id + "/code").unwrap();
        let mut code = String::new();
        codefile.read_to_string(&mut code).unwrap();
        code
    }

    fn render_results(&self) -> Json {
        config::compilers(&self.metadata.lang).unwrap().iter().map(|kv| {
            run_result::open_render(&self, &kv.1)
        }).collect::<Vec<_>>().to_json()
    }
}