Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/check-links.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ jobs:
fail: false
checkbox: false
output: ./lychee/out.md
args: "--mode task --base . --config ./ci/lychee.toml ."
args: "--base . --config ./ci/lychee.toml ."

- name: Save lychee cache
uses: actions/cache/save@v4
Expand Down
23 changes: 10 additions & 13 deletions .github/workflows/mdbook-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,19 @@ jobs:
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
cache: 'true'
toolchain: nightly
toolchain: stable

- name: Run tests
id: cargo_test
run: |
cargo +nightly test --test skeptic -- -Z unstable-options --format junit --report-time --test-threads=1 | tee ./TEST-cookbook.xml
cargo test --test skeptic -- --test-threads=1

- name: List files for debugging
- name: Test Results
if: always()
run: ls -R

- name: Publish Test Report
uses: mikepenz/[email protected]
if: always()
with:
fail_on_failure: true
require_tests: true
summary: ${{ steps.cargo_test.outputs.summary }}
report_paths: '**/TEST-*.xml'
run: |
if [ ${{ steps.cargo_test.outcome }} == 'success' ]; then
echo "✅ All tests passed!"
else
echo "❌ Some tests failed. Check the logs above for details."
exit 1
fi
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@ target/
book/
*.swp
lines.txt
.idea/
.idea/
.skeptic-cache
.lycheecache
3 changes: 3 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"makefile.configureOnOpen": false
}
6 changes: 3 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -259,9 +259,9 @@ after the code sample.
> The [distributions available are documented here][rand-distributions].

[uniform distribution]: https://en.wikipedia.org/wiki/Uniform_distribution_(continuous)
[`Distribution::sample`]: https://docs.rs/rand/*/rand/distributions/trait.Distribution.html#tymethod.sample
[`rand::Rng`]: https://docs.rs/rand/*/rand/trait.Rng.html
[rand-distributions]: https://docs.rs/rand/*/rand/distributions/index.html
[`Distribution::sample`]: https://docs.rs/rand/0.9/rand/distr/trait.Distribution.html#tymethod.sample
[`rand::Rng`]: https://docs.rs/rand/0.9/rand/trait.Rng.html
[rand-distributions]: https://docs.rs/rand/0.9/rand/distr/index.html

#### Code

Expand Down
28 changes: 18 additions & 10 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,28 @@ license = "MIT/Apache-2.0"
publish = false
build = "build.rs"

[features]
default = []
test-rand = []

[dependencies]
ansi_term = "0.11.0"
approx = "0.3"
base64 = "0.9"
bitflags = "1.0"
base64 = "0.22.1"
bitflags = "1.3.2"
byteorder = "1.0"
cc = "1.0"
chrono = "0.4"
clap = "4.5"
crossbeam = "0.5"
crossbeam-channel = "0.3.9"
crossbeam = "0.8"
crossbeam-channel = "0.5"
csv = "1.0"
data-encoding = "2.1.0"
env_logger = "0.11.3"
flate2 = "1.0"
glob = "0.3"
image = "0.20"
image = "0.24"

lazy_static = "1.0"
log = "0.4"
log4rs = "0.8"
Expand All @@ -35,23 +40,26 @@ num = "0.4"
num_cpus = "1.16"
percent-encoding = "2.3"
petgraph = "0.6"
postgres = "0.19"
postgres = "0.19.7"
rand = "0.9"
rand_distr = "0.5.1"
rand_distr = "0.5"
rayon = "1.10"
regex = "1.11"
reqwest = { version = "0.12", features = ["blocking", "json", "stream"] }
ring = "0.17"
rusqlite = { version = "0.32", features = ["chrono"] }
same-file = "1.0"
select = "0.6"
select = "0.6.0"

semver = "1.0"
serde = { version = "1.0", features = ["derive"] }
serde_derive = "1.0"
serde_json = "1.0"
sha2 = "0.10"
tar = "0.4"
tempfile = "3.14"
thiserror = "2"
anyhow = "1.0"
threadpool = "1.8"
toml = "0.8"
tokio = { version = "1", features = ["full"] }
Expand All @@ -63,9 +71,9 @@ walkdir = "2.5"
syslog = "5.0"

[build-dependencies]
skeptic = "0.13"
skeptic = { git = "https://github.com/AndyGauge/rust-skeptic", branch = "rlib-patch" }
walkdir = "2.5"

[dev-dependencies]
skeptic = "0.13"
skeptic = { git = "https://github.com/AndyGauge/rust-skeptic", branch = "rlib-patch" }
walkdir = "2.5"
2 changes: 1 addition & 1 deletion LICENSE-CC0
Original file line number Diff line number Diff line change
Expand Up @@ -113,4 +113,4 @@ Affirmer's express Statement of Purpose.
CC0 or use of the Work.

For more information, please see
<http://creativecommons.org/publicdomain/zero/1.0/>
<https://creativecommons.org/publicdomain/zero/1.0/>
9 changes: 3 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
# A Rust Cookbook &emsp; [![Build Status][build-badge]][build-url]

[build-badge]: https://github.com/rust-lang-nursery/rust-cookbook/workflows/Deploy%20to%20GitHub%20Pages/badge.svg
[build-url]: https://github.com/rust-lang-nursery/rust-cookbook/actions?query=workflow%3A%22Deploy+to+GitHub+Pages%22
# A Rust Cookbook

**[Read it here]**.

Expand Down Expand Up @@ -92,12 +89,12 @@ For details see [CONTRIBUTING.md] on GitHub.
## License [![CC0-badge]][CC0-deed]

Rust Cookbook is licensed under Creative Commons Zero v1.0 Universal License
([LICENSE-CC0](LICENSE-CC0) or https://creativecommons.org/publicdomain/zero/1.0/legalcode)
([LICENSE-CC0](LICENSE-CC0) or https://creativecommons.org/)

Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in Rust Cookbook by you, as defined in the CC0-1.0 license, shall be
[dedicated to the public domain][CC0-deed] and licensed as above, without any additional
terms or conditions.

[CC0-deed]: https://creativecommons.org/publicdomain/zero/1.0/deed.en
[CC0-deed]: https://creativecommons.org/publicdomain/zero/1.0/
[CC0-badge]: https://mirrors.creativecommons.org/presskit/buttons/80x15/svg/cc-zero.svg
14 changes: 14 additions & 0 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,20 @@ const REMOVED_TESTS: &[&str] = &[
];

fn main() {
#[cfg(feature = "test-rand")]
{
let rand_paths = vec![
"./src/algorithms/randomness/rand.md",
"./src/algorithms/randomness/rand-range.md",
"./src/algorithms/randomness/rand-dist.md",
"./src/algorithms/randomness/rand-custom.md",
"./src/algorithms/randomness/rand-passwd.md",
"./src/algorithms/randomness/rand-choose.md",
];
skeptic::generate_doc_tests(&rand_paths[..]);
return;
}

let paths = WalkDir::new("./src/").into_iter()
// convert paths to Strings
.map(|p| p.unwrap().path().to_str().unwrap().to_string())
Expand Down
7 changes: 7 additions & 0 deletions ci/lychee.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,10 @@ exclude_loopback = false

# Check mail addresses
include_mail = true

# Exclude problematic links that consistently fail
exclude = [
# Creative Commons links return 403 for automated requests
"https://creativecommons.org/publicdomain/zero/1.0/",
"https://creativecommons.org/"
]
22 changes: 12 additions & 10 deletions src/about.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,9 @@ Consider this example for "generate random numbers within a range":
use rand::Rng;

fn main() {
let mut rng = rand::thread_rng();
println!("Random f64: {}", rng.gen::<f64>());
let mut rng = rand::rng();
let random_number: u32 = rng.random();
println!("Random number: {}", random_number);
}
```

Expand Down Expand Up @@ -97,14 +98,15 @@ should read after deciding which crate suites your purpose.

## A note about error handling
Rust has [`std::error::Trait`] which is implemented to handle exceptions.
Handling multiple types of these traits can be simplified using [`anyhow`]
or specified with an `enum` which macros exist to make this easier within
[`thiserror`] for library authors.
This cookbook uses [`anyhow`] for simplified error handling in examples,
which provides easy error propagation and context. For library authors,
[`thiserror`] provides a more structured approach using derive macros
to create custom error types.

Error chain has been shown in this book for historical reasons before Rust
`std` and crates represented macro use as a preference. For more background
on error handling in Rust, read [this page of the Rust book][error-docs]
and [this blog post][error-blog].
This cookbook previously used the `error-chain` crate, but has been updated
to use `anyhow` as it's now the preferred approach for application-level
error handling. For more background on error handling in Rust, read
[this page of the Rust book][error-docs] and [this blog post][error-blog].

## A note about crate representation

Expand All @@ -129,7 +131,7 @@ as are crates that are pending evaluation.
{{#include links.md}}

[index]: intro.html
[error-docs]: https://do.rust-lang.org/book/error-handling.html
[error-docs]: https://doc.rust-lang.org/book/ch09-00-error-handling.html
[error-blog]: https://brson.github.io/2016/11/30/starting-with-error-chain
[error-chain]: https://docs.rs/error-chain/
[Rust Libz Blitz]: https://internals.rust-lang.org/t/rust-libz-blitz/5184
Expand Down
20 changes: 11 additions & 9 deletions src/algorithms/randomness/rand-choose.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,28 @@
[![rand-badge]][rand] [![cat-os-badge]][cat-os]

Randomly generates a string of given length ASCII characters with custom
user-defined bytestring, with [`random_range`].
user-defined bytestring, with [`gen_range`].

```rust,edition2018
use rand::Rng;

const CHARSET: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ\
abcdefghijklmnopqrstuvwxyz\
0123456789)(*&^%$#@!~";
const PASSWORD_LEN: usize = 30;

fn main() {
use rand::Rng;
const CHARSET: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ\
abcdefghijklmnopqrstuvwxyz\
0123456789)(*&^%$#@!~";
const PASSWORD_LEN: usize = 30;
let mut rng = rand::rng();

let password: String = (0..PASSWORD_LEN)
.map(|_| {
let idx = rng.random_range(0..CHARSET.len());
CHARSET[idx] as char
let idx = rng.gen_range(0..CHARSET.len());
char::from(CHARSET[idx])
})
.collect();

println!("{:?}", password);
}
```

[`random_range`]: https://docs.rs/rand/*/rand/trait.Rng.html#method.random_range
[`gen_range`]: https://docs.rs/rand/0.9/rand/trait.Rng.html#method.gen_range
16 changes: 7 additions & 9 deletions src/algorithms/randomness/rand-custom.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,30 @@ Implements the [`Distribution`] trait on type Point for [`Standard`] in order to

```rust,edition2018
use rand::Rng;
use rand::distributions::{Distribution, Standard};

#[derive(Debug)]
struct Point {
x: i32,
y: i32,
}

impl Distribution<Point> for Standard {
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> Point {
let (rand_x, rand_y) = rng.random();
impl Point {
fn random<R: Rng>(rng: &mut R) -> Self {
Point {
x: rand_x,
y: rand_y,
x: rng.random(),
y: rng.random(),
}
}
}

fn main() {
let mut rng = rand::rng();
let rand_tuple = rng.random::<(i32, bool, f64)>();
let rand_point: Point = rng.random();
let rand_point = Point::random(&mut rng);
println!("Random tuple: {:?}", rand_tuple);
println!("Random Point: {:?}", rand_point);
}
```

[`Distribution`]: https://docs.rs/rand/*/rand/distributions/trait.Distribution.html
[`Standard`]: https://docs.rs/rand/*/rand/distributions/struct.Standard.html
[Distribution]: https://docs.rs/rand/0.9/rand/distr/trait.Distribution.html
[Standard]: https://docs.rs/rand/0.9/rand/distr/struct.Standard.html
23 changes: 14 additions & 9 deletions src/algorithms/randomness/rand-dist.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,27 @@ generator [`rand::Rng`].
The [distributions available are documented here][rand-distributions].
An example using the [`Normal`] distribution is shown below.

```rust,edition2018,ignore
use rand_distr::{Distribution, Normal, NormalError};
use rand::rng;
```rust,edition2018
use rand::Rng;
use rand_distr::{Distribution, LogNormal, Normal};

fn main() {
let mut rng = rand::rng();
let normal = Normal::new(2.0, 3.0)
.expect("Failed to create normal distribution");
let log_normal = LogNormal::new(1.0, 0.5)
.expect("Failed to create log-normal distribution");

fn main() -> Result<(), NormalError> {
let mut rng = rng();
let normal = Normal::new(2.0, 3.0)?;
let v = normal.sample(&mut rng);
println!("{} is from a N(2, 9) distribution", v);
Ok(())
let v = log_normal.sample(&mut rng);
println!("{} is from an ln N(1, 0.25) distribution", v);
}
```

[`Distribution::sample`]: https://docs.rs/rand/*/rand/distributions/trait.Distribution.html#tymethod.sample
[`Distribution::sample`]: https://docs.rs/rand/0.9/rand/distr/trait.Distribution.html#tymethod.sample
[`Normal`]: https://docs.rs/rand_distr/*/rand_distr/struct.Normal.html
[`rand::Rng`]: https://docs.rs/rand/*/rand/trait.Rng.html
[`rand::Rng`]: https://docs.rs/rand/0.9/rand/trait.Rng.html
[`rand_distr`]: https://docs.rs/rand_distr/*/rand_distr/index.html
[rand-distributions]: https://docs.rs/rand_distr/*/rand_distr/index.html

Expand Down
Loading