Skip to content

Commit

Permalink
feat: finer snippet parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
derdilla committed Aug 30, 2024
1 parent 1f9f2d7 commit b06f109
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 17 deletions.
2 changes: 1 addition & 1 deletion rust/snippets/src/snippets/creator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ impl SnipCreator {
}

pub fn add(&self, name: String) -> bool {
fs::write(self.path.join(name), "todo");
fs::write(self.path.join(name), "todo").unwrap();
true
}
}
9 changes: 9 additions & 0 deletions rust/snippets/src/snippets/lang.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
pub enum Lang {
Md,
/*Txt,
Rust,
Dart,
C,
Java,
Python,*/
}
32 changes: 16 additions & 16 deletions rust/snippets/src/snippets/mod.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
use std::fs;

use colored::Colorize;
use colored::{Colorize, CustomColor};
use creator::SnipCreator;
use log::{debug, error, info};
use snip::{Snip, SnipBuilder};

use crate::input::config::Config;

mod creator;
mod lang;
mod snip;

pub struct SnipetsFolderBuilder<'a> {
config: &'a Config,
Expand All @@ -31,26 +34,21 @@ impl<'a> ValidatedSnipptsFolder<'a> {
pub fn index(self) -> Option<IndexedSnipptsFolder<'a>> {
match fs::read_dir(&self.config.dir) {
Ok(dir) => {
let mut files = Vec::new();
let mut builders = Vec::new();
let mut initial_length = 0;
for f in dir {
initial_length += 1;
if let Ok(f) = f {
let f = f.path();
if f.is_file() {
if let Some(f) = f.file_name() {
if let Some(f) = f.to_str() {
files.push(f.to_string());
}
}
if let Some(f) = SnipBuilder::try_new(f.path()) {
builders.push(f)
}
}
}

info!("Indexed {} / {} files in snippets dir", files.len(), initial_length);
info!("Indexed {} / {} files in snippets dir", builders.len(), initial_length);
Some(IndexedSnipptsFolder {
config: &self.config,
index: files,
snippets: builders,
})
},
Err(err) => {
Expand All @@ -64,20 +62,22 @@ impl<'a> ValidatedSnipptsFolder<'a> {

pub struct IndexedSnipptsFolder<'a>{
config: &'a Config,
index: Vec<String>,
snippets: Vec<SnipBuilder>,
}

impl<'a> IndexedSnipptsFolder<'a> {
pub fn open(self) -> SnipptsFolder {
let snips = self.snippets.into_iter()
.filter_map(|b| b.build());
SnipptsFolder {
index: self.index,
snippets: snips.collect(),
creator: SnipCreator::new(self.config.dir.clone()),
}
}
}

pub struct SnipptsFolder {
index: Vec<String>,
snippets: Vec<Snip>,
creator: SnipCreator,
}

Expand All @@ -87,8 +87,8 @@ impl SnipptsFolder {
}
pub fn list(&self) {
println!("{}", "Available snippets:".bold().underline());
for file in &self.index {
println!("{}{}", "> ".cyan(), file);
for snip in &self.snippets {
println!("{}{}\t\t{}", "> ".cyan(), snip.name, snip.tags.join(",").custom_color(CustomColor::new(200, 200, 200)).italic());
}
}
}
89 changes: 89 additions & 0 deletions rust/snippets/src/snippets/snip.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
use std::{fs::{self, Metadata}, path::PathBuf, time::SystemTime};

use log::{debug, trace, warn};

use super::lang::Lang;

pub struct Snip {
pub content: String,
pub name: String,
pub last_mod: SystemTime,
pub tags: Vec<String>,
pub lang: Lang,
}

#[derive(Debug)]
pub struct SnipBuilder {
file: PathBuf,
meta: Metadata,
name: String,
}

impl SnipBuilder {
/// Gather outer file information (fast)
pub fn try_new(f: PathBuf) -> Option<Self> {
debug!("Creating SnipBuilder from {:?}", f);
if !f.is_file() {
warn!("{} is not a file, skipping.", f.display());
return None;
}
trace!("Starting filename extraction for {:?}.", &f);
let name = f.file_name()?;
let name = name.to_str()?;
let name = name.to_string();
debug!("Extracted file name from snippet {:?}: {}.", &f, &name);

trace!("Starting metadata extraction for {:?}.", &f);
let meta = f.metadata().ok()?;
debug!("Extracted metadata from snippet {:?}: {:#?}.", &f, &meta);

Some(SnipBuilder {
file: f,
name,
meta
})
}

/// Parse file content and metadata (slower).
pub fn build(self) -> Option<Snip> {
trace!("Building snippet {:?}", &self);

let last_mod = self.meta.modified()
.inspect_err(|err| {
warn!("Cant fetch modified date from snippet {}", self.name);
debug!("{:#?}", err);
})
.ok()?;

let file_content = fs::read_to_string(self.file)
.inspect_err(|err| {
warn!("Cant read snippet to string: {}", self.name);
debug!("{:#?}", err);
})
.ok()?;

let tags = if let Some(tags) = file_content.lines().next() {
debug!("Parsing tag line {}", &tags);
tags.split(',').map(|e|e.to_string()).collect::<Vec<String>>()
} else {
warn!("No tag line in snippet: {}", self.name);
return None;
};

let content = file_content.lines()
.skip(2)
.map(|e| e.to_string())
.collect::<Vec<String>>()
.join("\n");


Some(Snip {
content,
name: self.name,
last_mod,
tags,
lang: Lang::Md,
})
}
}

0 comments on commit b06f109

Please sign in to comment.