main.rs 4.42 KB
#[macro_use]
extern crate diesel;

mod error;
mod models;
mod routes;
mod schema;

use std::io::Write;
use crate::routes::markdown::get_markdowns;
use crate::routes::other::*;
use crate::routes::user::*;

use actix_web::{guard, web, App, HttpResponse, HttpServer};
use diesel::r2d2::{self, ConnectionManager};
use diesel::SqliteConnection;
use diffy::create_patch;
use flate2::Compression;
use flate2::write::{DeflateEncoder, DeflateDecoder};
use listenfd::ListenFd;

pub(crate) type Pool = r2d2::Pool<ConnectionManager<SqliteConnection>>;

const ORIGINAL :&str = r"This is a long Multiline text to
see if we can create a small patch set from
a longer text.

This paragraph will be kept without modification. The reason I
try this is to see if the diff becomes smaller than storing a
compressed new version of this text...

So this whole paragraph is obsolete. It will be removed in the
modified text.

There is probably a threshold up to what amount of text is needed
to make the diff smaller.
";

const MODIFIED :&str = r"This is a long multiline text to
see if we can create a small patch set from
a longer text.

This paragraph will be kept without modification. The reason I
try this is to see if the diff becomes smaller than storing a
compressed new version of this text...

This is the replacement for the previous paragraph.

There is probably a threshold up to what amount of text is needed
to make the diff smaller.
";

#[actix_rt::main]
async fn main() -> std::io::Result<()> {
    /* just some playing with diffy */
    let patch = format!("{}", create_patch(ORIGINAL, MODIFIED));
    println!("{} - {}", patch.len(), patch);

    let mut encoder = DeflateEncoder::new(Vec::new(), Compression::best());
    encoder.write_all(patch.as_bytes()).unwrap();
    let compressed = encoder.finish().unwrap();
    println!("{} - {:?}", compressed.len(), compressed);

    let mut decoder = DeflateDecoder::new(Vec::new());
    decoder.write_all(compressed.as_ref()).unwrap();
    let decompressed = decoder.finish().unwrap();
    let decompressed = match std::str::from_utf8(decompressed.as_ref()) {
        Ok(v) => v,
        Err(e) => panic!("Invalid UTF-8 sequence: {}", e),
    };
    println!("{} - {}", decompressed.len(), decompressed);
    /* ======= */

    let mut listenfd = ListenFd::from_env();

    dotenv::dotenv().ok();

    let database_url = std::env::var("DATABASE_URL").expect("NOT FOUND");
    let database_pool = Pool::builder()
        .build(ConnectionManager::new(database_url))
        .unwrap();

    let server = HttpServer::new(move || {
        App::new() . data(database_pool.clone())
                   . service(actix_files::Files::new("/static", "./static"))
                   . service( web::scope("/api/v0")
                            . service( web::resource("/markdowns")
                                     . route(web::get().to(get_markdowns))
                                     )
                            . service( web::resource("/users")
                                     . route(web::get().to(get_users))
                                     . route(web::put().to(create_user))
                                     )
                            . service( web::resource("/users/{id}")
                                     . route(web::delete().to(delete_user))
                                     . route(web::get().to(get_user))
                                     . route(web::put().to(update_user))
                                     )
                            )
                   . service( web::scope("")
                            . route("/", web::get().to(root))
                            . route("/index", web::get().to(root))
                            . route("/index.html", web::get().to(root))
                            . route("/favicon", web::get().to(favicon))
                            . route("/favicon.ico", web::get().to(favicon))
                            )
                   . default_service( web::resource("")
                            . route( web::get().to(p404) )
                            . route( web::route()
                                   . guard( guard::Not(guard::Get()) )
                                   . to(HttpResponse::MethodNotAllowed)
                                   )
                            )
    });

    let server = match listenfd.take_tcp_listener(0).unwrap() {
        Some(l) => server.listen(l)?,
        None => server.bind("localhost:8080")?,
    };

    server.run().await
}