Salto de complejidad enorme; hasta nuevo aviso

This commit is contained in:
perro tuerto 2023-02-15 08:19:42 -08:00
parent f88b2601d4
commit 7155aa67b8
27 changed files with 763 additions and 0 deletions

355
exercises/ex03/Cargo.lock generated Normal file
View File

@ -0,0 +1,355 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "aho-corasick"
version = "0.7.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
dependencies = [
"memchr",
]
[[package]]
name = "ansi_term"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
dependencies = [
"winapi",
]
[[package]]
name = "assert_cmd"
version = "2.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9834fcc22e0874394a010230586367d4a3e9f11b560f469262678547e1d2575e"
dependencies = [
"bstr",
"doc-comment",
"predicates",
"predicates-core",
"predicates-tree",
"wait-timeout",
]
[[package]]
name = "atty"
version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
dependencies = [
"hermit-abi",
"libc",
"winapi",
]
[[package]]
name = "autocfg"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bstr"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7f0778972c64420fdedc63f09919c8a88bda7b25135357fd25a5d9f3257e832"
dependencies = [
"memchr",
"once_cell",
"regex-automata",
"serde",
]
[[package]]
name = "cat"
version = "0.1.0"
dependencies = [
"assert_cmd",
"clap",
"predicates",
"rand",
]
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "2.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
dependencies = [
"ansi_term",
"atty",
"bitflags",
"strsim",
"textwrap",
"unicode-width",
"vec_map",
]
[[package]]
name = "difflib"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8"
[[package]]
name = "doc-comment"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fea41bba32d969b513997752735605054bc0dfa92b4c56bf1189f2e174be7a10"
[[package]]
name = "either"
version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
[[package]]
name = "float-cmp"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4"
dependencies = [
"num-traits",
]
[[package]]
name = "getrandom"
version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "hermit-abi"
version = "0.1.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
dependencies = [
"libc",
]
[[package]]
name = "itertools"
version = "0.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
dependencies = [
"either",
]
[[package]]
name = "libc"
version = "0.2.139"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "201de327520df007757c1f0adce6e827fe8562fbc28bfd9c15571c66ca1f5f79"
[[package]]
name = "memchr"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
[[package]]
name = "normalize-line-endings"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be"
[[package]]
name = "num-traits"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
dependencies = [
"autocfg",
]
[[package]]
name = "once_cell"
version = "1.17.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
[[package]]
name = "ppv-lite86"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "predicates"
version = "2.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59230a63c37f3e18569bdb90e4a89cbf5bf8b06fea0b84e65ea10cc4df47addd"
dependencies = [
"difflib",
"float-cmp",
"itertools",
"normalize-line-endings",
"predicates-core",
"regex",
]
[[package]]
name = "predicates-core"
version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72f883590242d3c6fc5bf50299011695fa6590c2c70eac95ee1bdb9a733ad1a2"
[[package]]
name = "predicates-tree"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54ff541861505aabf6ea722d2131ee980b8276e10a1297b94e896dd8b621850d"
dependencies = [
"predicates-core",
"termtree",
]
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom",
]
[[package]]
name = "regex"
version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-automata"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
[[package]]
name = "regex-syntax"
version = "0.6.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848"
[[package]]
name = "serde"
version = "1.0.152"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb"
[[package]]
name = "strsim"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[package]]
name = "termtree"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95059e91184749cb66be6dc994f67f182b6d897cb3df74a5bf66b5e709295fd8"
[[package]]
name = "textwrap"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
dependencies = [
"unicode-width",
]
[[package]]
name = "unicode-width"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
[[package]]
name = "vec_map"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
[[package]]
name = "wait-timeout"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6"
dependencies = [
"libc",
]
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

14
exercises/ex03/Cargo.toml Normal file
View File

@ -0,0 +1,14 @@
[package]
name = "cat"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
clap = "2.33"
[dev-dependencies]
assert_cmd = "2"
predicates = "2"
rand = "0.8"

70
exercises/ex03/src/lib.rs Normal file
View File

@ -0,0 +1,70 @@
use std::error::Error;
use clap::{App, Arg};
use std::fs::File;
use std::io::{self, BufRead, BufReader};
type MyResult<T> = Result<T, Box<dyn Error>>;
#[derive(Debug)]
pub struct Config {
files: Vec<String>,
numbered: bool,
nonblank: bool,
}
pub fn run(config: Config) -> MyResult<()> {
for filename in config.files {
match open(&filename) {
Err(err) => eprintln!("Failed to open {}: {}", filename, err),
Ok(file) => print(&file, &config.numbered, &config.nonblank),
}
}
Ok(())
}
pub fn get_args() -> MyResult<Config> {
let matches = App::new("cat")
.version("0.1.0")
.author("perro <hi@perrotuerto.blog>")
.about("Rust cat")
.arg(
Arg::with_name("files")
.value_name("ARCHIVOS")
.help("Archivos de entrada")
.multiple(true)
.default_value("-"),
)
.arg(
Arg::with_name("numbered")
.short("n")
.long("number")
.help("Imprime números de línea")
.takes_value(false)
.conflicts_with("nonblank"),
)
.arg(
Arg::with_name("nonblank")
.short("b")
.long("number-nonblank")
.help("Imprime números de línea solo si no están vacías")
.takes_value(false),
)
.get_matches();
Ok(Config {
files: matches.values_of_lossy("files").unwrap(),
numbered: matches.is_present("numbered"),
nonblank: matches.is_present("nonblank"),
})
}
fn open(filename: &str) -> MyResult<Box<dyn BufRead>> {
match filename {
"-" => Ok(Box::new(BufReader::new(io::stdin()))),
_ => Ok(Box::new(BufReader::new(File::open(filename)?))),
}
}
fn print(_file: &Box<dyn BufRead>, _numbered: &bool, _nonblank: &bool) {
// TODO
}

View File

@ -0,0 +1,6 @@
fn main () {
if let Err(e) = cat::get_args().and_then(cat::run) {
eprintln!("{}", e);
std::process::exit(1);
}
}

200
exercises/ex03/tests/cli.rs Normal file
View File

@ -0,0 +1,200 @@
use assert_cmd::Command;
use predicates::prelude::*;
use rand::{distributions::Alphanumeric, Rng};
use std::error::Error;
use std::fs;
type TestResult = Result<(), Box<dyn Error>>;
const PRG: &str = "cat";
const EMPTY: &str = "tests/inputs/empty.txt";
const FOX: &str = "tests/inputs/fox.txt";
const SPIDERS: &str = "tests/inputs/spiders.txt";
const BUSTLE: &str = "tests/inputs/the-bustle.txt";
// --------------------------------------------------
#[test]
fn usage() -> TestResult {
for flag in &["-h", "--help"] {
Command::cargo_bin(PRG)?
.arg(flag)
.assert()
.stdout(predicate::str::contains("USAGE"));
}
Ok(())
}
// --------------------------------------------------
fn gen_bad_file() -> String {
loop {
let filename: String = rand::thread_rng()
.sample_iter(&Alphanumeric)
.take(7)
.map(char::from)
.collect();
if fs::metadata(&filename).is_err() {
return filename;
}
}
}
// --------------------------------------------------
#[test]
fn skips_bad_file() -> TestResult {
let bad = gen_bad_file();
let expected = format!("{}: .* [(]os error 2[)]", bad);
Command::cargo_bin(PRG)?
.arg(&bad)
.assert()
.success()
.stderr(predicate::str::is_match(expected)?);
Ok(())
}
// --------------------------------------------------
fn run(args: &[&str], expected_file: &str) -> TestResult {
let expected = fs::read_to_string(expected_file)?;
Command::cargo_bin(PRG)?
.args(args)
.assert()
.success()
.stdout(expected);
Ok(())
}
// --------------------------------------------------
fn run_stdin(
input_file: &str,
args: &[&str],
expected_file: &str,
) -> TestResult {
let input = fs::read_to_string(input_file)?;
let expected = fs::read_to_string(expected_file)?;
Command::cargo_bin(PRG)?
.args(args)
.write_stdin(input)
.assert()
.success()
.stdout(expected);
Ok(())
}
// --------------------------------------------------
#[test]
fn bustle_stdin() -> TestResult {
run_stdin(BUSTLE, &["-"], "tests/expected/the-bustle.txt.stdin.out")
}
// --------------------------------------------------
#[test]
fn bustle_stdin_n() -> TestResult {
run_stdin(
BUSTLE,
&["-n", "-"],
"tests/expected/the-bustle.txt.n.stdin.out",
)
}
// --------------------------------------------------
#[test]
fn bustle_stdin_b() -> TestResult {
run_stdin(
BUSTLE,
&["-b", "-"],
"tests/expected/the-bustle.txt.b.stdin.out",
)
}
// --------------------------------------------------
#[test]
fn empty() -> TestResult {
run(&[EMPTY], "tests/expected/empty.txt.out")
}
// --------------------------------------------------
#[test]
fn empty_n() -> TestResult {
run(&["-n", EMPTY], "tests/expected/empty.txt.n.out")
}
// --------------------------------------------------
#[test]
fn empty_b() -> TestResult {
run(&["-b", EMPTY], "tests/expected/empty.txt.b.out")
}
// --------------------------------------------------
#[test]
fn fox() -> TestResult {
run(&[FOX], "tests/expected/fox.txt.out")
}
// --------------------------------------------------
#[test]
fn fox_n() -> TestResult {
run(&["-n", FOX], "tests/expected/fox.txt.n.out")
}
// --------------------------------------------------
#[test]
fn fox_b() -> TestResult {
run(&["-b", FOX], "tests/expected/fox.txt.b.out")
}
// --------------------------------------------------
#[test]
fn spiders() -> TestResult {
run(&[SPIDERS], "tests/expected/spiders.txt.out")
}
// --------------------------------------------------
#[test]
fn spiders_n() -> TestResult {
run(&["--number", SPIDERS], "tests/expected/spiders.txt.n.out")
}
// --------------------------------------------------
#[test]
fn spiders_b() -> TestResult {
run(
&["--number-nonblank", SPIDERS],
"tests/expected/spiders.txt.b.out",
)
}
// --------------------------------------------------
#[test]
fn bustle() -> TestResult {
run(&[BUSTLE], "tests/expected/the-bustle.txt.out")
}
// --------------------------------------------------
#[test]
fn bustle_n() -> TestResult {
run(&["-n", BUSTLE], "tests/expected/the-bustle.txt.n.out")
}
// --------------------------------------------------
#[test]
fn bustle_b() -> TestResult {
run(&["-b", BUSTLE], "tests/expected/the-bustle.txt.b.out")
}
// --------------------------------------------------
#[test]
fn all() -> TestResult {
run(&[FOX, SPIDERS, BUSTLE], "tests/expected/all.out")
}
// --------------------------------------------------
#[test]
fn all_n() -> TestResult {
run(&[FOX, SPIDERS, BUSTLE, "-n"], "tests/expected/all.n.out")
}
// --------------------------------------------------
#[test]
fn all_b() -> TestResult {
run(&[FOX, SPIDERS, BUSTLE, "-b"], "tests/expected/all.b.out")
}

View File

@ -0,0 +1,13 @@
1 The quick brown fox jumps over the lazy dog.
1 Don't worry, spiders,
2 I keep house
3 casually.
1 The bustle in a house
2 The morning after death
3 Is solemnest of industries
4 Enacted upon earth,—
5 The sweeping up the heart,
6 And putting love away
7 We shall not want to use again
8 Until eternity.

View File

@ -0,0 +1,13 @@
1 The quick brown fox jumps over the lazy dog.
1 Don't worry, spiders,
2 I keep house
3 casually.
1 The bustle in a house
2 The morning after death
3 Is solemnest of industries
4 Enacted upon earth,—
5
6 The sweeping up the heart,
7 And putting love away
8 We shall not want to use again
9 Until eternity.

View File

@ -0,0 +1,13 @@
The quick brown fox jumps over the lazy dog.
Don't worry, spiders,
I keep house
casually.
The bustle in a house
The morning after death
Is solemnest of industries
Enacted upon earth,—
The sweeping up the heart,
And putting love away
We shall not want to use again
Until eternity.

View File

@ -0,0 +1 @@
1 The quick brown fox jumps over the lazy dog.

View File

@ -0,0 +1 @@
1 The quick brown fox jumps over the lazy dog.

View File

@ -0,0 +1 @@
The quick brown fox jumps over the lazy dog.

View File

@ -0,0 +1,3 @@
1 Don't worry, spiders,
2 I keep house
3 casually.

View File

@ -0,0 +1,3 @@
1 Don't worry, spiders,
2 I keep house
3 casually.

View File

@ -0,0 +1,3 @@
Don't worry, spiders,
I keep house
casually.

View File

@ -0,0 +1,9 @@
1 The bustle in a house
2 The morning after death
3 Is solemnest of industries
4 Enacted upon earth,—
5 The sweeping up the heart,
6 And putting love away
7 We shall not want to use again
8 Until eternity.

View File

@ -0,0 +1,9 @@
1 The bustle in a house
2 The morning after death
3 Is solemnest of industries
4 Enacted upon earth,—
5 The sweeping up the heart,
6 And putting love away
7 We shall not want to use again
8 Until eternity.

View File

@ -0,0 +1,9 @@
1 The bustle in a house
2 The morning after death
3 Is solemnest of industries
4 Enacted upon earth,—
5
6 The sweeping up the heart,
7 And putting love away
8 We shall not want to use again
9 Until eternity.

View File

@ -0,0 +1,9 @@
1 The bustle in a house
2 The morning after death
3 Is solemnest of industries
4 Enacted upon earth,—
5
6 The sweeping up the heart,
7 And putting love away
8 We shall not want to use again
9 Until eternity.

View File

@ -0,0 +1,9 @@
The bustle in a house
The morning after death
Is solemnest of industries
Enacted upon earth,—
The sweeping up the heart,
And putting love away
We shall not want to use again
Until eternity.

View File

@ -0,0 +1,9 @@
The bustle in a house
The morning after death
Is solemnest of industries
Enacted upon earth,—
The sweeping up the heart,
And putting love away
We shall not want to use again
Until eternity.

View File

View File

@ -0,0 +1 @@
The quick brown fox jumps over the lazy dog.

View File

@ -0,0 +1,3 @@
Don't worry, spiders,
I keep house
casually.

View File

@ -0,0 +1,9 @@
The bustle in a house
The morning after death
Is solemnest of industries
Enacted upon earth,—
The sweeping up the heart,
And putting love away
We shall not want to use again
Until eternity.