Skip to content

Commit bf4ca10

Browse files
committed
initial commit
1 parent ab22342 commit bf4ca10

File tree

5 files changed

+137
-0
lines changed

5 files changed

+137
-0
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/target

Cargo.lock

+61
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[package]
2+
name = "up2code"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
[dependencies]
7+
anyhow = "1.0.89"
8+
regex = "1.11.0"

src/main.rs

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
use regex::Regex;
2+
use std::{env, fs, sync::LazyLock};
3+
4+
static LISTINGS: LazyLock<Regex> = LazyLock::new(|| {
5+
Regex::new(
6+
r"(?m)^```rust\n(?<code>[^`]+?)\n?```\n\(\[Listing `(?<listing>[\s\S]+?)`\]\((?<link>.*?)\)",
7+
)
8+
.unwrap()
9+
});
10+
11+
fn main() -> anyhow::Result<()> {
12+
let paths: Vec<String> = env::args().skip(1).collect();
13+
if paths.is_empty() {
14+
eprintln!("Usage: up2code [PATH, ...]");
15+
return Ok(());
16+
}
17+
for path in &paths {
18+
let text = fs::read_to_string(path)?;
19+
// println!("{text}");
20+
LISTINGS.captures_iter(&text).for_each(|m| {
21+
if let Some(code) = m.name("code") {
22+
println!("Code: {}", code.as_str());
23+
}
24+
if let Some(listing) = m.name("listing") {
25+
println!("Listing: {}", listing.as_str());
26+
}
27+
if let Some(link) = m.name("link") {
28+
println!("Link: {}", link.as_str());
29+
}
30+
});
31+
}
32+
Ok(())
33+
}

tests/data/test.md

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
The conventional answer to this in Rust is to put our unit tests inside a module (`mod tests`, let's say, though the name is up to us), and then protect that module with a `cfg(test)` attribute:
2+
3+
\vspace{5pt}
4+
```rust
5+
#[cfg(test)]
6+
mod tests {
7+
// tests go here
8+
}
9+
```
10+
11+
`cfg` turns compilation on or off for the item it's attached to, based on the value of some expression. `cfg(test)` means the `tests` module will be compiled only if we're running in `cargo test` mode. Otherwise it will be ignored entirely, saving time, energy, and the planet.
12+
13+
### Anatomy of a test module
14+
15+
So here's what our test looks like once we've moved it into its own module:
16+
17+
\vspace{5pt}
18+
```rust
19+
#[cfg(test)]
20+
mod tests {
21+
use super::*;
22+
use std::io;
23+
24+
#[test]
25+
fn count_lines_fn_counts_lines_in_input() {
26+
let input = io::Cursor::new("line 1\nline2\n");
27+
let lines = count_lines(input);
28+
assert_eq!(2, lines);
29+
}
30+
}
31+
```
32+
([Listing `counter_2`](https://github.com/bitfield/tsr-tools/blob/main/counter_2/src/lib.rs))
33+
34+
A module can have its own `use` declarations, which is handy since we often want to `use` things in tests that we don't need in the library itself (`std::io` in this example).

0 commit comments

Comments
 (0)