Vendor things

This commit is contained in:
John Doty 2024-03-08 11:03:01 -08:00
parent 5deceec006
commit 977e3c17e5
19434 changed files with 10682014 additions and 0 deletions

314
third-party/vendor/if_chain/src/lib.rs vendored Normal file
View file

@ -0,0 +1,314 @@
//! This crate provides a single macro called `if_chain!`.
//!
//! `if_chain!` lets you write long chains of nested `if` and `if let`
//! statements without the associated rightward drift. It also supports multiple
//! patterns (e.g. `if let Foo(a) | Bar(a) = b`) in places where Rust would
//! normally not allow them.
//!
//! See the associated [blog post] for the background behind this crate.
//!
//! [blog post]: https://lambda.xyz/blog/if-chain
//!
//! # Note about recursion limits
//!
//! If you run into "recursion limit reached" errors while using this macro, try
//! adding
//!
//! ```rust,ignore
//! #![recursion_limit = "1000"]
//! ```
//!
//! to the top of your crate.
//!
//! # Examples
//!
//! ## Quick start
//!
//! ```rust,ignore
//! if_chain! {
//! if let Some(y) = x;
//! if y.len() == 2;
//! if let Some(z) = y;
//! then {
//! do_stuff_with(z);
//! }
//! }
//! ```
//!
//! becomes
//!
//! ```rust,ignore
//! if let Some(y) = x {
//! if y.len() == 2 {
//! if let Some(z) = y {
//! do_stuff_with(z);
//! }
//! }
//! }
//! ```
//!
//! ## Fallback values with `else`
//!
//! ```rust,ignore
//! if_chain! {
//! if let Some(y) = x;
//! if let Some(z) = y;
//! then {
//! do_stuff_with(z)
//! } else {
//! do_something_else()
//! }
//! }
//! ```
//!
//! becomes
//!
//! ```rust,ignore
//! if let Some(y) = x {
//! if let Some(z) = y {
//! do_stuff_with(z)
//! } else {
//! do_something_else()
//! }
//! } else {
//! do_something_else()
//! }
//! ```
//!
//! ## Intermediate variables with `let`
//!
//! ```rust,ignore
//! if_chain! {
//! if let Some(y) = x;
//! let z = y.some().complicated().expression();
//! if z == 42;
//! then {
//! do_stuff_with(y);
//! }
//! }
//! ```
//!
//! becomes
//!
//! ```rust,ignore
//! if let Some(y) = x {
//! let z = y.some().complicated().expression();
//! if z == 42 {
//! do_stuff_with(y);
//! }
//! }
//! ```
//!
//! ## Type ascription
//!
//! ```rust,ignore
//! let mut x = some_generic_computation();
//! if_chain! {
//! if x > 7;
//! let y: u32 = another_generic_computation();
//! then { x += y }
//! else { x += 1 }
//! }
//! ```
//!
//! becomes
//!
//! ```rust,ignore
//! let mut x = some_generic_computation();
//! if x > 7 {
//! let y: u32 = another_generic_computation();
//! x += y
//! } else {
//! x += 1
//! }
//! ```
//!
//! ## Multiple patterns
//!
//! ```rust,ignore
//! if_chain! {
//! if let Foo(y) | Bar(y) | Baz(y) = x;
//! let Bubbles(z) | Buttercup(z) | Blossom(z) = y;
//! then { do_stuff_with(z) }
//! }
//! ```
//!
//! becomes
//!
//! ```rust,ignore
//! match x {
//! Foo(y) | Bar(y) | Baz(y) => match y {
//! Bubbles(z) | Buttercup(z) | Blossom(z) => do_stuff_with(z)
//! },
//! _ => {}
//! }
//! ```
//!
//! Note that if you use a plain `let`, then `if_chain!` assumes that the
//! pattern is *irrefutable* (always matches) and doesn't add a fallback branch.
#![cfg_attr(not(test), no_std)]
/// Macro for writing nested `if let` expressions.
///
/// See the crate documentation for information on how to use this macro.
#[macro_export(local_inner_macros)]
macro_rules! if_chain {
($($tt:tt)*) => {
__if_chain! { @init () $($tt)* }
};
}
#[doc(hidden)]
#[macro_export(local_inner_macros)]
macro_rules! __if_chain {
// Expand with both a successful case and a fallback
(@init ($($tt:tt)*) then { $($then:tt)* } else { $($other:tt)* }) => {
__if_chain! { @expand { $($other)* } $($tt)* then { $($then)* } }
};
// Expand with no fallback
(@init ($($tt:tt)*) then { $($then:tt)* }) => {
__if_chain! { @expand {} $($tt)* then { $($then)* } }
};
// Munch everything until either of the arms above can be matched.
// Munched tokens are placed into `$($tt)*`
(@init ($($tt:tt)*) $head:tt $($tail:tt)*) => {
__if_chain! { @init ($($tt)* $head) $($tail)* }
};
// `let` with a single pattern
(@expand { $($other:tt)* } let $pat:pat = $expr:expr; $($tt:tt)+) => {
{
let $pat = $expr;
__if_chain! { @expand { $($other)* } $($tt)+ }
}
};
// `let` with a single identifier and a type hint
(@expand { $($other:tt)* } let $ident:ident: $ty:ty = $expr:expr; $($tt:tt)+) => {
{
let $ident: $ty = $expr;
__if_chain! { @expand { $($other)* } $($tt)+ }
}
};
// `let` with multiple patterns
(@expand { $($other:tt)* } let $pat1:pat | $($pat:pat)|+ = $expr:expr; $($tt:tt)+) => {
match $expr {
$pat1 | $($pat)|+ => { __if_chain! { @expand { $($other)* } $($tt)+ } }
}
};
// `if let` with a single pattern
(@expand {} if let $pat:pat = $expr:expr; $($tt:tt)+) => {
if let $pat = $expr {
__if_chain! { @expand {} $($tt)+ }
}
};
// `if let` with a single pattern and a fallback
(@expand { $($other:tt)+ } if let $pat:pat = $expr:expr; $($tt:tt)+) => {
if let $pat = $expr {
__if_chain! { @expand { $($other)+ } $($tt)+ }
} else {
$($other)+
}
};
// `if let` with multiple matterns and a fallback (if present)
(@expand { $($other:tt)* } if let $pat1:pat | $($pat:pat)|+ = $expr:expr; $($tt:tt)+) => {
match $expr {
$pat1 | $($pat)|+ => { __if_chain! { @expand { $($other)* } $($tt)+ } },
_ => { $($other)* }
}
};
// `if` with a successful case
(@expand {} if $expr:expr; $($tt:tt)+) => {
if $expr {
__if_chain! { @expand {} $($tt)+ }
}
};
// `if` with both a successful case and a fallback
(@expand { $($other:tt)+ } if $expr:expr; $($tt:tt)+) => {
if $expr {
__if_chain! { @expand { $($other)+ } $($tt)+ }
} else {
$($other)+
}
};
// Final macro call
(@expand { $($other:tt)* } then { $($then:tt)* }) => {
$($then)*
};
}
#[cfg(test)]
mod tests {
#[test]
fn simple() {
let x: Option<Result<Option<String>, (u32, u32)>> = Some(Err((41, 42)));
let mut success = false;
if_chain! {
if let Some(y) = x;
if let Err(z) = y;
let (_, b) = z;
if b == 42;
then { success = true; }
}
assert!(success);
}
#[test]
fn empty() {
let success;
if_chain! {
then { success = true; }
}
assert!(success);
}
#[test]
fn empty_with_else() {
let success;
if_chain! {
then { success = true; }
else { unreachable!(); }
}
assert!(success);
}
#[test]
fn if_let_multiple_patterns() {
#[derive(Copy, Clone)]
enum Robot { Nano, Biscuit1, Biscuit2 }
for &(robot, expected) in &[
(Robot::Nano, false),
(Robot::Biscuit1, true),
(Robot::Biscuit2, true),
] {
let is_biscuit = if_chain! {
if let Robot::Biscuit1 | Robot::Biscuit2 = robot;
then { true } else { false }
};
assert_eq!(is_biscuit, expected);
}
}
#[test]
fn let_multiple_patterns() {
let x: Result<u32, u32> = Ok(42);
if_chain! {
let Ok(x) | Err(x) = x;
then { assert_eq!(x, 42); }
else { panic!(); }
}
}
#[test]
fn let_type_annotation_patterns() {
let mut x = 1;
if_chain! {
if x > 0;
let y: u32 = 2;
then { x += y; }
else { x += 1; }
}
assert_eq!(x, 3);
}
}