Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wasm web support #620

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ cfg-if = "1.0"
# https://rustsec.org/advisories/RUSTSEC-2020-0053.html
dirs-next = { version = "2.0", optional = true }
# For History
fd-lock = "3.0.0"
fd-lock = { version = "3.0.0", optional = true }
libc = "0.2"
log = "0.4"
unicode-width = "0.1"
Expand Down Expand Up @@ -58,14 +58,15 @@ assert_matches = "1.2"
rustyline-derive = { version = "0.6.0", path = "rustyline-derive" }

[features]
default = ["custom-bindings", "with-dirs"]
default = ["custom-bindings", "with-dirs", "wasm-incompatible"]
custom-bindings = ["radix_trie"]
with-dirs = ["dirs-next"]
with-fuzzy = ["skim"]
case_insensitive_history_search = ["regex"]
wasm-incompatible = ["fd-lock"]

[package.metadata.docs.rs]
features = ["custom-bindings", "with-dirs", "with-fuzzy"]
features = ["custom-bindings", "with-dirs", "with-fuzzy", "wasm-incompatible"]
all-features = false
no-default-features = true
default-target = "x86_64-unknown-linux-gnu"
Expand Down
54 changes: 50 additions & 4 deletions src/history.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
//! History API

#[cfg(feature = "fd-lock")]
use fd_lock::RwLock;
#[cfg(feature = "fd-lock")]
use log::{debug, warn};
use std::collections::vec_deque;
use std::collections::VecDeque;
use std::fs::{File, OpenOptions};
#[cfg(feature = "fd-lock")]
use std::fs::File;
#[cfg(feature = "fd-lock")]
use std::fs::OpenOptions;
#[cfg(feature = "fd-lock")]
use std::io::SeekFrom;
use std::iter::DoubleEndedIterator;
use std::ops::Index;
use std::path::{Path, PathBuf};
use std::path::Path;
#[cfg(feature = "fd-lock")]
use std::path::PathBuf;
#[cfg(feature = "fd-lock")]
use std::time::SystemTime;

use super::Result;
Expand Down Expand Up @@ -50,15 +59,18 @@ pub struct History {
/// Number of entries inputed by user and not saved yet
new_entries: usize,
/// last path used by either `load` or `save`
#[cfg(feature = "fd-lock")]
path_info: Option<PathInfo>,
}

/// Last histo path, modified timestamp and size
#[cfg(feature = "fd-lock")]
struct PathInfo(PathBuf, SystemTime, usize);

impl History {
// New multiline-aware history files start with `#V2\n` and have newlines
// and backslashes escaped in them.
#[cfg(feature = "fd-lock")]
const FILE_VERSION_V2: &'static str = "#V2";

/// Default constructor
Expand All @@ -79,6 +91,7 @@ impl History {
ignore_space: config.history_ignore_space(),
ignore_dups: config.history_duplicates() == HistoryDuplicates::IgnoreConsecutive,
new_entries: 0,
#[cfg(feature = "fd-lock")]
path_info: None,
}
}
Expand Down Expand Up @@ -154,6 +167,7 @@ impl History {
/// Save the history in the specified file.
// TODO history_truncate_file
// https://tiswww.case.edu/php/chet/readline/history.html#IDX31
#[cfg(feature = "fd-lock")]
pub fn save<P: AsRef<Path> + ?Sized>(&mut self, path: &P) -> Result<()> {
if self.is_empty() || self.new_entries == 0 {
return Ok(());
Expand All @@ -170,6 +184,16 @@ impl History {
self.update_path(path, &lock_guard, self.len())
}

/// Save the history in the specified file.
// TODO history_truncate_file
/// Not implemented for wasm.
// https://tiswww.case.edu/php/chet/readline/history.html#IDX31
#[cfg(not(feature = "fd-lock"))]
pub fn save<P: AsRef<Path> + ?Sized>(&mut self, _path: &P) -> Result<()> {
todo!();
}

#[cfg(feature = "fd-lock")]
fn save_to(&mut self, file: &File, append: bool) -> Result<()> {
use std::io::{BufWriter, Write};

Expand Down Expand Up @@ -204,6 +228,7 @@ impl History {

/// Append new entries in the specified file.
// Like [append_history](http://tiswww.case.edu/php/chet/readline/history.html#IDX30).
#[cfg(feature = "fd-lock")]
pub fn append<P: AsRef<Path> + ?Sized>(&mut self, path: &P) -> Result<()> {
use std::io::Seek;

Expand Down Expand Up @@ -251,10 +276,19 @@ impl History {
Ok(())
}

/// Append new entries in the specified file.
// Like [append_history](http://tiswww.case.edu/php/chet/readline/history.html#IDX30).
/// Not implemented for wasm.
#[cfg(not(feature = "fd-lock"))]
pub fn append<P: AsRef<Path> + ?Sized>(&mut self, _path: &P) -> Result<()> {
todo!();
}

/// Load the history from the specified file.
///
/// # Errors
/// Will return `Err` if path does not already exist or could not be read.
#[cfg(feature = "fd-lock")]
pub fn load<P: AsRef<Path> + ?Sized>(&mut self, path: &P) -> Result<()> {
let path = path.as_ref();
let file = File::open(path)?;
Expand All @@ -270,6 +304,16 @@ impl History {
}
}

/// Load the history from the specified file.
/// Not implemented for wasm.
/// # Errors
/// Will return `Err` if path does not already exist or could not be read.
#[cfg(not(feature = "fd-lock"))]
pub fn load<P: AsRef<Path> + ?Sized>(&mut self, _path: &P) -> Result<()> {
todo!();
}

#[cfg(feature = "fd-lock")]
fn load_from(&mut self, file: &File) -> Result<bool> {
use std::io::{BufRead, BufReader};

Expand Down Expand Up @@ -332,6 +376,7 @@ impl History {
Ok(appendable)
}

#[cfg(feature = "fd-lock")]
fn update_path(&mut self, path: &Path, file: &File, size: usize) -> Result<()> {
let modified = file.metadata()?.modified()?;
if let Some(PathInfo(
Expand All @@ -352,6 +397,7 @@ impl History {
Ok(())
}

#[cfg(feature = "fd-lock")]
fn can_just_append(&self, path: &Path, file: &File) -> Result<bool> {
if let Some(PathInfo(ref previous_path, ref previous_modified, ref previous_size)) =
self.path_info
Expand Down Expand Up @@ -543,15 +589,15 @@ impl<'a> DoubleEndedIterator for Iter<'a> {
}

cfg_if::cfg_if! {
if #[cfg(any(windows, target_arch = "wasm32"))] {
if #[cfg(all(any(windows, target_arch = "wasm32"), feature = "fd-lock"))] {
fn umask() -> u16 {
0
}

fn restore_umask(_: u16) {}

fn fix_perm(_: &File) {}
} else if #[cfg(unix)] {
} else if #[cfg(all(unix, feature = "fd-lock"))] {
use nix::sys::stat::{self, Mode, fchmod};
fn umask() -> Mode {
stat::umask(Mode::S_IXUSR | Mode::S_IRWXG | Mode::S_IRWXO)
Expand Down