with_api/
lib.rs

1#![warn(missing_docs)]
2
3//! # With_api
4//!
5//! A simple set of macros for the ergonomic shinking of scope.
6//! # Examples
7//! ```
8//! # use std::sync::Mutex;
9//! # use std::collections::HashMap;
10//! use with_api::mut_with;
11//!
12//! let protec: Mutex<HashMap<usize, String>> =
13//!     Mutex::new(Vec::new().into_iter().collect());
14//!
15//! // critical section minimised.
16//! mut_with!(protec.lock().unwrap(), |db| {
17//!     let _ = db.insert(42, "meaning of life".to_string());
18//!     assert!(!db.is_empty());
19//! });
20//! ```
21
22#[macro_export]
23/// Owns the value defined in the `with_expr` and evaluates the enclosing block
24macro_rules! with {
25    ($with_expr:expr, |$var:ident| $bl:block) => {{
26        let $var = $with_expr;
27        $bl()
28    }};
29}
30
31#[macro_export]
32/// Borrows the value defined in the `with_expr` and evaluates the enclosing block
33macro_rules! bor_with {
34    ($with_expr:expr, |$var:ident| $bl:block) => {{
35        let $var = &$with_expr;
36        $bl()
37    }};
38}
39
40#[macro_export]
41/// Exclusively borrows the value defined in the `with_expr` and evaluates the enclosing block
42macro_rules! mut_with {
43    ($with_expr:expr, |$var:ident| $bl:block) => {{
44        let mut $var = $with_expr;
45        $bl()
46    }};
47}
48
49#[test]
50fn tuple_access() {
51    fn get_tup() -> (String, usize) {
52        ("meaning of life".to_string(), 42)
53    }
54
55    with!(get_tup(), |tup| {
56        let (description, value) = tup;
57        assert!(!description.is_empty() && value == 42);
58    });
59}
60
61#[test]
62fn borrowed() {
63    use std::collections::HashMap;
64    use std::sync::Mutex;
65
66    let db: Mutex<HashMap<&str, String>> =
67        Mutex::new(vec![("key", "value".to_string())].into_iter().collect());
68
69    bor_with!(db.lock().unwrap(), |db| {
70        assert_eq!(db.get("key").unwrap(), &"value".to_string());
71    });
72}
73
74#[test]
75fn mutated() {
76    use std::fs::File;
77    use std::io::prelude::*;
78    use std::path::Path;
79
80    mut_with!(File::open(Path::new("test/hello.txt")).unwrap(), |file| {
81        let mut buf = String::new();
82        let len = file.read_to_string(&mut buf).unwrap();
83        assert_ne!(len, 0);
84    });
85}