Provide times as unix seconds for all --json outputs
This commit is contained in:
@@ -4,3 +4,4 @@
|
||||
|
||||
pub mod proto;
|
||||
pub mod server;
|
||||
pub mod util;
|
||||
|
||||
@@ -6,9 +6,12 @@ use std::path::PathBuf;
|
||||
use chrono::{DateTime, TimeDelta, Utc};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::proto::finger_protocol::{
|
||||
classic_formatter::classic_format_finger_response_structured_user_entry,
|
||||
parser::try_parse_structured_user_entry_from_raw_finger_response,
|
||||
use crate::{
|
||||
proto::finger_protocol::{
|
||||
classic_formatter::classic_format_finger_response_structured_user_entry,
|
||||
parser::try_parse_structured_user_entry_from_raw_finger_response,
|
||||
},
|
||||
util::duration_serde,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
@@ -243,10 +246,12 @@ impl FingerResponseStructuredUserEntry {
|
||||
pub enum MailStatus {
|
||||
NoMail,
|
||||
NewMailReceived {
|
||||
#[serde(with = "chrono::serde::ts_seconds")]
|
||||
received_time: DateTime<Utc>,
|
||||
#[serde(with = "chrono::serde::ts_seconds")]
|
||||
unread_since: DateTime<Utc>,
|
||||
},
|
||||
MailLastRead(DateTime<Utc>),
|
||||
MailLastRead(#[serde(with = "chrono::serde::ts_seconds")] DateTime<Utc>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
@@ -255,12 +260,14 @@ pub struct FingerResponseUserSession {
|
||||
pub tty: String,
|
||||
|
||||
/// When the user logged in and created this session
|
||||
#[serde(with = "chrono::serde::ts_seconds")]
|
||||
pub login_time: DateTime<Utc>,
|
||||
|
||||
/// The hostname or address of the machine from which the user is logged in, if available
|
||||
pub host: Option<String>,
|
||||
|
||||
/// The amount of time since the use last interacted with the tty
|
||||
#[serde(with = "duration_serde::duration_seconds_option")]
|
||||
pub idle_time: Option<TimeDelta>,
|
||||
|
||||
/// Whether this tty is writable, and thus can receive messages via `mesg(1)`
|
||||
|
||||
@@ -6,9 +6,12 @@ use bytes::{Buf, BufMut, BytesMut};
|
||||
use chrono::{DateTime, Duration, Utc};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::proto::rwhod_protocol::time_codec::{
|
||||
RwhodTimestamps, decode_rwhod_timestamp_near_time, decode_rwhod_timestamps,
|
||||
encode_rwhod_timestamp,
|
||||
use crate::{
|
||||
proto::rwhod_protocol::time_codec::{
|
||||
RwhodTimestamps, decode_rwhod_timestamp_near_time, decode_rwhod_timestamps,
|
||||
encode_rwhod_timestamp,
|
||||
},
|
||||
util::duration_serde,
|
||||
};
|
||||
|
||||
/// Classic C struct for utmp data for a single user session.
|
||||
@@ -256,9 +259,11 @@ pub type LoadAverage = (i32, i32, i32);
|
||||
pub struct WhodStatusUpdate {
|
||||
// NOTE: there is only one defined packet type, so we just omit it here
|
||||
/// Timestamp by sender
|
||||
#[serde(with = "chrono::serde::ts_seconds")]
|
||||
pub sendtime: DateTime<Utc>,
|
||||
|
||||
/// Timestamp applied by receiver
|
||||
#[serde(with = "chrono::serde::ts_seconds_option")]
|
||||
pub recvtime: Option<DateTime<Utc>>,
|
||||
|
||||
/// Name of the host sending the status update (max 32 characters)
|
||||
@@ -268,6 +273,7 @@ pub struct WhodStatusUpdate {
|
||||
pub load_average: LoadAverage,
|
||||
|
||||
/// Which time the system was booted
|
||||
#[serde(with = "chrono::serde::ts_seconds")]
|
||||
pub boot_time: DateTime<Utc>,
|
||||
|
||||
/// List of users currently logged in to the host (max 42 entries)
|
||||
@@ -307,9 +313,11 @@ pub struct WhodUserEntry {
|
||||
pub user_id: String,
|
||||
|
||||
/// Time when the user logged in
|
||||
#[serde(with = "chrono::serde::ts_seconds")]
|
||||
pub login_time: DateTime<Utc>,
|
||||
|
||||
/// How long since the user last typed on the TTY
|
||||
#[serde(with = "duration_serde::duration_seconds")]
|
||||
pub idle_time: Duration,
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
pub mod duration_serde;
|
||||
@@ -0,0 +1,38 @@
|
||||
pub mod duration_seconds {
|
||||
use chrono::TimeDelta;
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer, de::Error};
|
||||
|
||||
pub fn serialize<S: Serializer>(
|
||||
duration: &TimeDelta,
|
||||
serializer: S,
|
||||
) -> Result<S::Ok, S::Error> {
|
||||
duration.num_seconds().serialize(serializer)
|
||||
}
|
||||
|
||||
pub fn deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result<TimeDelta, D::Error> {
|
||||
let secs = i64::deserialize(deserializer)?;
|
||||
TimeDelta::try_seconds(secs).ok_or_else(|| Error::custom("duration out of range"))
|
||||
}
|
||||
}
|
||||
|
||||
pub mod duration_seconds_option {
|
||||
use chrono::TimeDelta;
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer, de::Error};
|
||||
|
||||
pub fn serialize<S: Serializer>(
|
||||
duration: &Option<TimeDelta>,
|
||||
serializer: S,
|
||||
) -> Result<S::Ok, S::Error> {
|
||||
duration.map(|d| d.num_seconds()).serialize(serializer)
|
||||
}
|
||||
|
||||
pub fn deserialize<'de, D: Deserializer<'de>>(
|
||||
deserializer: D,
|
||||
) -> Result<Option<TimeDelta>, D::Error> {
|
||||
let secs = Option::<i64>::deserialize(deserializer)?;
|
||||
secs.map(|secs| {
|
||||
TimeDelta::try_seconds(secs).ok_or_else(|| Error::custom("duration out of range"))
|
||||
})
|
||||
.transpose()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user