Skip to content

Commit

Permalink
WIP: Cached file property extraction, used thiserror for file errors …
Browse files Browse the repository at this point in the history
…instead of miette
  • Loading branch information
ryanpeach committed Nov 1, 2024
1 parent 85b00aa commit efd1ec5
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 21 deletions.
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ debug = false

[dependencies]
bon = "2.3.0"
cached = "0.53.1"
clap = { version = "4.5.16", features = ["derive"] }
env_logger = "0.11.5"
fuzzy-matcher = "0.3.7"
Expand Down
18 changes: 18 additions & 0 deletions src/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ use std::path::PathBuf;

use walkdir::WalkDir;

use thiserror::Error;

use std;

pub mod content;
pub mod name;

Expand All @@ -18,3 +22,17 @@ pub fn get_files(dirs: Vec<PathBuf>) -> Vec<PathBuf> {
}
out
}

/// A bunch of bad things can happen while you're reading files,
/// This covers most of them.
#[derive(Debug, Error)]
pub enum Error {
#[error("Error reading the file.")]
IoError(#[from] std::io::Error),
#[error("Error parsing the yaml based on expected template.")]
SerdeError(#[from] serde_yaml::Error),
#[error("Found duplicate property {0} in file contents")]
DuplicateProperty(String),
}


16 changes: 16 additions & 0 deletions src/file/content.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,19 @@
use std::{fs, path::PathBuf};

use cached::proc_macro::cached;
use front_matter::FrontMatter;

use super::Error;

pub mod body;
pub mod front_matter;
pub mod lists;

/// Get all information from a file needed for the rest of the program
/// Importantly, this is cached, so you don't have to pass around the results
/// Just run it at the very beginning of the program
#[cached(result = true)]
pub fn from_file(path: PathBuf) -> Result<FrontMatter, Error> {
let contents = fs::read_to_string(path).map_err(Error::IoError)?;
FrontMatter::new(&contents)
}
13 changes: 3 additions & 10 deletions src/file/content/front_matter.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
mod logseq;
mod yaml;

use std::path::PathBuf;
use super::Error;

use miette::{miette, Result};

#[derive(Debug, Default)]
#[derive(Debug, Default, Clone)]
pub struct FrontMatter {
/// The aliases of the file
pub aliases: Vec<String>,
}

impl FrontMatter {
pub fn new(contents: &str) -> Result<Self> {
pub fn new(contents: &str) -> Result<Self, Error> {
// Try to parse as YAML
let out = yaml::Config::new(contents)?;
if !out.is_empty() {
Expand All @@ -28,11 +26,6 @@ impl FrontMatter {
// If we can't parse it, return the default
Ok(Self::default())
}

pub fn from_file(path: &PathBuf) -> Result<Self> {
let contents = std::fs::read_to_string(path).map_err(|e| miette!(e))?;
Self::new(&contents)
}
}

#[cfg(test)]
Expand Down
9 changes: 5 additions & 4 deletions src/file/content/front_matter/logseq.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,26 @@
use serde::{Deserialize, Serialize};

use miette::{miette, Result};
use regex::Regex;

use crate::file::Error;

#[derive(Serialize, Deserialize, Debug, Default)]
pub struct Config {
/// The aliases of the file
#[serde(default)]
pub alias: Vec<String>,
}

fn parse_csv(contents: &str) -> Result<Vec<String>> {
fn parse_csv(contents: &str) -> Result<Vec<String>, Error> {
contents
.split(',')
.map(|s| Ok(s.trim().to_string()))
.collect()
}

impl Config {
pub fn new(contents: &str) -> Result<Self> {
pub fn new(contents: &str) -> Result<Self, Error> {
// find alias:: and capture the rest of the line as csv
let re = Regex::new(r"alias::\s*(.*)").expect("Its a constant.");

Expand All @@ -34,7 +35,7 @@ impl Config {
// The first capture group is the regex match as a whole
// The second is the parenthesized subexpression
if caps.len() > 2 {
return Err(miette!("More than one alias property found."));
return Err(Error::DuplicateProperty("alias".to_owned()));
}
let alias =
parse_csv(&caps[1]).expect("Already checked for exactly one capture group.");
Expand Down
6 changes: 3 additions & 3 deletions src/file/content/front_matter/yaml.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
use serde::{Deserialize, Serialize};

use miette::{miette, Result};
use crate::file::Error;

#[derive(Serialize, Deserialize, Debug, Default)]
pub struct Config {
Expand All @@ -15,7 +15,7 @@ pub struct Config {
}

impl Config {
pub fn new(contents: &str) -> Result<Self> {
pub fn new(contents: &str) -> Result<Self, Error> {
// See if contents contains "---" and a newline and another "---" using multiline regex
let re = regex::Regex::new(r"(?s)---\n(.*)\n---").expect("Its a constant.");
let frontmatter = re.captures(contents);
Expand All @@ -25,7 +25,7 @@ impl Config {
None => Ok(Self::default()),
Some(caps) => {
// Parse the YAML
serde_yaml::from_str(&caps[1]).map_err(|e| miette!(e))
serde_yaml::from_str(&caps[1]).map_err(Error::SerdeError)
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/rules/broken_wikilink.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::{collections::HashMap, path::PathBuf};
use miette::{miette, Diagnostic, NamedSource, Result, SourceSpan};
use thiserror::Error;

use crate::{file::content::front_matter::FrontMatter, rules::duplicate_alias::DuplicateAlias};
use crate::{file::content::from_file, rules::duplicate_alias::DuplicateAlias};

use super::HasCode;

Expand Down Expand Up @@ -47,7 +47,7 @@ impl BrokenWikilink {
let mut lookup_table = HashMap::<String, PathBuf>::new();
for file_path in files {
let front_matter =
FrontMatter::from_file(&file_path).expect("This file was reported as existing");
from_file(file_path.clone()).map_err(|e| miette!(e))?;
for alias in front_matter.aliases {
if let Some(out) = lookup_table.insert(alias.clone(), file_path.clone()) {
return match DuplicateAlias::new(&alias, &out, &file_path) {
Expand Down
4 changes: 2 additions & 2 deletions src/rules/duplicate_alias.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use bon::Builder;
use miette::{miette, Diagnostic, NamedSource, Result, SourceOffset, SourceSpan};
use thiserror::Error;

use crate::{file::content::front_matter::FrontMatter, sed::MissingSubstringError};
use crate::{file::content::from_file, sed::MissingSubstringError};

use super::HasCode;

Expand Down Expand Up @@ -173,7 +173,7 @@ impl DuplicateAlias {
let mut lookup_table = HashMap::<String, PathBuf>::new();
let mut duplicates: Vec<DuplicateAlias> = Vec::new();
for file_path in files {
let front_matter = FrontMatter::from_file(&file_path).map_err(|e| miette!(e))?;
let front_matter = from_file(file_path.clone()).map_err(|e| miette!(e))?;
for alias in front_matter.aliases {
if let Some(out) = lookup_table.insert(alias.clone(), file_path.clone()) {
duplicates.push(
Expand Down

0 comments on commit efd1ec5

Please sign in to comment.