main.rs

  1mod api;
  2mod auth;
  3mod db;
  4mod env;
  5mod rpc;
  6
  7use ::rpc::Peer;
  8use anyhow::Result;
  9use async_trait::async_trait;
 10use db::{Db, PostgresDb};
 11use hyper::{
 12    server::conn::AddrStream,
 13    service::{make_service_fn, service_fn},
 14    Body, Request, Response, Server,
 15};
 16use serde::Deserialize;
 17use std::{convert::Infallible, net::TcpListener, sync::Arc};
 18
 19// type Request = tide::Request<Arc<AppState>>;
 20
 21#[derive(Default, Deserialize)]
 22pub struct Config {
 23    pub http_port: u16,
 24    pub database_url: String,
 25    pub api_token: String,
 26}
 27
 28pub struct AppState {
 29    db: Arc<dyn Db>,
 30    config: Config,
 31}
 32
 33impl AppState {
 34    async fn new(config: Config) -> Result<Arc<Self>> {
 35        let db = PostgresDb::new(&config.database_url, 5).await?;
 36
 37        let this = Self {
 38            db: Arc::new(db),
 39            config,
 40        };
 41        Ok(Arc::new(this))
 42    }
 43}
 44
 45// #[async_trait]
 46// trait RequestExt {
 47//     fn db(&self) -> &Arc<dyn Db>;
 48// }
 49
 50// #[async_trait]
 51// impl RequestExt for Request {
 52//     fn db(&self) -> &Arc<dyn Db> {
 53//         &self.state().db
 54//     }
 55// }
 56
 57#[tokio::main]
 58async fn main() -> Result<()> {
 59    if std::env::var("LOG_JSON").is_ok() {
 60        json_env_logger::init();
 61    } else {
 62        env_logger::init();
 63    }
 64
 65    if let Err(error) = env::load_dotenv() {
 66        log::error!(
 67            "error loading .env.toml (this is expected in production): {}",
 68            error
 69        );
 70    }
 71
 72    let config = envy::from_env::<Config>().expect("error loading config");
 73    let state = AppState::new(config).await?;
 74    let rpc = Peer::new();
 75    run_server(
 76        state.clone(),
 77        rpc,
 78        TcpListener::bind(&format!("0.0.0.0:{}", state.config.http_port))
 79            .expect("failed to bind TCP listener"),
 80    )
 81    .await?;
 82    Ok(())
 83}
 84
 85pub async fn run_server(state: Arc<AppState>, rpc: Arc<Peer>, listener: TcpListener) -> Result<()> {
 86    let make_service = make_service_fn(|_: &AddrStream| async move {
 87        Ok::<_, Infallible>(service_fn(|_: Request<Body>| async move {
 88            Response::new(Body::from(format!("hello"))
 89        }))
 90    });
 91
 92    Server::from_tcp(listener)
 93        .expect("could not create server")
 94        .serve(make_service);
 95
 96    // let mut app = tide::with_state(state.clone());
 97    // rpc::add_routes(&mut app, &rpc);
 98
 99    // let mut web = tide::with_state(state.clone());
100    // web.with(CompressMiddleware::new());
101    // api::add_routes(&mut web);
102
103    // app.at("/").nest(web);
104
105    // app.listen(listener).await?;
106
107    Ok(())
108}