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}