Skip to content

Commit

Permalink
support txtpp as second extension (#8)
Browse files Browse the repository at this point in the history
* support txtpp as second extension

* update readme

* update dependencies
  • Loading branch information
Pistonight authored Oct 30, 2023
1 parent 74f9738 commit 2a32265
Show file tree
Hide file tree
Showing 11 changed files with 259 additions and 227 deletions.
284 changes: 121 additions & 163 deletions Cargo.lock

Large diffs are not rendered by default.

9 changes: 5 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "txtpp"
version = "0.2.2"
version = "0.2.3"
edition = "2021"
description = "A simple-to-use general purpose preprocessor for text files."
repository = "https://github.com/Pistonite/txtpp"
Expand All @@ -12,20 +12,21 @@ exclude = [
"tests/examples/**/*",
"docs/*",
".github/**/*",
"Justfile"
"Taskfile.yml"
]

[dependencies]
which = "^4.4.0"
which = "^5.0.0"
error-stack = "^0.3.1"
termcolor = "^1.2.0"
threadpool = "^1.8.1"
clap = { version = "^4.2.4", features = ["cargo", "derive"], optional = true }
clap = { version = "^4.4.7", features = ["cargo", "derive"], optional = true }
log = "^0.4.17"
env_logger = "^0.10.0"
derivative = "^2.2.0"

[features]
default = ["cli"]
cli = ["clap"]

[dev-dependencies]
Expand Down
26 changes: 0 additions & 26 deletions Justfile

This file was deleted.

1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# txtpp
![Build Badge](https://img.shields.io/github/actions/workflow/status/Pistonite/txtpp/rust.yml)
![Version Badge](https://img.shields.io/crates/v/txtpp)
![Docs Badge](https://img.shields.io/docsrs/txtpp)
![License Badge](https://img.shields.io/github/license/Pistonite/txtpp)
![Issue Badge](https://img.shields.io/github/issues/Pistonite/txtpp)

Expand Down
30 changes: 30 additions & 0 deletions Taskfile.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
version: '3'

tasks:
install:
desc: Install dependencies
cmds:
- rustup update
- cargo install cargo-watch
clean:
desc: Clean example output
cmds:
- cargo run -- clean tests/examples docs -r
readme:
desc: Generate the readme
cmds:
- cargo run -- docs/README.md
- mv docs/README.md README.md
dev:
desc: Run tests in watch mode
cmds:
- cargo watch -x test
check:
desc: Pre-commit checks
cmds:
- cargo clippy --all-targets --all-features -- -D warnings -D clippy::todo
- cargo fmt
- cargo doc
- cargo test
- task: readme
- task: clean
3 changes: 2 additions & 1 deletion docs/README.md.txtpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# txtpp
![Build Badge](https://img.shields.io/github/actions/workflow/status/Pistonite/txtpp/rust.yml)
![Version Badge](https://img.shields.io/crates/v/txtpp)
![Docs Badge](https://img.shields.io/docsrs/txtpp)
![License Badge](https://img.shields.io/github/license/Pistonite/txtpp)
![Issue Badge](https://img.shields.io/github/issues/Pistonite/txtpp)

Expand Down Expand Up @@ -60,7 +59,9 @@ TXTPP#include fiz.txt
- [Execution](#execution)
- [Directive Specification](#directive-specification)
- [Include Directive](#include-directive)
- [After Directive](#after-directive)
- [Run Directive](#run-directive)
- [Empty Directive](#empty-directive)
- [Temp Directive](#temp-directive)
- [Tag Directive](#tag-directive)
- [Write Directive](#write-directive)
Expand Down
5 changes: 1 addition & 4 deletions src/core/util/dependency.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,7 @@ impl DepManager {
if self.finished.contains(dependency) {
continue;
}
let dependers = self
.in_edges
.entry(dependency.clone())
.or_insert(HashSet::new());
let dependers = self.in_edges.entry(dependency.clone()).or_default();
// add depender -> dependency edge
if dependers.insert(depender.clone()) {
*dependency_count += 1;
Expand Down
2 changes: 1 addition & 1 deletion src/fs/io_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ impl IOCtx {
.attach_printable(format!("could not open input file: `{input_path}`"))
})?;

let output_path = input_file.as_path_buf().trim_txtpp().map_err(|e| {
let output_path = input_file.as_path_buf().remove_txtpp().map_err(|e| {
e.change_context(Self::make_error_with_kind(
input_path.clone(),
PpErrorKind::OpenFile,
Expand Down
2 changes: 1 addition & 1 deletion src/fs/path/abs_path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ impl AbsPath {
}

pub fn trim_txtpp(&self) -> Result<String, PathError> {
let p = self.p.trim_txtpp()?;
let p = self.p.remove_txtpp()?;
Ok(path_string_from_base(&self.b, &p))
}
}
Expand Down
122 changes: 97 additions & 25 deletions src/fs/path/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,25 +21,42 @@ mod directory;
pub use directory::*;

pub trait TxtppPath: Sized {
/// Get the path with the txtpp extension,
/// Get the path to the txtpp file corresponding to the current path.
///
/// Return `.txtpp` added to self if:
/// - self does not end with `.txtpp`
/// - `{self}.txtpp` is a file
/// Otherwise, returns None.
/// For a file foo.bar, the txtpp file could be:
/// - foo.bar.txtpp, or
/// - foo.txtpp.bar
///
/// If the path is already a txtpp file, `None` will be returned.
/// Otherwise, if a corresponding txtpp file exists, that will be returned
fn get_txtpp_file(&self) -> Option<Self>;
/// Check if the path has the txtpp extension itself

/// Check if the path matches a txtpp file format. The path can be non-existent and this will
/// still return true as long as the format is correct.
fn is_txtpp_file(&self) -> bool;
/// Remove the txtpp extension from the path.

/// If current path is a txtpp file, return the path corresponding to the output of the txtpp
/// file. This is the reverse of [`TxtppPath::get_txtpp_file`].
///
/// If the path does not have the txtpp extension, an error will be returned.
fn trim_txtpp(&self) -> Result<Self, PathError>;
/// If the path is not a txtpp file, an error will be returned.
fn remove_txtpp(&self) -> Result<Self, PathError>;
}

impl TxtppPath for PathBuf {
fn is_txtpp_file(&self) -> bool {
match self.extension() {
Some(ext) => ext == TXTPP_EXT,
Some(ext) => {
if ext == TXTPP_EXT {
return true;
}
// check if the second extension is txtpp
let mut p = self.clone();
p.set_extension("");
match p.extension() {
Some(ext) => ext == TXTPP_EXT,
None => false,
}
}
None => false,
}
}
Expand All @@ -50,31 +67,57 @@ impl TxtppPath for PathBuf {
}

let mut p = self.clone();
let ext = match p.extension() {
match self.extension() {
Some(ext) => {
let mut ext = ext.to_os_string();
ext.push(".");
ext.push(TXTPP_EXT);
ext
// if there is extension, try .xxx.txtpp then .txtpp.xxx
let mut ext1 = ext.to_os_string();
ext1.push(".");
ext1.push(TXTPP_EXT);
p.set_extension(ext1);

if p.is_file() {
return Some(p);
}
p.set_extension(""); // restore p
let mut ext2 = OsString::from(TXTPP_EXT);
ext2.push(".");
ext2.push(ext);
p.set_extension(ext2);
if p.is_file() {
Some(p)
} else {
None
}
}
None => {
// if there's no extension, the only way is adding .txtpp at the end
let ext = OsString::from(TXTPP_EXT);
p.set_extension(ext);
if p.is_file() {
Some(p)
} else {
None
}
}
None => OsString::from(TXTPP_EXT),
};
p.set_extension(ext);

if p.is_file() {
Some(p)
} else {
None
}
}

fn trim_txtpp(&self) -> Result<Self, PathError> {
fn remove_txtpp(&self) -> Result<Self, PathError> {
if !self.is_txtpp_file() {
return Err(Report::new(PathError::from(self))
.attach_printable(format!("path does not {TXTPP_EXT} extension")));
.attach_printable(format!("path does not have {TXTPP_EXT} extension")));
}
let mut p = self.clone();
p.set_extension("");
if matches!(p.extension(), Some(ext) if ext == TXTPP_EXT) {
// remove the txtpp extension and add the original back
p.set_extension("");
let self_ext = self.extension().ok_or_else(|| {
Report::new(PathError::from(self))
.attach_printable(format!("path does not have {TXTPP_EXT} extension"))
})?;
p.set_extension(self_ext);
}

Ok(p)
}
Expand All @@ -95,3 +138,32 @@ pub fn normalize_path(p: &str) -> &str {
pub fn normalize_path(p: &str) -> &str {
p
}

#[cfg(test)]
mod test {
use super::*;

#[test]
fn test_is_txtpp_file() {
assert!(PathBuf::from("foo.txtpp").is_txtpp_file());
assert!(PathBuf::from("foo.bar.txtpp").is_txtpp_file());
assert!(PathBuf::from("foo.txtpp.bar").is_txtpp_file());
assert!(!PathBuf::from("foo.bar").is_txtpp_file());
assert!(!PathBuf::from("foo").is_txtpp_file());
assert!(!PathBuf::from("txtpp").is_txtpp_file());
}

#[test]
fn test_remove_txtpp() {
assert!(PathBuf::from("foo").remove_txtpp().is_err());
assert!(PathBuf::from("foo.bar").remove_txtpp().is_err());
assert_eq!(
PathBuf::from("foo.bar.txtpp").remove_txtpp().unwrap(),
PathBuf::from("foo.bar")
);
assert_eq!(
PathBuf::from("foo.txtpp.bar").remove_txtpp().unwrap(),
PathBuf::from("foo.bar")
);
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
hello
-TXTPP#include bar.txt
world
world

0 comments on commit 2a32265

Please sign in to comment.