Skip to content

Commit

Permalink
Create zet search Command (#8)
Browse files Browse the repository at this point in the history
* Enable visit all the folders/file inside the zet repository
* Enable `zet search`
* Improve the documentation for zet::dir
* Added example of environment needed by project
* Added the zet current dir for testing on gitignore
  • Loading branch information
peterramaldes authored Nov 1, 2023
1 parent 4cd9bc4 commit 45872ee
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 28 deletions.
1 change: 1 addition & 0 deletions .envrc.example
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ZET_PATH="./zet"
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
/target
/zet
.envrc
33 changes: 6 additions & 27 deletions src/create.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,19 @@ use std::{
};

pub fn run() -> io::Result<()> {
let path = get_path_from_files();
let path = zet::dir();

// Create the path if doesn't exists, thrown an error if cannot
fs::create_dir_all(&path)?;

// Create dir if doesn´t exists
let today = Utc::now();
let folder_name = today.date_naive().format("%Y%m%d");
let folder_path = format!("{path}/{folder_name}");
let folder_path = format!(
"{}/{}",
path.into_os_string().into_string().unwrap(),
folder_name
);
let _ = fs::create_dir(&folder_path);

// Create the file
Expand All @@ -29,28 +33,3 @@ pub fn run() -> io::Result<()> {

Ok(())
}

/// Get path with this precendece:
///
/// 1. $ZET_PATH
/// 2. $HOME/.config/zet
///
/// This function is not portable, the .config folder will not work on windows
fn get_path_from_files() -> String {
let mut path = match env::var("ZET_PATH") {
Ok(val) => String::from(val),
Err(_e) => "".to_string(),
};

if path.is_empty() {
let home = match env::var("HOME") {
Ok(val) => String::from(val),
Err(_e) => panic!("doesn't have $HOME env set"), // TODO: this should not be a problem
// for windows :(
};

path = format!("{home}/.config/zet");
}

path
}
29 changes: 29 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use std::{
env,
path::{Path, PathBuf},
};

/// Returns the directory for Zettelkasten repository
///
/// The Zettelkasten repository take the below procedence:
/// 1. `${ZET_PATH}`
/// 2. `$HOME/.config/zet`
///
pub fn dir() -> PathBuf {
let mut path = match env::var("ZET_PATH") {
Ok(val) => String::from(val),

Check warning on line 14 in src/lib.rs

View workflow job for this annotation

GitHub Actions / clippy

useless conversion to the same type: `std::string::String`

warning: useless conversion to the same type: `std::string::String` --> src/lib.rs:14:20 | 14 | Ok(val) => String::from(val), | ^^^^^^^^^^^^^^^^^ help: consider removing `String::from()`: `val` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#useless_conversion = note: `#[warn(clippy::useless_conversion)]` on by default
Err(_e) => "".to_string(),
};

if path.is_empty() {
let home = match env::var("HOME") {
Ok(val) => String::from(val),

Check warning on line 20 in src/lib.rs

View workflow job for this annotation

GitHub Actions / clippy

useless conversion to the same type: `std::string::String`

warning: useless conversion to the same type: `std::string::String` --> src/lib.rs:20:24 | 20 | Ok(val) => String::from(val), | ^^^^^^^^^^^^^^^^^ help: consider removing `String::from()`: `val` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#useless_conversion
Err(_e) => panic!("doesn't have $HOME env set"), // TODO: this should not be a problem
// for windows :(
};

path = format!("{home}/.config/zet");
}

return Path::new(&path).to_path_buf();
}
19 changes: 18 additions & 1 deletion src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
pub mod create;
pub mod search;

use clap::Parser;
use clap::{Args, Parser};

#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
Expand All @@ -16,12 +17,28 @@ enum Subcommand {
/// the env isn´t set.
#[clap(visible_alias = "c")]
Create,

/// Search specific words on the Zettelkasten repository
#[clap(visible_alias = "s")]
Search(SearchArgs),
}

#[derive(Args, Debug)]
pub struct SearchArgs {
/// The word that you are trying to find on Zettelkasten repository
#[arg(short, long)]
target_word: Option<String>,

/// If this flag enable, means that the word search using the `target_word` will ignore case
#[arg(short, long)]
ignore_case: bool,
}

fn main() -> std::io::Result<()> {
let cli = Cli::parse();

return match cli.subcommand {
Subcommand::Create => create::run(),
Subcommand::Search(args) => search::run(args),
};

Check warning on line 43 in src/main.rs

View workflow job for this annotation

GitHub Actions / clippy

unneeded `return` statement

warning: unneeded `return` statement --> src/main.rs:40:5 | 40 | / return match cli.subcommand { 41 | | Subcommand::Create => create::run(), 42 | | Subcommand::Search(args) => search::run(args), 43 | | }; | |_____^ | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_return = note: `#[warn(clippy::needless_return)]` on by default help: remove `return` | 40 ~ match cli.subcommand { 41 + Subcommand::Create => create::run(), 42 + Subcommand::Search(args) => search::run(args), 43 ~ } |
}
43 changes: 43 additions & 0 deletions src/search.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
use std::{
fs::{self},
io::{self, Read},
path::PathBuf,
};

use crate::SearchArgs;

pub fn run(args: SearchArgs) -> io::Result<()> {
println!("Search for word: '{}'", args.target_word.as_ref().unwrap());
search_target_word(&zet::dir(), &args)
}

fn search_target_word(dir: &PathBuf, args: &SearchArgs) -> io::Result<()> {
for entry in fs::read_dir(dir)? {
let entry = entry?;
let path = entry.path();

if entry.file_type()?.is_file() {
// Check if contains the word that we are searching
let file_path = entry.path();

// Open the file
let mut file = fs::File::open(&file_path)?;

// Read the file content into a String
let mut content = String::new();
file.read_to_string(&mut content)?;

// Search for the target word in the content
let target_word = args.target_word.as_ref().unwrap();
if (args.ignore_case && content.to_lowercase().contains(&target_word.to_lowercase()))
|| content.contains(target_word)
{
println!("* {:?}", file_path);
}
} else {
search_target_word(&path, args)?;
}
}

Ok(())
}

0 comments on commit 45872ee

Please sign in to comment.