Advertisement
Guest User

RUSTSUR

a guest
Jan 2nd, 2019
114
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 3.37 KB | None | 0 0
  1. #[macro_use]
  2. extern crate diesel;
  3.  
  4. use diesel::prelude::*;
  5. use diesel::sqlite::SqliteConnection;
  6. use dotenv::dotenv;
  7. use std::env;
  8.  
  9. pub mod schema;
  10. pub mod models;
  11.  
  12. use self::models::{Page, NewPage};
  13. use warp::{Reply, Filter, http::{StatusCode}};
  14.  
  15. type Conn = r2d2::Pool<diesel::r2d2::ConnectionManager<SqliteConnection>>;
  16.  
  17. fn establish_connection() -> r2d2::Pool<diesel::r2d2::ConnectionManager<SqliteConnection>> {
  18.     dotenv().ok();
  19.  
  20.     let database_url = env::var("DATABASE_URL")
  21.         .expect("DATABASE_URL must be set");
  22.     let manager = diesel::r2d2::ConnectionManager::new(database_url);
  23.     r2d2::Pool::builder()
  24.         .max_size(4)
  25.         .build(manager)
  26.         .expect("Failed to create connection pool!")
  27. }
  28.  
  29. fn main() {
  30.     let connection = establish_connection();
  31.     let connection = warp::any().map(move || connection.clone());
  32.  
  33.     let page_name = warp::path::param2::<String>();
  34.  
  35.     let load_page = warp::get2().and(page_name).and(connection.clone()).and_then(load_page);
  36.     let upload_page = warp::put2().and(page_name).and(connection).and(warp::body::json()).and_then(upload_page);
  37.     let api = warp::path("pages").and(load_page.or(upload_page)).recover(error_handler);
  38.  
  39.     let routes = warp::path("api").and(api);
  40.  
  41.     warp::serve(routes)
  42.         .run(([127, 0, 0, 1], 3030));
  43. }
  44.  
  45. #[derive(Debug)]
  46. enum Error {
  47.     DatabaseError(diesel::result::Error),
  48.     NotFound(String)
  49. }
  50.  
  51. impl std::fmt::Display for Error {
  52.     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
  53.         match self {
  54.             Error::DatabaseError(err) => write!(f, "Database error: {}", err),
  55.             Error::NotFound(thing) => write!(f, "{} not found", thing)
  56.         }
  57.     }
  58. }
  59.  
  60. impl std::error::Error for Error {}
  61.  
  62. fn error_handler(r: warp::Rejection) -> Result<impl Reply, warp::Rejection> {
  63.     if let Some(err) = r.find_cause::<Error>() {
  64.         let code = match err {
  65.             Error::DatabaseError(_) => StatusCode::INTERNAL_SERVER_ERROR,
  66.             Error::NotFound(_) => StatusCode::NOT_FOUND
  67.         };
  68.         Ok(warp::reply::with_status(err.to_string(), code))
  69.     } else {
  70.         Err(r)
  71.     }
  72. }
  73.  
  74. fn load_page(name: String, conn: Conn) -> Result<impl Reply, warp::Rejection> {
  75.     match get_page(&conn.get().unwrap(), &name) {
  76.         Ok(page) => Ok(warp::reply::json(&page)),
  77.         Err(err) => Err(match err {
  78.             diesel::result::Error::NotFound => warp::reject::custom(Error::NotFound(name)), // https://github.com/seanmonstar/warp/issues/77
  79.             _ => warp::reject::custom(Error::DatabaseError(err))
  80.         })
  81.     }
  82. }
  83.  
  84. fn upload_page(name: String, conn: Conn, body: String) -> Result<impl Reply, warp::Rejection> {
  85.     match set_page(&conn.get().unwrap(), &name, &body) {
  86.         Ok(_) => Ok(warp::reply()),
  87.         Err(err) => Err(warp::reject::custom(Error::DatabaseError(err)))
  88.     }
  89. }
  90.  
  91. fn get_page(conn: &SqliteConnection, name_: &str) -> Result<Page, diesel::result::Error> {
  92.     use crate::schema::pages::dsl::*;
  93.     pages.filter(name.eq(name_))
  94.         .get_result(conn)
  95. }
  96.  
  97. fn set_page<'a>(conn: &SqliteConnection, title: &'a str, body: &'a str) -> Result<(), diesel::result::Error> {
  98.    let new_page = NewPage {
  99.        name: title,
  100.        body: body
  101.    };
  102.  
  103.    diesel::replace_into(schema::pages::table)
  104.        .values(&new_page)
  105.        .execute(conn)
  106.        .map(|_| ())
  107. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement