mod db; mod error; mod exn_tracing; use std::process::exit; use derive_more::Display; use exn::{Result, ResultExt, bail}; use serde::{Deserialize, Serialize}; use sqlx::prelude::FromRow; use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt}; use uuid::Uuid; use crate::exn_tracing::{ExnLayer, exn_to_json_value}; #[derive(Debug, Clone, FromRow)] pub struct FooBar { id: Uuid, foo: String, bar: String, } pub struct FooBarRequest { foo: String, bar: String, } #[derive(Debug, Display, Serialize, Deserialize)] #[display("the program died")] pub struct MainError; impl std::error::Error for MainError {} #[tokio::main] async fn main() -> Result<(), MainError> { let err = || MainError; init_tracing(); //files::write().or_raise(err)?; let _ = match files::write().or_raise(err) { Ok(_) => (), Err(e) => { error_exn!(e); exit(1); //bail!(MainError) } }; let pool = db::create_pool("foobar.db").await.or_raise(err)?; let foobar = db::insert_foobar( &pool, FooBarRequest { foo: "foo".to_string(), bar: "bar".to_string(), }, ) .await .or_raise(err)?; println!("FOOBAR! {:?}", foobar); Ok(()) } mod files { use std::{fs::File, io::Write}; use derive_more::Display; use exn::{Result, ResultExt}; #[derive(Debug, Display)] pub enum FileError { #[display("failed to create file: {file}")] Create { file: String }, #[display("failed to write to file: {text}")] Write { text: String }, } impl std::error::Error for FileError {} pub fn write() -> Result<(), FileError> { // mkdir res; chown root:root // will get the error to test output let path = "res/foo.txt"; let mut file = File::create(path).or_raise(|| FileError::Create { file: path.to_string(), })?; let text = "Hello, world!"; file.write_all(text.as_bytes()) .or_raise(|| FileError::Write { text: text.to_string(), })?; Ok(()) } } fn init_tracing() { tracing_subscriber::registry().with(ExnLayer).init(); //tracing_subscriber::fmt().pretty().json().init(); }