fix: proper datetime serialization
This commit is contained in:
4
Cargo.lock
generated
4
Cargo.lock
generated
@@ -2138,6 +2138,7 @@ checksum = "ee6798b1838b6a0f69c007c133b8df5866302197e404e8b6ee8ed3e3a5e68dc6"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"base64",
|
"base64",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
"chrono",
|
||||||
"crc",
|
"crc",
|
||||||
"crossbeam-queue",
|
"crossbeam-queue",
|
||||||
"either",
|
"either",
|
||||||
@@ -2213,6 +2214,7 @@ dependencies = [
|
|||||||
"bitflags",
|
"bitflags",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
"chrono",
|
||||||
"crc",
|
"crc",
|
||||||
"digest",
|
"digest",
|
||||||
"dotenvy",
|
"dotenvy",
|
||||||
@@ -2254,6 +2256,7 @@ dependencies = [
|
|||||||
"base64",
|
"base64",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
|
"chrono",
|
||||||
"crc",
|
"crc",
|
||||||
"dotenvy",
|
"dotenvy",
|
||||||
"etcetera",
|
"etcetera",
|
||||||
@@ -2288,6 +2291,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "c2d12fe70b2c1b4401038055f90f151b78208de1f9f89a7dbfd41587a10c3eea"
|
checksum = "c2d12fe70b2c1b4401038055f90f151b78208de1f9f89a7dbfd41587a10c3eea"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"atoi",
|
"atoi",
|
||||||
|
"chrono",
|
||||||
"flume",
|
"flume",
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ edition = "2024"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
axum = "0.8"
|
axum = "0.8"
|
||||||
tokio = { version = "1", features = ["full"] }
|
tokio = { version = "1", features = ["full"] }
|
||||||
tower-http = { version = "0.6", features = ["compression-full", "fs"] }
|
tower-http = { version = "0.6", features = ["catch-panic", "compression-full", "fs"] }
|
||||||
hyper = { version = "1", features = ["full"] }
|
hyper = { version = "1", features = ["full"] }
|
||||||
serde = { version = "1", features = ["derive"] }
|
serde = { version = "1", features = ["derive"] }
|
||||||
serde_with = { version = "3.16", features = ["hashbrown_0_16", "json"] }
|
serde_with = { version = "3.16", features = ["hashbrown_0_16", "json"] }
|
||||||
@@ -20,12 +20,12 @@ tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
|||||||
anyhow = "1"
|
anyhow = "1"
|
||||||
thiserror = "2"
|
thiserror = "2"
|
||||||
http-body-util = "0.1.1"
|
http-body-util = "0.1.1"
|
||||||
chrono = { version = "0.4", features = ["clock"] }
|
chrono = { version = "0.4", features = ["clock", "serde"] }
|
||||||
reqwest = { version = "0.12", features = ["json", "rustls-tls", "gzip"], default-features = false }
|
reqwest = { version = "0.12", features = ["json", "rustls-tls", "gzip"], default-features = false }
|
||||||
hashbrown = { version = "0.16", features = ["serde"] }
|
hashbrown = { version = "0.16", features = ["serde"] }
|
||||||
concat-idents = "1.1"
|
concat-idents = "1.1"
|
||||||
indoc = "2.0"
|
indoc = "2.0"
|
||||||
sqlx = { version = "0.8", features = ["runtime-tokio", "sqlite"] }
|
sqlx = { version = "0.8", features = ["runtime-tokio", "sqlite", "chrono"] }
|
||||||
rust-embed = "8.0"
|
rust-embed = "8.0"
|
||||||
mime_guess = "2.0"
|
mime_guess = "2.0"
|
||||||
jsonwebtoken = "9"
|
jsonwebtoken = "9"
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
use serde::{Deserialize, Serialize};
|
use std::fmt::Display;
|
||||||
|
|
||||||
|
use chrono::{DateTime, TimeZone, Utc};
|
||||||
|
use serde::{Deserialize, Serialize, Serializer};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|
||||||
// Authentication models
|
// Authentication models
|
||||||
@@ -48,8 +51,10 @@ pub struct RuleResponse {
|
|||||||
pub action: String,
|
pub action: String,
|
||||||
pub custom_response: Option<String>,
|
pub custom_response: Option<String>,
|
||||||
pub is_enabled: bool,
|
pub is_enabled: bool,
|
||||||
pub created_at: String,
|
#[serde(serialize_with = "serialize_dt")]
|
||||||
pub updated_at: String,
|
pub created_at: DateTime<Utc>,
|
||||||
|
#[serde(serialize_with = "serialize_dt")]
|
||||||
|
pub updated_at: DateTime<Utc>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<crate::db::models::InterceptionRule> for RuleResponse {
|
impl From<crate::db::models::InterceptionRule> for RuleResponse {
|
||||||
@@ -71,8 +76,10 @@ pub struct CommandResponse {
|
|||||||
pub id: i64,
|
pub id: i64,
|
||||||
pub command: Value,
|
pub command: Value,
|
||||||
pub status: String,
|
pub status: String,
|
||||||
pub received_at: String,
|
#[serde(serialize_with = "serialize_dt")]
|
||||||
pub processed_at: Option<String>,
|
pub received_at: DateTime<Utc>,
|
||||||
|
#[serde(serialize_with = "serialize_option_dt")]
|
||||||
|
pub processed_at: Option<DateTime<Utc>>,
|
||||||
pub notes: Option<String>,
|
pub notes: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,3 +106,24 @@ impl ApiError {
|
|||||||
Self { error: msg.into() }
|
Self { error: msg.into() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn serialize_dt<S, TZ>(dt: &DateTime<TZ>, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
TZ: TimeZone,
|
||||||
|
TZ::Offset: Display,
|
||||||
|
S: Serializer,
|
||||||
|
{
|
||||||
|
let s = dt.format("%Y-%m-%d %H:%M:%S %z").to_string();
|
||||||
|
serializer.serialize_str(&s)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn serialize_option_dt<S, TZ>(dt: &Option<DateTime<TZ>>, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
TZ: TimeZone,
|
||||||
|
TZ::Offset: Display,
|
||||||
|
S: Serializer,
|
||||||
|
{
|
||||||
|
dt.as_ref()
|
||||||
|
.map(|dt| dt.format("%Y-%m-%d %H:%M:%S %z").to_string())
|
||||||
|
.serialize(serializer)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,4 +1,7 @@
|
|||||||
use serde::{Deserialize, Serialize};
|
use std::fmt::Display;
|
||||||
|
|
||||||
|
use chrono::{DateTime, TimeZone, Utc};
|
||||||
|
use serde::{Deserialize, Serialize, Serializer};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, sqlx::FromRow)]
|
#[derive(Debug, Clone, Serialize, Deserialize, sqlx::FromRow)]
|
||||||
@@ -8,8 +11,10 @@ pub struct InterceptionRule {
|
|||||||
pub action: String,
|
pub action: String,
|
||||||
pub custom_response: Option<String>,
|
pub custom_response: Option<String>,
|
||||||
pub is_enabled: bool,
|
pub is_enabled: bool,
|
||||||
pub created_at: String,
|
#[serde(serialize_with = "serialize_dt")]
|
||||||
pub updated_at: String,
|
pub created_at: DateTime<Utc>,
|
||||||
|
#[serde(serialize_with = "serialize_dt")]
|
||||||
|
pub updated_at: DateTime<Utc>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, sqlx::FromRow)]
|
#[derive(Debug, Clone, Serialize, Deserialize, sqlx::FromRow)]
|
||||||
@@ -17,8 +22,11 @@ pub struct Command {
|
|||||||
pub id: i64,
|
pub id: i64,
|
||||||
pub command_json: String,
|
pub command_json: String,
|
||||||
pub status: String,
|
pub status: String,
|
||||||
pub received_at: String,
|
#[serde(serialize_with = "serialize_dt")]
|
||||||
pub processed_at: Option<String>,
|
pub received_at: DateTime<Utc>,
|
||||||
|
#[serde(serialize_with = "serialize_option_dt")]
|
||||||
|
#[serde(default)]
|
||||||
|
pub processed_at: Option<DateTime<Utc>>,
|
||||||
pub notes: Option<String>,
|
pub notes: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -27,7 +35,8 @@ pub struct Config {
|
|||||||
pub key: String,
|
pub key: String,
|
||||||
pub value: String,
|
pub value: String,
|
||||||
pub description: Option<String>,
|
pub description: Option<String>,
|
||||||
pub updated_at: String,
|
#[serde(serialize_with = "serialize_dt")]
|
||||||
|
pub updated_at: DateTime<Utc>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, sqlx::FromRow)]
|
#[derive(Debug, Clone, Serialize, Deserialize, sqlx::FromRow)]
|
||||||
@@ -38,5 +47,27 @@ pub struct RequestLog {
|
|||||||
pub response_body: Value,
|
pub response_body: Value,
|
||||||
pub request_interception_action: String,
|
pub request_interception_action: String,
|
||||||
pub response_interception_action: String,
|
pub response_interception_action: String,
|
||||||
pub created_at: String,
|
#[serde(serialize_with = "serialize_dt")]
|
||||||
|
pub created_at: DateTime<Utc>,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn serialize_dt<S, TZ>(dt: &DateTime<TZ>, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
TZ: TimeZone,
|
||||||
|
TZ::Offset: Display,
|
||||||
|
S: Serializer,
|
||||||
|
{
|
||||||
|
let s = dt.format("%Y-%m-%d %H:%M:%S %z").to_string();
|
||||||
|
serializer.serialize_str(&s)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn serialize_option_dt<S, TZ>(dt: &Option<DateTime<TZ>>, serializer: S) -> Result<S::Ok, S::Error>
|
||||||
|
where
|
||||||
|
TZ: TimeZone,
|
||||||
|
TZ::Offset: Display,
|
||||||
|
S: Serializer,
|
||||||
|
{
|
||||||
|
dt.as_ref()
|
||||||
|
.map(|dt| dt.format("%Y-%m-%d %H:%M:%S %z").to_string())
|
||||||
|
.serialize(serializer)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user