Skip to content

Commit 67c3d9e

Browse files
committed
feat: Start Logger implementation
1 parent 6212459 commit 67c3d9e

File tree

6 files changed

+58
-13
lines changed

6 files changed

+58
-13
lines changed

src/database/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
// sea_orm example: https://github.com/SeaQL/sea-orm/blob/master/examples/axum_example/
22
pub mod category;
3+
pub mod operation;

src/database/operation.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
use chrono::{DateTime, Utc};
2+
use serde::{Deserialize, Serialize};
3+
4+
use crate::extractors::user::User;
5+
use crate::routes::category::CategoryForm;
16

27
/// Type of operation applied to the database.
38
#[derive(Clone, Debug, Serialize, Deserialize)]

src/extractors/user.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@ use axum::{
33
http::{StatusCode, request::Parts},
44
};
55
use derive_more::Display;
6+
use serde::{Deserialize, Serialize};
67

7-
#[derive(Clone, Debug, Display)]
88
/// A logged-in user, as expressed by the Remote-User header.
99
///
1010
/// Cannot be produced outside of header extraction.
11+
#[derive(Clone, Debug, Display, Deserialize, Serialize)]
12+
#[serde(transparent)]
1113
pub struct User(String);
1214

1315
impl<S> OptionalFromRequestParts<S> for User

src/routes/category.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,13 @@ use askama::Template;
22
use askama_web::WebTemplate;
33
use axum::Form;
44
use axum::extract::State;
5-
// use sea_orm::entity::*;
6-
use serde::Deserialize;
5+
use serde::{Deserialize, Serialize};
76

87
use crate::database::{category, category::CategoryOperator};
98
use crate::extractors::user::User;
109
use crate::state::{AppState, AppStateContext, error::*};
1110

12-
#[derive(Clone, Debug, Deserialize)]
11+
#[derive(Clone, Debug, Deserialize, Serialize)]
1312
pub struct CategoryForm {
1413
pub name: String,
1514
pub path: String,

src/state/logger.rs

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,46 @@
11
use camino::Utf8PathBuf;
22
use snafu::prelude::*;
33
use tokio::fs::{File, OpenOptions};
4+
use tokio::io::AsyncWriteExt;
45
use tokio::sync::RwLock;
56

67
use std::sync::Arc;
78

9+
use crate::database::operation::Operation;
10+
811
#[derive(Debug, Snafu)]
912
#[snafu(visibility(pub))]
1013
pub enum LoggerError {
1114
/// Failed to create the log file, which did not previously exist.
1215
#[snafu(display("Failed to create the operations log {path}"))]
13-
Create { path: Utf8PathBuf, source: std::io::Error },
16+
Create {
17+
path: Utf8PathBuf,
18+
source: std::io::Error,
19+
},
1420
/// Failed to read the log file
1521
#[snafu(display("Failed to read the operations log {path}"))]
16-
Read { path: Utf8PathBuf, source: std::io::Error } ,
22+
Read {
23+
path: Utf8PathBuf,
24+
source: std::io::Error,
25+
},
1726
/// Failed to append a line to the log file
1827
#[snafu(display("Failed to append to the operations log {path}"))]
19-
Append { path: Utf8PathBuf, source: std::io::Error },
28+
Append {
29+
path: Utf8PathBuf,
30+
source: std::io::Error,
31+
},
2032
#[snafu(display("Failed to parse JSON from operations log {path}"))]
21-
Parse { path: Utf8PathBuf, source: serde_json::Error },
33+
Parse {
34+
path: Utf8PathBuf,
35+
source: serde_json::Error,
36+
},
2237
}
2338

2439
#[derive(Clone, Debug)]
2540
pub struct Logger {
2641
/// Log file storage
2742
pub path: Utf8PathBuf,
28-
43+
2944
/// Handle to the log file in append-mode
3045
pub handle: Arc<RwLock<File>>,
3146
}
@@ -34,16 +49,37 @@ impl Logger {
3449
pub async fn new(path: Utf8PathBuf) -> Result<Self, LoggerError> {
3550
let mut handle = OpenOptions::new();
3651
let mut handle = handle.append(true).read(true);
37-
let handle = if !tokio::fs::try_exists(&path).await.context(ReadSnafu { path: path.to_path_buf() })? {
52+
let handle = if !tokio::fs::try_exists(&path).await.context(ReadSnafu {
53+
path: path.to_path_buf(),
54+
})? {
3855
handle = handle.create(true);
39-
handle.open(&path).await.context(CreateSnafu { path: path.to_path_buf() })?
56+
handle.open(&path).await.context(CreateSnafu {
57+
path: path.to_path_buf(),
58+
})?
4059
} else {
41-
handle.open(&path).await.context(ReadSnafu { path: path.to_path_buf() })?
60+
handle.open(&path).await.context(ReadSnafu {
61+
path: path.to_path_buf(),
62+
})?
4263
};
4364

4465
Ok(Self {
4566
path: path.to_path_buf(),
4667
handle: Arc::new(RwLock::new(handle)),
4768
})
4869
}
70+
71+
pub async fn write(&self, operation: Operation) -> Result<(), LoggerError> {
72+
// This should never fail
73+
let operation = serde_json::to_string(&operation).unwrap();
74+
75+
let mut handle = self.handle.write().await;
76+
handle
77+
.write(operation.as_bytes())
78+
.await
79+
.context(AppendSnafu {
80+
path: self.path.to_path_buf(),
81+
})?;
82+
83+
Ok(())
84+
}
4985
}

src/state/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,9 @@ impl AppState {
7474
.context(SqliteSnafu)?;
7575
Migrator::up(&database, None).await.unwrap();
7676

77-
let logger = Logger::new(config.log_path.clone()).await.context(LoggerSnafu)?;
77+
let logger = Logger::new(config.log_path.clone())
78+
.await
79+
.context(LoggerSnafu)?;
7880

7981
Ok(Self {
8082
config,

0 commit comments

Comments
 (0)