atuin/atuin-client/src/import/nu.rs
Vlad Stepanov 4077c33adf
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 <conrad.ludgate@truelayer.com>
2023-06-15 10:29:40 +00:00

68 lines
1.7 KiB
Rust

// import old shell history!
// automatically hoover up all that we can find
use std::{fs::File, io::Read, path::PathBuf};
use async_trait::async_trait;
use directories::BaseDirs;
use eyre::{eyre, Result};
use super::{unix_byte_lines, Importer, Loader};
use crate::history::History;
#[derive(Debug)]
pub struct Nu {
bytes: Vec<u8>,
}
fn get_histpath() -> Result<PathBuf> {
let base = BaseDirs::new().ok_or_else(|| eyre!("could not determine data directory"))?;
let config_dir = base.config_dir().join("nushell");
let histpath = config_dir.join("history.txt");
if histpath.exists() {
Ok(histpath)
} else {
Err(eyre!("Could not find history file."))
}
}
#[async_trait]
impl Importer for Nu {
const NAME: &'static str = "nu";
async fn new() -> Result<Self> {
let mut bytes = Vec::new();
let path = get_histpath()?;
let mut f = File::open(path)?;
f.read_to_end(&mut bytes)?;
Ok(Self { bytes })
}
async fn entries(&mut self) -> Result<usize> {
Ok(super::count_lines(&self.bytes))
}
async fn load(self, h: &mut impl Loader) -> Result<()> {
let now = chrono::Utc::now();
let mut counter = 0;
for b in unix_byte_lines(&self.bytes) {
let s = match std::str::from_utf8(b) {
Ok(s) => s,
Err(_) => continue, // we can skip past things like invalid utf8
};
let cmd: String = s.replace("<\\n>", "\n");
let offset = chrono::Duration::nanoseconds(counter);
counter += 1;
let entry = History::import().timestamp(now - offset).command(cmd);
h.push(entry.build().into()).await?;
}
Ok(())
}
}