Add delete handler and json-payload error response
This commit is contained in:
		
							parent
							
								
									e6278176e4
								
							
						
					
					
						commit
						7254eddc6c
					
				
					 8 changed files with 162 additions and 51 deletions
				
			
		| 
						 | 
					@ -1,7 +1,7 @@
 | 
				
			||||||
[package]
 | 
					[package]
 | 
				
			||||||
name = "emgauwa-core"
 | 
					name = "emgauwa-core"
 | 
				
			||||||
version = "0.1.0"
 | 
					version = "0.1.0"
 | 
				
			||||||
edition = "2021"
 | 
					edition = "2018"
 | 
				
			||||||
authors = ["Tobias Reisinger <tobias@msrg.cc>"]
 | 
					authors = ["Tobias Reisinger <tobias@msrg.cc>"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 | 
					# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										24
									
								
								src/db.rs
									
										
									
									
									
								
							
							
						
						
									
										24
									
								
								src/db.rs
									
										
									
									
									
								
							| 
						 | 
					@ -5,10 +5,10 @@ use diesel::prelude::*;
 | 
				
			||||||
use diesel_migrations::embed_migrations;
 | 
					use diesel_migrations::embed_migrations;
 | 
				
			||||||
use dotenv::dotenv;
 | 
					use dotenv::dotenv;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use crate::types::EmgauwaUid;
 | 
				
			||||||
use errors::DatabaseError;
 | 
					use errors::DatabaseError;
 | 
				
			||||||
use models::*;
 | 
					use models::*;
 | 
				
			||||||
use schema::schedules::dsl::*;
 | 
					use schema::schedules::dsl::*;
 | 
				
			||||||
use crate::types::EmgauwaUid;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub mod errors;
 | 
					pub mod errors;
 | 
				
			||||||
pub mod models;
 | 
					pub mod models;
 | 
				
			||||||
| 
						 | 
					@ -46,13 +46,33 @@ pub fn get_schedule_by_uid(filter_uid: EmgauwaUid) -> Result<Schedule, DatabaseE
 | 
				
			||||||
    Ok(result)
 | 
					    Ok(result)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn delete_schedule_by_uid(filter_uid: EmgauwaUid) -> Result<(), DatabaseError> {
 | 
				
			||||||
 | 
					    let filter_uid = match filter_uid {
 | 
				
			||||||
 | 
					        EmgauwaUid::Off => Err(DatabaseError::Protected),
 | 
				
			||||||
 | 
					        EmgauwaUid::On => Err(DatabaseError::Protected),
 | 
				
			||||||
 | 
					        EmgauwaUid::Any(_) => Ok(filter_uid)
 | 
				
			||||||
 | 
					    }?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let connection = get_connection();
 | 
				
			||||||
 | 
					    match diesel::delete(schedules.filter(uid.eq(filter_uid))).execute(&connection) {
 | 
				
			||||||
 | 
					        Ok(rows) => {
 | 
				
			||||||
 | 
					            if rows != 0 {
 | 
				
			||||||
 | 
					                Ok(())
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                Err(DatabaseError::DeleteError)
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        Err(_) => Err(DatabaseError::DeleteError),
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub fn create_schedule(new_name: &str, new_periods: &Periods) -> Result<Schedule, DatabaseError> {
 | 
					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: new_periods
 | 
					        periods: new_periods,
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    diesel::insert_into(schedules)
 | 
					    diesel::insert_into(schedules)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,17 +1,22 @@
 | 
				
			||||||
 | 
					use actix_web::HttpResponse;
 | 
				
			||||||
 | 
					use actix_web::http::StatusCode;
 | 
				
			||||||
use serde::ser::SerializeStruct;
 | 
					use serde::ser::SerializeStruct;
 | 
				
			||||||
use serde::{Serialize, Serializer};
 | 
					use serde::{Serialize, Serializer};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub enum DatabaseError {
 | 
					pub enum DatabaseError {
 | 
				
			||||||
 | 
					    DeleteError,
 | 
				
			||||||
    InsertError,
 | 
					    InsertError,
 | 
				
			||||||
    InsertGetError,
 | 
					    InsertGetError,
 | 
				
			||||||
    NotFound,
 | 
					    NotFound,
 | 
				
			||||||
 | 
					    Protected
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl DatabaseError {
 | 
					impl DatabaseError {
 | 
				
			||||||
    fn to_code(&self) -> u32 {
 | 
					    fn get_code(&self) -> StatusCode {
 | 
				
			||||||
        match self {
 | 
					        match self {
 | 
				
			||||||
            DatabaseError::NotFound => 404,
 | 
					            DatabaseError::NotFound => StatusCode::NOT_FOUND,
 | 
				
			||||||
            _ => 500
 | 
					            DatabaseError::Protected => StatusCode::FORBIDDEN,
 | 
				
			||||||
 | 
					            _ => StatusCode::INTERNAL_SERVER_ERROR
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -23,7 +28,7 @@ impl Serialize for DatabaseError {
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        let mut s = serializer.serialize_struct("error", 3)?;
 | 
					        let mut s = serializer.serialize_struct("error", 3)?;
 | 
				
			||||||
        s.serialize_field("type", "database-error")?;
 | 
					        s.serialize_field("type", "database-error")?;
 | 
				
			||||||
        s.serialize_field("code", &self.to_code())?;
 | 
					        s.serialize_field("code", &self.get_code().as_u16())?;
 | 
				
			||||||
        s.serialize_field("description", &String::from(self))?;
 | 
					        s.serialize_field("description", &String::from(self))?;
 | 
				
			||||||
        s.end()
 | 
					        s.end()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -32,11 +37,19 @@ impl Serialize for DatabaseError {
 | 
				
			||||||
impl From<&DatabaseError> for String {
 | 
					impl From<&DatabaseError> for String {
 | 
				
			||||||
    fn from(err: &DatabaseError) -> Self {
 | 
					    fn from(err: &DatabaseError) -> Self {
 | 
				
			||||||
        match err {
 | 
					        match err {
 | 
				
			||||||
            DatabaseError::InsertError => String::from("error inserting into database"),
 | 
					            DatabaseError::InsertError => String::from("error on inserting into database"),
 | 
				
			||||||
            DatabaseError::InsertGetError => {
 | 
					            DatabaseError::InsertGetError => {
 | 
				
			||||||
                String::from("error retrieving new entry from database (your entry was saved)")
 | 
					                String::from("error on retrieving new entry from database (your entry was saved)")
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            DatabaseError::NotFound => String::from("model was not found in database")
 | 
					            DatabaseError::NotFound => String::from("model was not found in database"),
 | 
				
			||||||
 | 
					            DatabaseError::DeleteError => String::from("error on deleting from database"),
 | 
				
			||||||
 | 
					            DatabaseError::Protected => String::from("model is protected"),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl From<DatabaseError> for HttpResponse {
 | 
				
			||||||
 | 
					    fn from(err: DatabaseError) -> Self {
 | 
				
			||||||
 | 
					        HttpResponse::build(err.get_code()).json(err)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,16 +1,21 @@
 | 
				
			||||||
 | 
					use actix_web::http::StatusCode;
 | 
				
			||||||
 | 
					use actix_web::HttpResponse;
 | 
				
			||||||
use serde::ser::SerializeStruct;
 | 
					use serde::ser::SerializeStruct;
 | 
				
			||||||
use serde::{Serialize, Serializer};
 | 
					use serde::{Serialize, Serializer};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub enum HandlerError {
 | 
					pub enum HandlerError {
 | 
				
			||||||
    BadUidError,
 | 
					    BadUid,
 | 
				
			||||||
 | 
					    ProtectedSchedule
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl HandlerError {
 | 
					impl HandlerError {
 | 
				
			||||||
    fn to_code(&self) -> u32 {
 | 
					    fn get_code(&self) -> StatusCode {
 | 
				
			||||||
        match self {
 | 
					        match self {
 | 
				
			||||||
            HandlerError::BadUidError => 400
 | 
					            HandlerError::BadUid => StatusCode::BAD_REQUEST,
 | 
				
			||||||
 | 
					            HandlerError::ProtectedSchedule => StatusCode::FORBIDDEN,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl Serialize for HandlerError {
 | 
					impl Serialize for HandlerError {
 | 
				
			||||||
| 
						 | 
					@ -19,7 +24,7 @@ impl Serialize for HandlerError {
 | 
				
			||||||
            S: Serializer,
 | 
					            S: Serializer,
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        let mut s = serializer.serialize_struct("error", 2)?;
 | 
					        let mut s = serializer.serialize_struct("error", 2)?;
 | 
				
			||||||
        s.serialize_field("code", &self.to_code())?;
 | 
					        s.serialize_field("code", &self.get_code().as_u16())?;
 | 
				
			||||||
        s.serialize_field("description", &String::from(self))?;
 | 
					        s.serialize_field("description", &String::from(self))?;
 | 
				
			||||||
        s.end()
 | 
					        s.end()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -28,7 +33,14 @@ impl Serialize for HandlerError {
 | 
				
			||||||
impl From<&HandlerError> for String {
 | 
					impl From<&HandlerError> for String {
 | 
				
			||||||
    fn from(err: &HandlerError) -> Self {
 | 
					    fn from(err: &HandlerError) -> Self {
 | 
				
			||||||
        match err {
 | 
					        match err {
 | 
				
			||||||
            HandlerError::BadUidError => String::from("the uid is in a bad format"),
 | 
					            HandlerError::BadUid => String::from("the uid is in a bad format"),
 | 
				
			||||||
 | 
					            HandlerError::ProtectedSchedule => String::from("the targeted schedule is protected"),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl From<HandlerError> for HttpResponse {
 | 
				
			||||||
 | 
					    fn from(err: HandlerError) -> Self {
 | 
				
			||||||
 | 
					        HttpResponse::build(err.get_code()).json(err)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,2 +1,38 @@
 | 
				
			||||||
 | 
					use actix_web::{error, Error, HttpRequest, HttpResponse};
 | 
				
			||||||
 | 
					use serde::ser::SerializeStruct;
 | 
				
			||||||
 | 
					use serde::{Serialize, Serializer};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub(crate) mod errors;
 | 
				
			||||||
pub mod v1;
 | 
					pub mod v1;
 | 
				
			||||||
mod errors;
 | 
					
 | 
				
			||||||
 | 
					enum EmgauwaJsonPayLoadError {
 | 
				
			||||||
 | 
					    Error(error::JsonPayloadError),
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl Serialize for EmgauwaJsonPayLoadError {
 | 
				
			||||||
 | 
					    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
 | 
				
			||||||
 | 
					    where
 | 
				
			||||||
 | 
					        S: Serializer,
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        let mut s = serializer.serialize_struct("error", 3)?;
 | 
				
			||||||
 | 
					        s.serialize_field("type", "json-payload-error")?;
 | 
				
			||||||
 | 
					        s.serialize_field("code", &400)?;
 | 
				
			||||||
 | 
					        s.serialize_field(
 | 
				
			||||||
 | 
					            "description",
 | 
				
			||||||
 | 
					            &match self {
 | 
				
			||||||
 | 
					                EmgauwaJsonPayLoadError::Error(err) => format!("{}", err),
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        )?;
 | 
				
			||||||
 | 
					        s.end()
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn json_error_handler(err: error::JsonPayloadError, _: &HttpRequest) -> Error {
 | 
				
			||||||
 | 
					    error::InternalError::from_response(
 | 
				
			||||||
 | 
					        "",
 | 
				
			||||||
 | 
					        HttpResponse::BadRequest()
 | 
				
			||||||
 | 
					            .content_type("application/json")
 | 
				
			||||||
 | 
					            .json(EmgauwaJsonPayLoadError::Error(err)),
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					    .into()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,6 @@
 | 
				
			||||||
use std::str::FromStr;
 | 
					use std::convert::TryFrom;
 | 
				
			||||||
use actix_web::{HttpResponse, Responder, web, get};
 | 
					use actix_web::{HttpResponse, Responder, web, get, delete};
 | 
				
			||||||
use serde::{Serialize, Deserialize};
 | 
					use serde::{Serialize, Deserialize};
 | 
				
			||||||
use uuid::Uuid;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::db;
 | 
					use crate::db;
 | 
				
			||||||
use crate::db::models::Periods;
 | 
					use crate::db::models::Periods;
 | 
				
			||||||
| 
						 | 
					@ -22,26 +21,18 @@ pub async fn index() -> impl Responder {
 | 
				
			||||||
#[get("/api/v1/schedules/{schedule_id}")]
 | 
					#[get("/api/v1/schedules/{schedule_id}")]
 | 
				
			||||||
pub async fn show(web::Path((schedule_uid,)): web::Path<(String,)>) -> impl Responder {
 | 
					pub async fn show(web::Path((schedule_uid,)): web::Path<(String,)>) -> impl Responder {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let emgauwa_uid = match schedule_uid.as_str() {
 | 
					    let emgauwa_uid = EmgauwaUid::try_from(schedule_uid.as_str()).or(Err(HandlerError::BadUid));
 | 
				
			||||||
        "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 {
 | 
					    match emgauwa_uid {
 | 
				
			||||||
        Ok(uid) => {
 | 
					        Ok(uid) => {
 | 
				
			||||||
            let schedule = db::get_schedule_by_uid(uid);
 | 
					            let schedule = db::get_schedule_by_uid(uid);
 | 
				
			||||||
            match schedule {
 | 
					            match schedule {
 | 
				
			||||||
                Ok(ok) => HttpResponse::Ok().json(ok),
 | 
					                Ok(ok) => HttpResponse::Ok().json(ok),
 | 
				
			||||||
                Err(err) => HttpResponse::NotFound().json(err),
 | 
					                Err(err) => HttpResponse::from(err),
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        Err(err) => HttpResponse::BadRequest().json(err)
 | 
					        Err(err) => HttpResponse::from(err)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub async fn add(post: web::Json<RequestSchedule>) -> impl Responder {
 | 
					pub async fn add(post: web::Json<RequestSchedule>) -> impl Responder {
 | 
				
			||||||
| 
						 | 
					@ -49,10 +40,25 @@ pub async fn add(post: web::Json<RequestSchedule>) -> impl Responder {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    match new_schedule {
 | 
					    match new_schedule {
 | 
				
			||||||
        Ok(ok) => HttpResponse::Created().json(ok),
 | 
					        Ok(ok) => HttpResponse::Created().json(ok),
 | 
				
			||||||
        Err(err) => HttpResponse::InternalServerError().json(err),
 | 
					        Err(err) => HttpResponse::from(err),
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub async fn delete() -> impl Responder {
 | 
					#[delete("/api/v1/schedules/{schedule_id}")]
 | 
				
			||||||
    "hello from delete schedule"
 | 
					pub async fn delete(web::Path((schedule_uid,)): web::Path<(String,)>) -> impl Responder {
 | 
				
			||||||
 | 
					    let emgauwa_uid = EmgauwaUid::try_from(schedule_uid.as_str()).or(Err(HandlerError::BadUid));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    match emgauwa_uid {
 | 
				
			||||||
 | 
					        Ok(uid) => match uid {
 | 
				
			||||||
 | 
					            EmgauwaUid::Off => HttpResponse::from(HandlerError::ProtectedSchedule),
 | 
				
			||||||
 | 
					            EmgauwaUid::On => HttpResponse::from(HandlerError::ProtectedSchedule),
 | 
				
			||||||
 | 
					            EmgauwaUid::Any(_) => {
 | 
				
			||||||
 | 
					                match db::delete_schedule_by_uid(uid) {
 | 
				
			||||||
 | 
					                    Ok(_) => HttpResponse::Ok().json("schedule got deleted"),
 | 
				
			||||||
 | 
					                    Err(err) => HttpResponse::from(err)
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        Err(err) => HttpResponse::from(err)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,6 +27,7 @@ async fn main() -> std::io::Result<()> {
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
            .wrap(middleware::Logger::default())
 | 
					            .wrap(middleware::Logger::default())
 | 
				
			||||||
            .wrap(middleware::NormalizePath::new(TrailingSlash::Trim))
 | 
					            .wrap(middleware::NormalizePath::new(TrailingSlash::Trim))
 | 
				
			||||||
 | 
					            .app_data(web::JsonConfig::default().error_handler(handlers::json_error_handler))
 | 
				
			||||||
            .route(
 | 
					            .route(
 | 
				
			||||||
                "/api/v1/schedules",
 | 
					                "/api/v1/schedules",
 | 
				
			||||||
                web::get().to(handlers::v1::schedules::index),
 | 
					                web::get().to(handlers::v1::schedules::index),
 | 
				
			||||||
| 
						 | 
					@ -36,10 +37,7 @@ async fn main() -> std::io::Result<()> {
 | 
				
			||||||
                web::post().to(handlers::v1::schedules::add),
 | 
					                web::post().to(handlers::v1::schedules::add),
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
            .service(handlers::v1::schedules::show)
 | 
					            .service(handlers::v1::schedules::show)
 | 
				
			||||||
            .route(
 | 
					            .service(handlers::v1::schedules::delete)
 | 
				
			||||||
                "/api/v1/schedules/{id}",
 | 
					 | 
				
			||||||
                web::delete().to(handlers::v1::schedules::delete),
 | 
					 | 
				
			||||||
            )
 | 
					 | 
				
			||||||
    })
 | 
					    })
 | 
				
			||||||
    .bind("127.0.0.1:5000")?
 | 
					    .bind("127.0.0.1:5000")?
 | 
				
			||||||
    .run()
 | 
					    .run()
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										54
									
								
								src/types.rs
									
										
									
									
									
								
							
							
						
						
									
										54
									
								
								src/types.rs
									
										
									
									
									
								
							| 
						 | 
					@ -1,5 +1,7 @@
 | 
				
			||||||
 | 
					use std::convert::TryFrom;
 | 
				
			||||||
use std::fmt::{Debug, Formatter};
 | 
					use std::fmt::{Debug, Formatter};
 | 
				
			||||||
use std::io::Write;
 | 
					use std::io::Write;
 | 
				
			||||||
 | 
					use std::str::FromStr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use diesel::backend::Backend;
 | 
					use diesel::backend::Backend;
 | 
				
			||||||
use diesel::deserialize::FromSql;
 | 
					use diesel::deserialize::FromSql;
 | 
				
			||||||
| 
						 | 
					@ -13,11 +15,20 @@ use uuid::Uuid;
 | 
				
			||||||
#[derive(AsExpression, FromSqlRow, PartialEq, Clone)]
 | 
					#[derive(AsExpression, FromSqlRow, PartialEq, Clone)]
 | 
				
			||||||
#[sql_type = "Binary"]
 | 
					#[sql_type = "Binary"]
 | 
				
			||||||
pub enum EmgauwaUid {
 | 
					pub enum EmgauwaUid {
 | 
				
			||||||
    On,
 | 
					 | 
				
			||||||
    Off,
 | 
					    Off,
 | 
				
			||||||
 | 
					    On,
 | 
				
			||||||
    Any(Uuid),
 | 
					    Any(Uuid),
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl EmgauwaUid {
 | 
				
			||||||
 | 
					    const OFF_STR: &'static str = "off";
 | 
				
			||||||
 | 
					    const ON_STR: &'static str = "on";
 | 
				
			||||||
 | 
					    const OFF_U8: u8 = 0;
 | 
				
			||||||
 | 
					    const ON_U8: u8 = 1;
 | 
				
			||||||
 | 
					    const OFF_U128: u128 = 0;
 | 
				
			||||||
 | 
					    const ON_U128: u128 = 1;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl Default for EmgauwaUid {
 | 
					impl Default for EmgauwaUid {
 | 
				
			||||||
    fn default() -> Self {
 | 
					    fn default() -> Self {
 | 
				
			||||||
        EmgauwaUid::Any(Uuid::new_v4())
 | 
					        EmgauwaUid::Any(Uuid::new_v4())
 | 
				
			||||||
| 
						 | 
					@ -27,8 +38,8 @@ impl Default for EmgauwaUid {
 | 
				
			||||||
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 {
 | 
				
			||||||
            EmgauwaUid::On => "on".fmt(f),
 | 
					            EmgauwaUid::Off => EmgauwaUid::OFF_STR.fmt(f),
 | 
				
			||||||
            EmgauwaUid::Off => "off".fmt(f),
 | 
					            EmgauwaUid::On => EmgauwaUid::ON_STR.fmt(f),
 | 
				
			||||||
            EmgauwaUid::Any(value) => value.fmt(f),
 | 
					            EmgauwaUid::Any(value) => value.fmt(f),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -37,9 +48,9 @@ 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 {
 | 
				
			||||||
            EmgauwaUid::On => out.write_all(&[1])?,
 | 
					            EmgauwaUid::Off => out.write_all(&[EmgauwaUid::OFF_U8])?,
 | 
				
			||||||
            EmgauwaUid::Off => out.write_all(&[0])?,
 | 
					            EmgauwaUid::On => out.write_all(&[EmgauwaUid::ON_U8])?,
 | 
				
			||||||
            EmgauwaUid::Any(_) => out.write_all(Uuid::from(self).as_bytes())?,
 | 
					            EmgauwaUid::Any(value) => out.write_all(value.as_bytes())?,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        Ok(IsNull::No)
 | 
					        Ok(IsNull::No)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -50,8 +61,8 @@ impl FromSql<Binary, Sqlite> for EmgauwaUid {
 | 
				
			||||||
        match bytes {
 | 
					        match bytes {
 | 
				
			||||||
            None => Ok(EmgauwaUid::default()),
 | 
					            None => Ok(EmgauwaUid::default()),
 | 
				
			||||||
            Some(value) => match value.read_blob() {
 | 
					            Some(value) => match value.read_blob() {
 | 
				
			||||||
                [0] => Ok(EmgauwaUid::Off),
 | 
					                [EmgauwaUid::OFF_U8] => Ok(EmgauwaUid::Off),
 | 
				
			||||||
                [1] => Ok(EmgauwaUid::On),
 | 
					                [EmgauwaUid::ON_U8] => Ok(EmgauwaUid::On),
 | 
				
			||||||
                value_bytes => Ok(EmgauwaUid::Any(Uuid::from_slice(value_bytes).unwrap())),
 | 
					                value_bytes => Ok(EmgauwaUid::Any(Uuid::from_slice(value_bytes).unwrap())),
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
| 
						 | 
					@ -70,18 +81,33 @@ impl Serialize for EmgauwaUid {
 | 
				
			||||||
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() {
 | 
				
			||||||
            0 => EmgauwaUid::Off,
 | 
					            EmgauwaUid::OFF_U128 => EmgauwaUid::Off,
 | 
				
			||||||
            1 => EmgauwaUid::On,
 | 
					            EmgauwaUid::ON_U128 => EmgauwaUid::On,
 | 
				
			||||||
            _ => EmgauwaUid::Any(uid),
 | 
					            _ => EmgauwaUid::Any(uid),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					impl TryFrom<&str> for EmgauwaUid {
 | 
				
			||||||
 | 
					    type Error = uuid::Error;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fn try_from(value: &str) -> Result<Self, Self::Error> {
 | 
				
			||||||
 | 
					        match value {
 | 
				
			||||||
 | 
					            EmgauwaUid::OFF_STR => Ok(EmgauwaUid::Off),
 | 
				
			||||||
 | 
					            EmgauwaUid::ON_STR => Ok(EmgauwaUid::On),
 | 
				
			||||||
 | 
					            any => match Uuid::from_str(any) {
 | 
				
			||||||
 | 
					                Ok(uuid) => Ok(EmgauwaUid::Any(uuid)),
 | 
				
			||||||
 | 
					                Err(err) => Err(err),
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl From<&EmgauwaUid> for Uuid {
 | 
					impl From<&EmgauwaUid> for Uuid {
 | 
				
			||||||
    fn from(emgauwa_uid: &EmgauwaUid) -> Uuid {
 | 
					    fn from(emgauwa_uid: &EmgauwaUid) -> Uuid {
 | 
				
			||||||
        match emgauwa_uid {
 | 
					        match emgauwa_uid {
 | 
				
			||||||
            EmgauwaUid::On => uuid::Uuid::from_u128(1),
 | 
					            EmgauwaUid::Off => uuid::Uuid::from_u128(EmgauwaUid::OFF_U128),
 | 
				
			||||||
            EmgauwaUid::Off => uuid::Uuid::from_u128(0),
 | 
					            EmgauwaUid::On => uuid::Uuid::from_u128(EmgauwaUid::ON_U128),
 | 
				
			||||||
            EmgauwaUid::Any(value) => *value,
 | 
					            EmgauwaUid::Any(value) => *value,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -90,8 +116,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::Off => String::from("off"),
 | 
					            EmgauwaUid::Off => String::from(EmgauwaUid::OFF_STR),
 | 
				
			||||||
            EmgauwaUid::On => String::from("on"),
 | 
					            EmgauwaUid::On => String::from(EmgauwaUid::ON_STR),
 | 
				
			||||||
            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