1
0
mirror of https://github.com/actix/examples synced 2024-11-27 16:02:57 +01:00
This commit is contained in:
Rob Ede 2022-07-09 21:05:06 +01:00
parent e97bc83f59
commit 4b801ba222
No known key found for this signature in database
GPG Key ID: 97C636207D3EF933
10 changed files with 55 additions and 42 deletions

1
Cargo.lock generated
View File

@ -5766,6 +5766,7 @@ dependencies = [
"actix-files", "actix-files",
"actix-session 0.5.0", "actix-session 0.5.0",
"actix-web", "actix-web",
"actix-web-lab",
"dotenv", "dotenv",
"env_logger", "env_logger",
"log", "log",

View File

@ -13,7 +13,7 @@ use actix_web::{
}; };
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug, PartialEq)] #[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
pub struct IndexResponse { pub struct IndexResponse {
user_id: Option<String>, user_id: Option<String>,
counter: i32, counter: i32,

View File

@ -43,7 +43,9 @@ async fn welcome(req: HttpRequest, session: Session) -> Result<HttpResponse> {
async fn default_handler(req_method: Method) -> Result<impl Responder> { async fn default_handler(req_method: Method) -> Result<impl Responder> {
match req_method { match req_method {
Method::GET => { Method::GET => {
let file = NamedFile::open("static/404.html")?.set_status_code(StatusCode::NOT_FOUND); let file = NamedFile::open("static/404.html")?
.customize()
.with_status(StatusCode::NOT_FOUND);
Ok(Either::Left(file)) Ok(Either::Left(file))
} }
_ => Ok(Either::Right(HttpResponse::MethodNotAllowed().finish())), _ => Ok(Either::Right(HttpResponse::MethodNotAllowed().finish())),

View File

@ -4,9 +4,10 @@ version = "1.0.0"
edition = "2021" edition = "2021"
[dependencies] [dependencies]
actix-web = "4"
actix-files = "0.6" actix-files = "0.6"
actix-session = "0.5" actix-session = "0.5"
actix-web = "4"
actix-web-lab = "0.16"
dotenv = "0.15" dotenv = "0.15"
env_logger = "0.9" env_logger = "0.9"

View File

@ -1,8 +1,9 @@
use actix_files::NamedFile; use actix_files::NamedFile;
use actix_session::Session; use actix_session::Session;
use actix_web::{ use actix_web::{
dev, error, http, middleware::ErrorHandlerResponse, web, Error, HttpResponse, Result, dev, error, middleware::ErrorHandlerResponse, web, Error, HttpResponse, Responder, Result,
}; };
use actix_web_lab::web::Redirect;
use serde::Deserialize; use serde::Deserialize;
use sqlx::SqlitePool; use sqlx::SqlitePool;
use tera::{Context, Tera}; use tera::{Context, Tera};
@ -24,8 +25,7 @@ pub async fn index(
let mut context = Context::new(); let mut context = Context::new();
context.insert("tasks", &tasks); context.insert("tasks", &tasks);
//Session is set during operations on other endpoints // Session is set during operations on other endpoints that can redirect to index
//that can redirect to index
if let Some(flash) = session::get_flash(&session)? { if let Some(flash) = session::get_flash(&session)? {
context.insert("msg", &(flash.kind, flash.message)); context.insert("msg", &(flash.kind, flash.message));
session::clear_flash(&session); session::clear_flash(&session);
@ -38,7 +38,7 @@ pub async fn index(
Ok(HttpResponse::Ok().body(rendered)) Ok(HttpResponse::Ok().body(rendered))
} }
#[derive(Deserialize)] #[derive(Debug, Deserialize)]
pub struct CreateForm { pub struct CreateForm {
description: String, description: String,
} }
@ -47,25 +47,27 @@ pub async fn create(
params: web::Form<CreateForm>, params: web::Form<CreateForm>,
pool: web::Data<SqlitePool>, pool: web::Data<SqlitePool>,
session: Session, session: Session,
) -> Result<HttpResponse, Error> { ) -> Result<impl Responder, Error> {
if params.description.is_empty() { if params.description.is_empty() {
session::set_flash(&session, FlashMessage::error("Description cannot be empty"))?; session::set_flash(&session, FlashMessage::error("Description cannot be empty"))?;
Ok(redirect_to("/")) Ok(Redirect::to("/"))
} else { } else {
db::create_task(params.into_inner().description, &pool) db::create_task(params.into_inner().description, &pool)
.await .await
.map_err(error::ErrorInternalServerError)?; .map_err(error::ErrorInternalServerError)?;
session::set_flash(&session, FlashMessage::success("Task successfully added"))?; session::set_flash(&session, FlashMessage::success("Task successfully added"))?;
Ok(redirect_to("/"))
Ok(Redirect::to("/"))
} }
} }
#[derive(Deserialize)] #[derive(Debug, Deserialize)]
pub struct UpdateParams { pub struct UpdateParams {
id: i32, id: i32,
} }
#[derive(Deserialize)] #[derive(Debug, Deserialize)]
pub struct UpdateForm { pub struct UpdateForm {
_method: String, _method: String,
} }
@ -75,65 +77,71 @@ pub async fn update(
params: web::Path<UpdateParams>, params: web::Path<UpdateParams>,
form: web::Form<UpdateForm>, form: web::Form<UpdateForm>,
session: Session, session: Session,
) -> Result<HttpResponse, Error> { ) -> Result<impl Responder, Error> {
match form._method.as_ref() { Ok(Redirect::to(match form._method.as_ref() {
"put" => toggle(db, params).await, "put" => toggle(db, params).await?,
"delete" => delete(db, params, session).await, "delete" => delete(db, params, session).await?,
unsupported_method => { unsupported_method => {
let msg = format!("Unsupported HTTP method: {unsupported_method}"); let msg = format!("Unsupported HTTP method: {unsupported_method}");
Err(error::ErrorBadRequest(msg)) return Err(error::ErrorBadRequest(msg));
} }
} }))
} }
async fn toggle( async fn toggle(
pool: web::Data<SqlitePool>, pool: web::Data<SqlitePool>,
params: web::Path<UpdateParams>, params: web::Path<UpdateParams>,
) -> Result<HttpResponse, Error> { ) -> Result<&'static str, Error> {
db::toggle_task(params.id, &pool) db::toggle_task(params.id, &pool)
.await .await
.map_err(error::ErrorInternalServerError)?; .map_err(error::ErrorInternalServerError)?;
Ok(redirect_to("/"))
Ok("/")
} }
async fn delete( async fn delete(
pool: web::Data<SqlitePool>, pool: web::Data<SqlitePool>,
params: web::Path<UpdateParams>, params: web::Path<UpdateParams>,
session: Session, session: Session,
) -> Result<HttpResponse, Error> { ) -> Result<&'static str, Error> {
db::delete_task(params.id, &pool) db::delete_task(params.id, &pool)
.await .await
.map_err(error::ErrorInternalServerError)?; .map_err(error::ErrorInternalServerError)?;
session::set_flash(&session, FlashMessage::success("Task was deleted."))?;
Ok(redirect_to("/"))
}
fn redirect_to(location: &str) -> HttpResponse { session::set_flash(&session, FlashMessage::success("Task was deleted."))?;
HttpResponse::Found()
.append_header((http::header::LOCATION, location)) Ok("/")
.finish()
} }
pub fn bad_request<B>(res: dev::ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> { pub fn bad_request<B>(res: dev::ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
let new_resp = NamedFile::open("static/errors/400.html")? let new_resp = NamedFile::open("static/errors/400.html")?
.set_status_code(res.status()) .customize()
.into_response(res.request()) .with_status(res.status())
.respond_to(res.request())
.map_into_boxed_body()
.map_into_right_body(); .map_into_right_body();
Ok(ErrorHandlerResponse::Response(res.into_response(new_resp))) Ok(ErrorHandlerResponse::Response(res.into_response(new_resp)))
} }
pub fn not_found<B>(res: dev::ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> { pub fn not_found<B>(res: dev::ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
let new_resp = NamedFile::open("static/errors/404.html")? let new_resp = NamedFile::open("static/errors/404.html")?
.set_status_code(res.status()) .customize()
.into_response(res.request()) .with_status(res.status())
.respond_to(res.request())
.map_into_boxed_body()
.map_into_right_body(); .map_into_right_body();
Ok(ErrorHandlerResponse::Response(res.into_response(new_resp))) Ok(ErrorHandlerResponse::Response(res.into_response(new_resp)))
} }
pub fn internal_server_error<B>(res: dev::ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> { pub fn internal_server_error<B>(res: dev::ServiceResponse<B>) -> Result<ErrorHandlerResponse<B>> {
let new_resp = NamedFile::open("static/errors/500.html")? let new_resp = NamedFile::open("static/errors/500.html")?
.set_status_code(res.status()) .customize()
.into_response(res.request()) .with_status(res.status())
.respond_to(res.request())
.map_into_boxed_body()
.map_into_right_body(); .map_into_right_body();
Ok(ErrorHandlerResponse::Response(res.into_response(new_resp))) Ok(ErrorHandlerResponse::Response(res.into_response(new_resp)))
} }

View File

@ -1,6 +1,6 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize)] #[derive(Clone, Debug, PartialEq, Eq, Deserialize, Serialize)]
pub struct User { pub struct User {
pub first_name: String, pub first_name: String,
pub last_name: String, pub last_name: String,

View File

@ -62,13 +62,14 @@ async fn rpc_select(
if params.len() != 1 || !params[0].is_u64() { if params.len() != 1 || !params[0].is_u64() {
return Err(convention::ErrorData::std(-32602)); return Err(convention::ErrorData::std(-32602));
} }
match app_state
let fut = app_state
.network .network
.read() .read()
.unwrap() .unwrap()
.wait(params[0].as_u64().unwrap()) .wait(params[0].as_u64().unwrap());
.await
{ match fut.await {
Ok(ok) => Ok(Value::from(ok)), Ok(ok) => Ok(Value::from(ok)),
Err(e) => Err(convention::ErrorData::new(500, &format!("{e:?}")[..])), Err(e) => Err(convention::ErrorData::new(500, &format!("{e:?}")[..])),
} }

View File

@ -2,7 +2,7 @@ use actix_protobuf::{ProtoBuf, ProtoBufResponseBuilder as _};
use actix_web::{middleware, web, App, HttpResponse, HttpServer, Result}; use actix_web::{middleware, web, App, HttpResponse, HttpServer, Result};
use prost_derive::Message; use prost_derive::Message;
#[derive(Clone, PartialEq, Message)] #[derive(Clone, PartialEq, Eq, Message)]
pub struct MyObj { pub struct MyObj {
#[prost(int32, tag = "1")] #[prost(int32, tag = "1")]
pub number: i32, pub number: i32,

View File

@ -82,7 +82,7 @@ impl ChatServer {
for id in sessions { for id in sessions {
if *id != skip_id { if *id != skip_id {
if let Some(addr) = self.sessions.get(id) { if let Some(addr) = self.sessions.get(id) {
let _ = addr.do_send(session::Message(message.to_owned())); addr.do_send(session::Message(message.to_owned()));
} }
} }
} }

View File

@ -97,7 +97,7 @@ impl ChatServer {
for id in sessions { for id in sessions {
if *id != skip_id { if *id != skip_id {
if let Some(addr) = self.sessions.get(id) { if let Some(addr) = self.sessions.get(id) {
let _ = addr.do_send(Message(message.to_owned())); addr.do_send(Message(message.to_owned()));
} }
} }
} }