From 4077c33adfdacaf0ed68657a1955a7b69a78d373 Mon Sep 17 00:00:00 2001 From: Vlad Stepanov <8uk.8ak@gmail.com> Date: Thu, 15 Jun 2023 14:29:40 +0400 Subject: Builder interface for History objects (#933) * [feature] store env variables in History records WIP: remove `HistoryWithoutDelete`, add some docstrings, tests * Create History objects through builders. Assure in compile-time that all required fields are set for the given construction scenario * (from #882) split Cmd::run into subfns * Update `History` doc * remove rmp-serde from history * update warning --------- Co-authored-by: Conrad Ludgate --- atuin-client/src/history/builder.rs | 100 ++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 atuin-client/src/history/builder.rs (limited to 'atuin-client/src/history/builder.rs') diff --git a/atuin-client/src/history/builder.rs b/atuin-client/src/history/builder.rs new file mode 100644 index 00000000..dc22b60e --- /dev/null +++ b/atuin-client/src/history/builder.rs @@ -0,0 +1,100 @@ +use chrono::Utc; +use typed_builder::TypedBuilder; + +use super::History; + +/// Builder for a history entry that is imported from shell history. +/// +/// The only two required fields are `timestamp` and `command`. +#[derive(Debug, Clone, TypedBuilder)] +pub struct HistoryImported { + timestamp: chrono::DateTime, + #[builder(setter(into))] + command: String, + #[builder(default = "unknown".into(), setter(into))] + cwd: String, + #[builder(default = -1)] + exit: i64, + #[builder(default = -1)] + duration: i64, + #[builder(default, setter(strip_option, into))] + session: Option, + #[builder(default, setter(strip_option, into))] + hostname: Option, +} + +impl From for History { + fn from(imported: HistoryImported) -> Self { + History::new( + imported.timestamp, + imported.command, + imported.cwd, + imported.exit, + imported.duration, + imported.session, + imported.hostname, + None, + ) + } +} + +/// Builder for a history entry that is captured via hook. +/// +/// This builder is used only at the `start` step of the hook, +/// so it doesn't have any fields which are known only after +/// the command is finished, such as `exit` or `duration`. +#[derive(Debug, Clone, TypedBuilder)] +pub struct HistoryCaptured { + timestamp: chrono::DateTime, + #[builder(setter(into))] + command: String, + #[builder(setter(into))] + cwd: String, +} + +impl From for History { + fn from(captured: HistoryCaptured) -> Self { + History::new( + captured.timestamp, + captured.command, + captured.cwd, + -1, + -1, + None, + None, + None, + ) + } +} + +/// Builder for a history entry that is loaded from the database. +/// +/// All fields are required, as they are all present in the database. +#[derive(Debug, Clone, TypedBuilder)] +pub struct HistoryFromDb { + id: String, + timestamp: chrono::DateTime, + command: String, + cwd: String, + exit: i64, + duration: i64, + session: String, + hostname: String, + deleted_at: Option>, +} + +impl From for History { + fn from(from_db: HistoryFromDb) -> Self { + History { + id: from_db.id, + timestamp: from_db.timestamp, + exit: from_db.exit, + command: from_db.command, + cwd: from_db.cwd, + duration: from_db.duration, + session: from_db.session, + hostname: from_db.hostname, + deleted_at: from_db.deleted_at, + } + } +} -- cgit v1.3.1