mirror of
https://github.com/icewind1991/zox
synced 2026-06-03 18:34:07 +02:00
initial implementation
This commit is contained in:
parent
9a8d5e4873
commit
c8408bc2bb
3 changed files with 384 additions and 4 deletions
201
Cargo.lock
generated
Normal file
201
Cargo.lock
generated
Normal file
|
|
@ -0,0 +1,201 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
[[package]]
|
||||
name = "bstr"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"regex-automata 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "csv"
|
||||
version = "1.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"bstr 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "csv-core"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "home"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.65"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "main_error"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pico-args"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.102"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.102"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
name = "zox"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"csv 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"home 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"main_error 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"pico-args 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[metadata]
|
||||
"checksum bstr 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8d6c2c5b58ab920a4f5aeaaca34b4488074e8cc7596af94e6f8c6ff247c60245"
|
||||
"checksum byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a7c3dd8985a7111efc5c80b44e23ecdd8c007de8ade3b96595387e812b957cf5"
|
||||
"checksum csv 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37519ccdfd73a75821cac9319d4fce15a81b9fcf75f951df5b9988aa3a0af87d"
|
||||
"checksum csv-core 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9b5cadb6b25c77aeff80ba701712494213f4a8418fcda2ee11b6560c3ad0bf4c"
|
||||
"checksum home 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a3753954f7bd71f0e671afb8b5a992d1724cf43b7f95a563cd4a0bde94659ca8"
|
||||
"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f"
|
||||
"checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
"checksum libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)" = "1a31a0627fdf1f6a39ec0dd577e101440b7db22672c0901fe00a9a6fbb5c24e8"
|
||||
"checksum main_error 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3516df0fb44d98fe6d6e859d224adfb7b6686447937e5b96308d6061595eed04"
|
||||
"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
|
||||
"checksum pico-args 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "22e32b0f3771287ebb436130477eabf0f11f934ed036099ad548bc885e708667"
|
||||
"checksum proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "9c9e470a8dc4aeae2dee2f335e8f533e2d4b347e1434e5671afc49b054592f27"
|
||||
"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
|
||||
"checksum regex-automata 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "92b73c2a1770c255c240eaa4ee600df1704a38dc3feaa6e949e7fcd4f8dc09f9"
|
||||
"checksum ryu 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8"
|
||||
"checksum scopeguard 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b42e15e59b18a828bbf5c58ea01debb36b9b096346de35d941dcb89009f24a0d"
|
||||
"checksum serde 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4b39bd9b0b087684013a792c59e3e07a46a01d2322518d8a1104641a0b1be0"
|
||||
"checksum serde_derive 1.0.102 (registry+https://github.com/rust-lang/crates.io-index)" = "ca13fc1a832f793322228923fbb3aba9f3f44444898f835d31ad1b74fa0a2bf8"
|
||||
"checksum syn 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "661641ea2aa15845cddeb97dad000d22070bb5c1fb456b96c1cba883ec691e92"
|
||||
"checksum unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
|
||||
"checksum winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6"
|
||||
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
|
@ -4,6 +4,9 @@ version = "0.1.0"
|
|||
authors = ["Robin Appelman <robin@icewind.nl>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
csv = "1.1"
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
pico-args = "0.3.0"
|
||||
home = "0.5.1"
|
||||
main_error = "0.1.0"
|
||||
180
src/main.rs
180
src/main.rs
|
|
@ -1,3 +1,179 @@
|
|||
fn main() {
|
||||
println!("Hello, world!");
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::cmp::Ordering;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
use main_error::MainError;
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
struct History {
|
||||
path: String,
|
||||
rank: f64,
|
||||
time: u64,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
enum SortBy {
|
||||
Frecent,
|
||||
Time,
|
||||
Rank,
|
||||
}
|
||||
|
||||
struct Args {
|
||||
add: bool,
|
||||
list: bool,
|
||||
help: bool,
|
||||
sort: SortBy,
|
||||
filter: Vec<String>,
|
||||
}
|
||||
|
||||
impl Args {
|
||||
pub fn from_env() -> Self {
|
||||
let mut args = pico_args::Arguments::from_env();
|
||||
|
||||
Args {
|
||||
add: args.contains("--add"),
|
||||
help: args.contains(["-h", "--help"]),
|
||||
sort: if args.contains("-t") {
|
||||
SortBy::Time
|
||||
} else if args.contains("-r") {
|
||||
SortBy::Rank
|
||||
} else {
|
||||
SortBy::Frecent
|
||||
},
|
||||
list: args.contains("-l"),
|
||||
filter: args.free().unwrap_or_default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const HOUR: u64 = 3600;
|
||||
const DAY: u64 = 86_400;
|
||||
const WEEK: u64 = 604_800;
|
||||
|
||||
impl History {
|
||||
pub fn frecent(&self, current_time: u64) -> f64 {
|
||||
match current_time - self.time {
|
||||
age if age < HOUR => self.rank * 4.0,
|
||||
age if age < DAY => self.rank * 2.0,
|
||||
age if age < WEEK => self.rank / 2.0,
|
||||
_ => self.rank / 4.0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn matches(&self, pattern: &[String]) -> bool {
|
||||
pattern.iter().all(|pat| self.path.contains(pat))
|
||||
}
|
||||
|
||||
pub fn get_sort(&self, sort: SortBy, current_time: u64) -> f64 {
|
||||
match sort {
|
||||
SortBy::Rank => self.rank,
|
||||
SortBy::Time => self.time as f64,
|
||||
SortBy::Frecent => self.frecent(current_time),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn now() -> u64 {
|
||||
let start = SystemTime::now();
|
||||
start
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.expect("Time went backwards")
|
||||
.as_secs()
|
||||
}
|
||||
|
||||
fn main() -> Result<(), MainError> {
|
||||
let args = Args::from_env();
|
||||
|
||||
let home = home::home_dir().expect("Cant get home directory");
|
||||
let history_path = home.join(".z");
|
||||
|
||||
let mut reader = csv::ReaderBuilder::new()
|
||||
.delimiter(b'|')
|
||||
.has_headers(false)
|
||||
.from_path(history_path.clone())
|
||||
.unwrap();
|
||||
|
||||
let now = now();
|
||||
|
||||
if args.help {
|
||||
println!("zox [-h][-l][-r][-t] args");
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let history = reader
|
||||
.deserialize::<History>()
|
||||
.filter_map(|result| result.ok());
|
||||
|
||||
if args.add {
|
||||
let home = home.to_str().expect("Home path not valid utf8").to_string();
|
||||
|
||||
let mut history: Vec<_> = history.collect();
|
||||
|
||||
for path in args.filter {
|
||||
if path != home {
|
||||
let mut existing = false;
|
||||
for item in history.iter_mut() {
|
||||
if item.path == path {
|
||||
item.rank += 1.0;
|
||||
item.time = now;
|
||||
|
||||
existing = true;
|
||||
}
|
||||
}
|
||||
|
||||
if !existing {
|
||||
history.push(History {
|
||||
path,
|
||||
rank: 1.0,
|
||||
time: now,
|
||||
})
|
||||
}
|
||||
|
||||
dbg!(existing);
|
||||
}
|
||||
}
|
||||
|
||||
let total = history.iter().fold(0.0, |sum, item| sum + item.rank);
|
||||
|
||||
if total > 9000.0 {
|
||||
for item in history.iter_mut() {
|
||||
item.rank *= 0.99;
|
||||
}
|
||||
}
|
||||
|
||||
let mut writer = csv::WriterBuilder::new()
|
||||
.delimiter(b'|')
|
||||
.has_headers(false)
|
||||
.from_path(history_path)?;
|
||||
|
||||
for item in history.into_iter().filter(|item| item.rank >= 1.0) {
|
||||
writer.serialize(item).unwrap();
|
||||
}
|
||||
|
||||
writer.flush()?;
|
||||
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let matches = history.filter(|item| item.matches(&args.filter));
|
||||
|
||||
if args.list {
|
||||
for item in matches {
|
||||
println!("{:<11}{}", item.get_sort(args.sort, now), item.path);
|
||||
}
|
||||
} else {
|
||||
let mut matches: Vec<History> = matches.collect();
|
||||
matches.sort_by(
|
||||
|a, b| match a.get_sort(args.sort, now) - b.get_sort(args.sort, now) {
|
||||
diff if diff < 0.0 => Ordering::Greater,
|
||||
diff if diff > 0.0 => Ordering::Less,
|
||||
_ => Ordering::Equal,
|
||||
},
|
||||
);
|
||||
|
||||
if let Some(first) = matches.first() {
|
||||
println!("{}", first.path);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue