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
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
/**
 * Error overrides.
 */
pub mod catchers;
/**
 * Endpoints that deal rfid devices.
 */
pub mod devices_endpoints;
/**
 * Endpoint that deal with videos.
 */
pub mod videos_endpoints;

use serde::Deserialize;
use rocket_contrib::json::{JsonValue};
use serde_json::json;
use rocket::data::{self, FromDataSimple};
use rocket::{Request, Data, Outcome::*};
use rocket::http::Status;
use std::io;
use std::io::Read;

#[derive(Deserialize)]
pub struct VideoBody {
    length_sec: i32
}

#[derive(Deserialize)]
pub struct RegisterBody {
    loc: String,
    tag: String
}

#[derive(Deserialize)]
pub struct StrCont {
    data: String,
}

#[derive(Deserialize)]
pub struct LogMessage {
    error: bool,
    message: String,
}

impl FromDataSimple for StrCont {
    type Error = io::Error;
    #[inline(always)]
    fn from_data(_: &Request, data: Data) -> data::Outcome<Self,  io::Error> {
        let mut value = String::new();
        match data.open().read_to_string(&mut value) {
            Ok(_) => Success(StrCont{data: value}),
            Err(e) => Failure((Status::BadRequest, e))
        }
    }
}

/**
 * Gets the current API version / checks if api is alive
 * 
 * This is an API endpoint mapped to
 * - / [GET]
 */
#[get("/")]
pub fn default() -> &'static str {
    "IoT server v1.0.0"
}

/**
* Logs a message or error to persistent logs.
*
* Returns:
* 
* `{"status": "success", "message": "message|error logged"}`
* 
* # Arguments
* `body` [LogMessage](struct.LogMessage.html) if LogMessage.error is true the message will be logged as an error.
*  */
fn log_message_json(body: LogMessage) -> Result<JsonValue, JsonValue>  {
    match body.error {
        true => {
            colour::yellow!("\n====LOG ERROR FROM IOT====\n");   
            colour::dark_red!("{}", body.message);
            colour::yellow!("\n============================\n");
            Ok(JsonValue(json!({"status": "success", "message": "error logged"})))
        } 
        _ => {
            colour::yellow!("\n====LOG MESSAGE FROM IOT====\n");   
            colour::yellow!("{}", body.message);
            colour::yellow!("\n============================\n");
            Ok(JsonValue(json!({"status": "success", "message": "message logged"})))
        }
    }
}


/**
* Logs a message or error to persistent logs.
*
* Returns:
* 
* `{"status": "success", "message": "message|error logged"}`
* 
* # Arguments
* ## Post body (json):
* `{ error: bool, message: <message_to_log> }`
* `body` [LogMessage](struct.LogMessage.html) if LogMessage.error is true the message will be logged as an error.
*  */
#[post("/logs", data = "<body>")]
pub fn log_message(body: StrCont) -> Result<JsonValue, JsonValue>  {
    match serde_json::from_str::<LogMessage>(&body.data[..]) {
        Ok(val) => log_message_json(val),
        Err(_) => log_message_str(body.data)
    }
}

/**
* Logs a string persistent logs.
*
* Returns:
* `{"status": "success", "message": "message logged"}`
* 
* # Arguments
* `body` String, the string to be logged.
*  */
fn log_message_str(body: String) -> Result<JsonValue, JsonValue>  {    
    colour::yellow!("\n====LOG MESSAGE FROM IOT====\n");
    colour::yellow!("{}", body);
    colour::yellow!("\n============================\n");
    Ok(JsonValue(json!({"status": "success", "message": "message logged"})))
}