Add saving periods
This commit is contained in:
parent
12d57d020f
commit
483fd60daa
13 changed files with 271 additions and 52 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -9,3 +9,4 @@ emgauwa-core.sqlite
|
||||||
# Added by cargo
|
# Added by cargo
|
||||||
|
|
||||||
/target
|
/target
|
||||||
|
/api.http
|
||||||
|
|
50
Cargo.lock
generated
50
Cargo.lock
generated
|
@ -81,7 +81,7 @@ dependencies = [
|
||||||
"serde_urlencoded",
|
"serde_urlencoded",
|
||||||
"sha-1",
|
"sha-1",
|
||||||
"slab",
|
"slab",
|
||||||
"time",
|
"time 0.2.27",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -247,7 +247,7 @@ dependencies = [
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_urlencoded",
|
"serde_urlencoded",
|
||||||
"socket2",
|
"socket2",
|
||||||
"time",
|
"time 0.2.27",
|
||||||
"tinyvec",
|
"tinyvec",
|
||||||
"url",
|
"url",
|
||||||
]
|
]
|
||||||
|
@ -417,6 +417,20 @@ version = "1.0.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "chrono"
|
||||||
|
version = "0.4.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"num-integer",
|
||||||
|
"num-traits",
|
||||||
|
"serde",
|
||||||
|
"time 0.1.43",
|
||||||
|
"winapi 0.3.9",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "const_fn"
|
name = "const_fn"
|
||||||
version = "0.4.8"
|
version = "0.4.8"
|
||||||
|
@ -436,7 +450,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "03a5d7b21829bc7b4bf4754a978a241ae54ea55a40f92bb20216e54096f4b951"
|
checksum = "03a5d7b21829bc7b4bf4754a978a241ae54ea55a40f92bb20216e54096f4b951"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"time",
|
"time 0.2.27",
|
||||||
"version_check",
|
"version_check",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -542,6 +556,7 @@ name = "emgauwa-core"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"actix-web",
|
"actix-web",
|
||||||
|
"chrono",
|
||||||
"diesel",
|
"diesel",
|
||||||
"diesel_migrations",
|
"diesel_migrations",
|
||||||
"dotenv",
|
"dotenv",
|
||||||
|
@ -1047,6 +1062,25 @@ dependencies = [
|
||||||
"winapi 0.3.9",
|
"winapi 0.3.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-integer"
|
||||||
|
version = "0.1.44"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"num-traits",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "num-traits"
|
||||||
|
version = "0.2.14"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num_cpus"
|
name = "num_cpus"
|
||||||
version = "1.13.0"
|
version = "1.13.0"
|
||||||
|
@ -1541,6 +1575,16 @@ dependencies = [
|
||||||
"num_cpus",
|
"num_cpus",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "time"
|
||||||
|
version = "0.1.43"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"winapi 0.3.9",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "time"
|
name = "time"
|
||||||
version = "0.2.27"
|
version = "0.2.27"
|
||||||
|
|
|
@ -11,6 +11,7 @@ authors = ["Tobias Reisinger <tobias@msrg.cc>"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
actix-web = "3"
|
actix-web = "3"
|
||||||
|
chrono = { version = "0.4", features = ["serde"] }
|
||||||
diesel = { version = "1.4", features = ["sqlite", "uuid"] }
|
diesel = { version = "1.4", features = ["sqlite", "uuid"] }
|
||||||
diesel_migrations = "1.4"
|
diesel_migrations = "1.4"
|
||||||
dotenv = "0.15"
|
dotenv = "0.15"
|
||||||
|
|
|
@ -41,13 +41,13 @@ CREATE TABLE schedules
|
||||||
UNIQUE,
|
UNIQUE,
|
||||||
name VARCHAR(128)
|
name VARCHAR(128)
|
||||||
NOT NULL,
|
NOT NULL,
|
||||||
periods TEXT
|
periods BLOB
|
||||||
NOT NULL
|
NOT NULL
|
||||||
);
|
);
|
||||||
--INSERT INTO schedules (uid, name, periods) VALUES (x'6f666600000000000000000000000000', 'off', x'00');
|
--INSERT INTO schedules (uid, name, periods) VALUES (x'6f666600000000000000000000000000', 'off', x'00');
|
||||||
--INSERT INTO schedules (uid, name, periods) VALUES (x'6f6e0000000000000000000000000000', 'on', x'010000009F05');
|
--INSERT INTO schedules (uid, name, periods) VALUES (x'6f6e0000000000000000000000000000', 'on', x'010000009F05');
|
||||||
INSERT INTO schedules (uid, name, periods) VALUES (x'00', 'off', '00');
|
INSERT INTO schedules (uid, name, periods) VALUES (x'00', 'off', x'');
|
||||||
INSERT INTO schedules (uid, name, periods) VALUES (x'01', 'on', '010000009F05');
|
INSERT INTO schedules (uid, name, periods) VALUES (x'01', 'on', x'0000173B');
|
||||||
|
|
||||||
CREATE TABLE tags
|
CREATE TABLE tags
|
||||||
(
|
(
|
||||||
|
|
41
src/db.rs
41
src/db.rs
|
@ -1,20 +1,18 @@
|
||||||
|
use std::env;
|
||||||
|
|
||||||
|
use diesel::dsl::sql;
|
||||||
|
use diesel::prelude::*;
|
||||||
|
use diesel_migrations::embed_migrations;
|
||||||
|
use dotenv::dotenv;
|
||||||
|
|
||||||
|
use errors::DatabaseError;
|
||||||
|
use models::*;
|
||||||
|
use schema::schedules::dsl::*;
|
||||||
|
use crate::types::EmgauwaUid;
|
||||||
|
|
||||||
pub mod errors;
|
pub mod errors;
|
||||||
pub mod models;
|
pub mod models;
|
||||||
pub mod schema;
|
pub mod schema;
|
||||||
mod types;
|
|
||||||
|
|
||||||
use diesel::prelude::*;
|
|
||||||
|
|
||||||
use diesel::dsl::sql;
|
|
||||||
use dotenv::dotenv;
|
|
||||||
use std::env;
|
|
||||||
|
|
||||||
use models::*;
|
|
||||||
use schema::schedules::dsl::*;
|
|
||||||
|
|
||||||
use diesel_migrations::embed_migrations;
|
|
||||||
use errors::DatabaseError;
|
|
||||||
use types::EmgauwaUid;
|
|
||||||
|
|
||||||
embed_migrations!("migrations");
|
embed_migrations!("migrations");
|
||||||
|
|
||||||
|
@ -34,18 +32,27 @@ pub fn run_migrations() {
|
||||||
pub fn get_schedules() -> Vec<Schedule> {
|
pub fn get_schedules() -> Vec<Schedule> {
|
||||||
let connection = get_connection();
|
let connection = get_connection();
|
||||||
schedules
|
schedules
|
||||||
.limit(5)
|
|
||||||
.load::<Schedule>(&connection)
|
.load::<Schedule>(&connection)
|
||||||
.expect("Error loading schedules")
|
.expect("Error loading schedules")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_schedule(new_name: &str) -> Result<Schedule, DatabaseError> {
|
pub fn get_schedule_by_uid(filter_uid: EmgauwaUid) -> Result<Schedule, DatabaseError> {
|
||||||
|
let connection = get_connection();
|
||||||
|
let result = schedules
|
||||||
|
.filter(uid.eq(filter_uid))
|
||||||
|
.first::<Schedule>(&connection)
|
||||||
|
.or(Err(DatabaseError::NotFound))?;
|
||||||
|
|
||||||
|
Ok(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_schedule(new_name: &str, new_periods: &Periods) -> Result<Schedule, DatabaseError> {
|
||||||
let connection = get_connection();
|
let connection = get_connection();
|
||||||
|
|
||||||
let new_schedule = NewSchedule {
|
let new_schedule = NewSchedule {
|
||||||
uid: &EmgauwaUid::default(),
|
uid: &EmgauwaUid::default(),
|
||||||
name: new_name,
|
name: new_name,
|
||||||
periods: "",
|
periods: new_periods
|
||||||
};
|
};
|
||||||
|
|
||||||
diesel::insert_into(schedules)
|
diesel::insert_into(schedules)
|
||||||
|
|
|
@ -4,6 +4,16 @@ use serde::{Serialize, Serializer};
|
||||||
pub enum DatabaseError {
|
pub enum DatabaseError {
|
||||||
InsertError,
|
InsertError,
|
||||||
InsertGetError,
|
InsertGetError,
|
||||||
|
NotFound,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl DatabaseError {
|
||||||
|
fn to_code(&self) -> u32 {
|
||||||
|
match self {
|
||||||
|
DatabaseError::NotFound => 404,
|
||||||
|
_ => 500
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Serialize for DatabaseError {
|
impl Serialize for DatabaseError {
|
||||||
|
@ -11,8 +21,9 @@ impl Serialize for DatabaseError {
|
||||||
where
|
where
|
||||||
S: Serializer,
|
S: Serializer,
|
||||||
{
|
{
|
||||||
let mut s = serializer.serialize_struct("error", 2)?;
|
let mut s = serializer.serialize_struct("error", 3)?;
|
||||||
s.serialize_field("code", &500)?;
|
s.serialize_field("type", "database-error")?;
|
||||||
|
s.serialize_field("code", &self.to_code())?;
|
||||||
s.serialize_field("description", &String::from(self))?;
|
s.serialize_field("description", &String::from(self))?;
|
||||||
s.end()
|
s.end()
|
||||||
}
|
}
|
||||||
|
@ -25,6 +36,7 @@ impl From<&DatabaseError> for String {
|
||||||
DatabaseError::InsertGetError => {
|
DatabaseError::InsertGetError => {
|
||||||
String::from("error retrieving new entry from database (your entry was saved)")
|
String::from("error retrieving new entry from database (your entry was saved)")
|
||||||
}
|
}
|
||||||
|
DatabaseError::NotFound => String::from("model was not found in database")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,24 @@
|
||||||
use super::types::EmgauwaUid;
|
use chrono::{NaiveTime, Timelike};
|
||||||
use serde::Serialize;
|
use diesel::backend::Backend;
|
||||||
|
use diesel::deserialize::FromSql;
|
||||||
|
use diesel::serialize::{IsNull, Output, ToSql};
|
||||||
|
use diesel::sql_types::Binary;
|
||||||
|
use diesel::sqlite::Sqlite;
|
||||||
|
use diesel::{deserialize, serialize};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::io::Write;
|
||||||
|
|
||||||
use super::schema::schedules;
|
use super::schema::schedules;
|
||||||
|
use crate::types::EmgauwaUid;
|
||||||
|
|
||||||
#[derive(Serialize, Queryable)]
|
#[derive(Serialize, Queryable)]
|
||||||
pub struct Schedule {
|
pub struct Schedule {
|
||||||
|
#[serde(skip)]
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
|
#[serde(alias = "id")]
|
||||||
pub uid: EmgauwaUid,
|
pub uid: EmgauwaUid,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub periods: String,
|
pub periods: Periods,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Insertable)]
|
#[derive(Insertable)]
|
||||||
|
@ -16,5 +26,74 @@ pub struct Schedule {
|
||||||
pub struct NewSchedule<'a> {
|
pub struct NewSchedule<'a> {
|
||||||
pub uid: &'a EmgauwaUid,
|
pub uid: &'a EmgauwaUid,
|
||||||
pub name: &'a str,
|
pub name: &'a str,
|
||||||
pub periods: &'a str,
|
pub periods: &'a Periods,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize, AsExpression, FromSqlRow, PartialEq, Clone)]
|
||||||
|
#[sql_type = "Binary"]
|
||||||
|
pub struct Period {
|
||||||
|
#[serde(with = "period_format")]
|
||||||
|
pub start: NaiveTime,
|
||||||
|
#[serde(with = "period_format")]
|
||||||
|
pub end: NaiveTime,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize, AsExpression, FromSqlRow, PartialEq, Clone)]
|
||||||
|
#[sql_type = "Binary"]
|
||||||
|
pub struct Periods(pub(crate) Vec<Period>);
|
||||||
|
|
||||||
|
mod period_format {
|
||||||
|
use chrono::NaiveTime;
|
||||||
|
use serde::{self, Deserialize, Deserializer, Serializer};
|
||||||
|
|
||||||
|
const FORMAT: &'static str = "%H:%M";
|
||||||
|
|
||||||
|
pub fn serialize<S>(time: &NaiveTime, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: Serializer,
|
||||||
|
{
|
||||||
|
let s = format!("{}", time.format(FORMAT));
|
||||||
|
serializer.serialize_str(&s)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn deserialize<'de, D>(deserializer: D) -> Result<NaiveTime, D::Error>
|
||||||
|
where
|
||||||
|
D: Deserializer<'de>,
|
||||||
|
{
|
||||||
|
let s = String::deserialize(deserializer)?;
|
||||||
|
NaiveTime::parse_from_str(&s, FORMAT).map_err(serde::de::Error::custom)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToSql<Binary, Sqlite> for Periods {
|
||||||
|
fn to_sql<W: Write>(&self, out: &mut Output<W, Sqlite>) -> serialize::Result {
|
||||||
|
for period in self.0.iter() {
|
||||||
|
out.write_all(&[
|
||||||
|
period.start.hour() as u8,
|
||||||
|
period.start.minute() as u8,
|
||||||
|
period.end.hour() as u8,
|
||||||
|
period.end.minute() as u8,
|
||||||
|
])?;
|
||||||
|
}
|
||||||
|
Ok(IsNull::No)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromSql<Binary, Sqlite> for Periods {
|
||||||
|
fn from_sql(bytes: Option<&<Sqlite as Backend>::RawValue>) -> deserialize::Result<Self> {
|
||||||
|
let blob = bytes.unwrap().read_blob();
|
||||||
|
|
||||||
|
let mut vec = Vec::new();
|
||||||
|
for i in (3..blob.len()).step_by(4) {
|
||||||
|
let start_val_h: u32 = blob[i - 3] as u32;
|
||||||
|
let start_val_m: u32 = blob[i - 2] as u32;
|
||||||
|
let end_val_h: u32 = blob[i - 1] as u32;
|
||||||
|
let end_val_m: u32 = blob[i - 0] as u32;
|
||||||
|
vec.push(Period {
|
||||||
|
start: NaiveTime::from_hms(start_val_h, start_val_m, 0),
|
||||||
|
end: NaiveTime::from_hms(end_val_h, end_val_m, 0),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Ok(Periods(vec))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ table! {
|
||||||
id -> Integer,
|
id -> Integer,
|
||||||
uid -> Binary,
|
uid -> Binary,
|
||||||
name -> Text,
|
name -> Text,
|
||||||
periods -> Text,
|
periods -> Binary,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
34
src/handlers/errors.rs
Normal file
34
src/handlers/errors.rs
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
use serde::ser::SerializeStruct;
|
||||||
|
use serde::{Serialize, Serializer};
|
||||||
|
|
||||||
|
pub enum HandlerError {
|
||||||
|
BadUidError,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HandlerError {
|
||||||
|
fn to_code(&self) -> u32 {
|
||||||
|
match self {
|
||||||
|
HandlerError::BadUidError => 400
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Serialize for HandlerError {
|
||||||
|
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
S: Serializer,
|
||||||
|
{
|
||||||
|
let mut s = serializer.serialize_struct("error", 2)?;
|
||||||
|
s.serialize_field("code", &self.to_code())?;
|
||||||
|
s.serialize_field("description", &String::from(self))?;
|
||||||
|
s.end()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&HandlerError> for String {
|
||||||
|
fn from(err: &HandlerError) -> Self {
|
||||||
|
match err {
|
||||||
|
HandlerError::BadUidError => String::from("the uid is in a bad format"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1 +1,2 @@
|
||||||
pub mod v1;
|
pub mod v1;
|
||||||
|
mod errors;
|
||||||
|
|
|
@ -1,17 +1,58 @@
|
||||||
|
use std::str::FromStr;
|
||||||
|
use actix_web::{HttpResponse, Responder, web, get};
|
||||||
|
use serde::{Serialize, Deserialize};
|
||||||
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::db;
|
use crate::db;
|
||||||
use actix_web::{HttpResponse, Responder};
|
use crate::db::models::Periods;
|
||||||
|
use crate::handlers::errors::HandlerError;
|
||||||
|
use crate::types::EmgauwaUid;
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct RequestSchedule {
|
||||||
|
name: String,
|
||||||
|
periods: Periods,
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn index() -> impl Responder {
|
pub async fn index() -> impl Responder {
|
||||||
let schedules = db::get_schedules();
|
let schedules = db::get_schedules();
|
||||||
HttpResponse::Ok().json(schedules)
|
HttpResponse::Ok().json(schedules)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get() -> impl Responder {
|
#[get("/api/v1/schedules/{schedule_id}")]
|
||||||
"hello from get schedules by id"
|
pub async fn show(web::Path((schedule_uid,)): web::Path<(String,)>) -> impl Responder {
|
||||||
|
|
||||||
|
let emgauwa_uid = match schedule_uid.as_str() {
|
||||||
|
"on" => Ok(EmgauwaUid::On),
|
||||||
|
"off" => Ok(EmgauwaUid::Off),
|
||||||
|
any => match Uuid::from_str(any) {
|
||||||
|
Ok(uuid) => Ok(EmgauwaUid::Any(uuid)),
|
||||||
|
Err(_) => Err(HandlerError::BadUidError)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
match emgauwa_uid {
|
||||||
|
Ok(uid) => {
|
||||||
|
let schedule = db::get_schedule_by_uid(uid);
|
||||||
|
match schedule {
|
||||||
|
Ok(ok) => HttpResponse::Ok().json(ok),
|
||||||
|
Err(err) => HttpResponse::NotFound().json(err),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Err(err) => HttpResponse::BadRequest().json(err)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn add() -> impl Responder {
|
pub async fn add(post: web::Json<RequestSchedule>) -> impl Responder {
|
||||||
let new_schedule = db::create_schedule("TEST");
|
|
||||||
|
println!("model: {:?}", post);
|
||||||
|
|
||||||
|
for period in post.periods.0.iter() {
|
||||||
|
println!("start: {:?}; end: {:?}", period.start, period.end);
|
||||||
|
}
|
||||||
|
|
||||||
|
let new_schedule = db::create_schedule(&post.name, &post.periods);
|
||||||
|
|
||||||
match new_schedule {
|
match new_schedule {
|
||||||
Ok(ok) => HttpResponse::Ok().json(ok),
|
Ok(ok) => HttpResponse::Ok().json(ok),
|
||||||
|
|
14
src/main.rs
14
src/main.rs
|
@ -1,13 +1,14 @@
|
||||||
mod db;
|
|
||||||
mod handlers;
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate diesel;
|
extern crate diesel;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate diesel_migrations;
|
extern crate diesel_migrations;
|
||||||
extern crate dotenv;
|
extern crate dotenv;
|
||||||
|
|
||||||
use actix_web::{web, App, HttpServer};
|
use actix_web::{App, HttpServer, web};
|
||||||
|
|
||||||
|
mod db;
|
||||||
|
mod handlers;
|
||||||
|
mod types;
|
||||||
|
|
||||||
#[actix_web::main]
|
#[actix_web::main]
|
||||||
async fn main() -> std::io::Result<()> {
|
async fn main() -> std::io::Result<()> {
|
||||||
|
@ -23,10 +24,7 @@ async fn main() -> std::io::Result<()> {
|
||||||
"/api/v1/schedules",
|
"/api/v1/schedules",
|
||||||
web::post().to(handlers::v1::schedules::add),
|
web::post().to(handlers::v1::schedules::add),
|
||||||
)
|
)
|
||||||
.route(
|
.service(handlers::v1::schedules::show)
|
||||||
"/api/v1/schedules/{id}",
|
|
||||||
web::get().to(handlers::v1::schedules::get),
|
|
||||||
)
|
|
||||||
.route(
|
.route(
|
||||||
"/api/v1/schedules/{id}",
|
"/api/v1/schedules/{id}",
|
||||||
web::delete().to(handlers::v1::schedules::delete),
|
web::delete().to(handlers::v1::schedules::delete),
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
use std::fmt::{Debug, Formatter};
|
||||||
|
use std::io::Write;
|
||||||
|
|
||||||
use diesel::backend::Backend;
|
use diesel::backend::Backend;
|
||||||
use diesel::deserialize::FromSql;
|
use diesel::deserialize::FromSql;
|
||||||
use diesel::serialize::{IsNull, Output, ToSql};
|
use diesel::serialize::{IsNull, Output, ToSql};
|
||||||
|
@ -5,8 +8,6 @@ use diesel::sql_types::Binary;
|
||||||
use diesel::sqlite::Sqlite;
|
use diesel::sqlite::Sqlite;
|
||||||
use diesel::{deserialize, serialize};
|
use diesel::{deserialize, serialize};
|
||||||
use serde::{Serialize, Serializer};
|
use serde::{Serialize, Serializer};
|
||||||
use std::fmt::{Debug, Formatter};
|
|
||||||
use std::io::Write;
|
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
#[derive(AsExpression, FromSqlRow, PartialEq, Clone)]
|
#[derive(AsExpression, FromSqlRow, PartialEq, Clone)]
|
||||||
|
@ -22,6 +23,7 @@ impl Default for EmgauwaUid {
|
||||||
EmgauwaUid::Any(Uuid::new_v4())
|
EmgauwaUid::Any(Uuid::new_v4())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for EmgauwaUid {
|
impl Debug for EmgauwaUid {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
match self {
|
match self {
|
||||||
|
@ -31,6 +33,7 @@ impl Debug for EmgauwaUid {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToSql<Binary, Sqlite> for EmgauwaUid {
|
impl ToSql<Binary, Sqlite> for EmgauwaUid {
|
||||||
fn to_sql<W: Write>(&self, out: &mut Output<W, Sqlite>) -> serialize::Result {
|
fn to_sql<W: Write>(&self, out: &mut Output<W, Sqlite>) -> serialize::Result {
|
||||||
match self {
|
match self {
|
||||||
|
@ -41,6 +44,7 @@ impl ToSql<Binary, Sqlite> for EmgauwaUid {
|
||||||
Ok(IsNull::No)
|
Ok(IsNull::No)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromSql<Binary, Sqlite> for EmgauwaUid {
|
impl FromSql<Binary, Sqlite> for EmgauwaUid {
|
||||||
fn from_sql(bytes: Option<&<Sqlite as Backend>::RawValue>) -> deserialize::Result<Self> {
|
fn from_sql(bytes: Option<&<Sqlite as Backend>::RawValue>) -> deserialize::Result<Self> {
|
||||||
match bytes {
|
match bytes {
|
||||||
|
@ -59,13 +63,10 @@ impl Serialize for EmgauwaUid {
|
||||||
where
|
where
|
||||||
S: Serializer,
|
S: Serializer,
|
||||||
{
|
{
|
||||||
match self {
|
String::from(self).serialize(serializer)
|
||||||
EmgauwaUid::On => "off".serialize(serializer),
|
|
||||||
EmgauwaUid::Off => "on".serialize(serializer),
|
|
||||||
EmgauwaUid::Any(value) => value.serialize(serializer),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Uuid> for EmgauwaUid {
|
impl From<Uuid> for EmgauwaUid {
|
||||||
fn from(uid: Uuid) -> EmgauwaUid {
|
fn from(uid: Uuid) -> EmgauwaUid {
|
||||||
match uid.as_u128() {
|
match uid.as_u128() {
|
||||||
|
@ -89,8 +90,8 @@ impl From<&EmgauwaUid> for Uuid {
|
||||||
impl From<&EmgauwaUid> for String {
|
impl From<&EmgauwaUid> for String {
|
||||||
fn from(emgauwa_uid: &EmgauwaUid) -> String {
|
fn from(emgauwa_uid: &EmgauwaUid) -> String {
|
||||||
match emgauwa_uid {
|
match emgauwa_uid {
|
||||||
EmgauwaUid::On => String::from("off"),
|
EmgauwaUid::Off => String::from("off"),
|
||||||
EmgauwaUid::Off => String::from("on"),
|
EmgauwaUid::On => String::from("on"),
|
||||||
EmgauwaUid::Any(value) => value.to_hyphenated().to_string(),
|
EmgauwaUid::Any(value) => value.to_hyphenated().to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Add table
Add a link
Reference in a new issue