1use chrono::Utc;
2#[cfg(any(feature = "sqlite", feature = "sqlite-dynlib"))]
3use rusqlite::ToSql;
4use serde::{de::DeserializeOwned, Deserialize, Serialize};
5use std::{fmt::Display, time::Duration};
6
7#[derive(Debug, Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
9pub struct HistoryItemId(pub i64);
10impl HistoryItemId {
11 pub const fn new(i: i64) -> HistoryItemId {
13 HistoryItemId(i)
14 }
15}
16
17impl Display for HistoryItemId {
18 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
19 write!(f, "{}", self.0)
20 }
21}
22
23#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
25pub struct HistorySessionId(pub(crate) i64);
26impl HistorySessionId {
27 pub(crate) const fn new(i: i64) -> HistorySessionId {
28 HistorySessionId(i)
29 }
30}
31
32impl Display for HistorySessionId {
33 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34 write!(f, "{}", self.0)
35 }
36}
37
38#[cfg(any(feature = "sqlite", feature = "sqlite-dynlib"))]
39impl ToSql for HistorySessionId {
40 fn to_sql(&self) -> rusqlite::Result<rusqlite::types::ToSqlOutput<'_>> {
41 Ok(rusqlite::types::ToSqlOutput::Owned(
42 rusqlite::types::Value::Integer(self.0),
43 ))
44 }
45}
46
47impl From<HistorySessionId> for i64 {
48 fn from(id: HistorySessionId) -> Self {
49 id.0
50 }
51}
52
53pub trait HistoryItemExtraInfo: Serialize + DeserializeOwned + Default + Send {}
55
56#[derive(Clone, Copy, Default, Debug, PartialEq, Eq)]
57pub struct IgnoreAllExtraInfo;
59
60impl Serialize for IgnoreAllExtraInfo {
61 fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
62 where
63 S: serde::Serializer,
64 {
65 Option::<IgnoreAllExtraInfo>::None.serialize(serializer)
66 }
67}
68
69impl<'de> Deserialize<'de> for IgnoreAllExtraInfo {
70 fn deserialize<D>(d: D) -> std::result::Result<Self, D::Error>
71 where
72 D: serde::Deserializer<'de>,
73 {
74 serde::de::IgnoredAny::deserialize(d).map(|_| IgnoreAllExtraInfo)
75 }
76}
77
78impl HistoryItemExtraInfo for IgnoreAllExtraInfo {}
79
80#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
82pub struct HistoryItem<ExtraInfo: HistoryItemExtraInfo = IgnoreAllExtraInfo> {
83 pub id: Option<HistoryItemId>,
85 pub start_timestamp: Option<chrono::DateTime<Utc>>,
87 pub command_line: String,
89 pub session_id: Option<HistorySessionId>,
92 pub hostname: Option<String>,
94 pub cwd: Option<String>,
96 pub duration: Option<Duration>,
98 pub exit_status: Option<i64>,
100 #[serde(deserialize_with = "Option::<ExtraInfo>::deserialize")]
105 pub more_info: Option<ExtraInfo>,
106}
107
108impl HistoryItem {
109 pub fn from_command_line(cmd: impl Into<String>) -> HistoryItem {
111 HistoryItem {
112 id: None,
113 start_timestamp: None,
114 command_line: cmd.into(),
115 session_id: None,
116 hostname: None,
117 cwd: None,
118 duration: None,
119 exit_status: None,
120 more_info: None,
121 }
122 }
123}