wasmflow_macros/
lib.rs

1#![doc(html_logo_url = "https://avatars.githubusercontent.com/u/104781277?s=96&v=4")]
2#![doc = include_str!("../README.md")]
3// !!START_LINTS
4// Wasmflow lints
5// Do not change anything between the START_LINTS and END_LINTS line.
6// This is automatically generated. Add exceptions after this section.
7#![deny(
8  clippy::expect_used,
9  clippy::explicit_deref_methods,
10  clippy::option_if_let_else,
11  clippy::await_holding_lock,
12  clippy::cloned_instead_of_copied,
13  clippy::explicit_into_iter_loop,
14  clippy::flat_map_option,
15  clippy::fn_params_excessive_bools,
16  clippy::implicit_clone,
17  clippy::inefficient_to_string,
18  clippy::large_types_passed_by_value,
19  clippy::manual_ok_or,
20  clippy::map_flatten,
21  clippy::map_unwrap_or,
22  clippy::must_use_candidate,
23  clippy::needless_for_each,
24  clippy::needless_pass_by_value,
25  clippy::option_option,
26  clippy::redundant_else,
27  clippy::semicolon_if_nothing_returned,
28  clippy::too_many_lines,
29  clippy::trivially_copy_pass_by_ref,
30  clippy::unnested_or_patterns,
31  clippy::future_not_send,
32  clippy::useless_let_if_seq,
33  clippy::str_to_string,
34  clippy::inherent_to_string,
35  clippy::let_and_return,
36  clippy::string_to_string,
37  clippy::try_err,
38  clippy::if_then_some_else_none,
39  bad_style,
40  clashing_extern_declarations,
41  const_err,
42  dead_code,
43  deprecated,
44  explicit_outlives_requirements,
45  improper_ctypes,
46  invalid_value,
47  missing_copy_implementations,
48  missing_debug_implementations,
49  mutable_transmutes,
50  no_mangle_generic_items,
51  non_shorthand_field_patterns,
52  overflowing_literals,
53  path_statements,
54  patterns_in_fns_without_body,
55  private_in_public,
56  trivial_bounds,
57  trivial_casts,
58  trivial_numeric_casts,
59  type_alias_bounds,
60  unconditional_recursion,
61  unreachable_pub,
62  unsafe_code,
63  unstable_features,
64  unused,
65  unused_allocation,
66  unused_comparisons,
67  unused_import_braces,
68  unused_parens,
69  unused_qualifications,
70  while_true,
71  missing_docs
72)]
73#![allow(unused_attributes)]
74// !!END_LINTS
75// Add exceptions here
76#![allow()]
77
78#[macro_export]
79/// Test a condition and if it is false, return the supplied error.
80/// It's like an assert! that doesn't panic.
81macro_rules! ensure {
82    ($cond:expr, $msg:literal $(,)?) => {
83        if !$cond {
84            return Err($msg.into());
85        }
86    };
87    ($cond:expr, $err:expr $(,)?) => {
88        if !$cond {
89            return Err($err);
90        }
91    };
92    ($cond:expr, $fmt:expr, $($arg:tt)*) => {
93        if !$cond {
94            return Err(format!($fmt, $($arg)*));
95        }
96    };
97}
98
99#[macro_export]
100/// Test a condition and if it is false, return the supplied error.
101/// It's like an assert! that doesn't panic.
102macro_rules! map_wrapper {
103  ($cond:ident, $t:ty, $($arg:tt)*) => {
104    impl $cond {
105
106      #[must_use]
107      /// Get the value for the requested field.
108      fn get<K: AsRef<str>>(&self, field: K) -> Option<&$t> {
109        self.0.get(field.as_ref())
110      }
111
112      #[must_use]
113      /// Get the value for the requested field.
114      fn contains_key<K: AsRef<str>>(&self, field: K) -> bool {
115        self.0.contains_key(field.as_ref())
116      }
117
118      /// Insert a $t into the inner map.
119      fn insert<K: AsRef<str>>(&mut self, field: K, value: $t) {
120        self.0.insert(field.as_ref().to_owned(), value);
121      }
122
123      $($arg)*
124    }
125  };
126}
127
128#[macro_export]
129/// Test a condition and if it is false, return the supplied error.
130/// It's like an assert! that doesn't panic.
131macro_rules! kv_impl {
132  ($t:ty) => {
133    kv_impl!{$t, pub(self)}
134  };
135  ($t:ty, $v:vis) => {
136    #[must_use]
137    #[allow(unused, unreachable_pub)]
138    /// Get the value for the requested field.
139    $v fn get<K: AsRef<str>>(&self, field: K) -> Option<&$t> {
140      self.0.get(field.as_ref())
141    }
142
143    #[must_use]
144    #[allow(unused, unreachable_pub)]
145    /// Get the value for the requested field.
146    $v fn get_mut<K: AsRef<str>>(&mut self, field: K) -> Option<&mut $t> {
147      self.0.get_mut(field.as_ref())
148    }
149
150    #[must_use]
151    #[allow(unused, unreachable_pub)]
152    /// Get the value for the requested field.
153    $v fn contains_key<K: AsRef<str>>(&self, field: K) -> bool {
154      self.0.contains_key(field.as_ref())
155    }
156
157    /// Insert a $t into the inner map.
158    #[allow(unused, unreachable_pub)]
159    $v fn insert<K: AsRef<str>>(&mut self, field: K, value: $t) {
160      self.0.insert(field.as_ref().to_owned(), value);
161    }
162
163    #[must_use]
164    #[allow(unused, unreachable_pub)]
165    /// Remove a value from the inner Map.
166    $v fn remove(&mut self, key:&str) -> Option<$t> {
167      self.0.remove(key)
168    }
169
170    #[must_use]
171    #[allow(unused, unreachable_pub)]
172    /// Return a list of names in the inner HashMap.
173    $v fn names(&self) -> Vec<String> {
174      self.0.keys().cloned().collect()
175    }
176
177    #[must_use]
178    #[allow(unused, unreachable_pub)]
179    /// Return true if the inner HashMap is empty.
180    $v fn is_empty(&self) -> bool {
181      self.0.is_empty()
182    }
183
184    /// Return the inner HashMap.
185    #[must_use]
186    #[allow(unused, unreachable_pub)]
187    $v fn into_inner(self) -> std::collections::HashMap<String, $t> {
188      self.0
189    }
190
191    /// Return a reference to the inner HashMap.
192    #[must_use]
193    #[allow(unused, unreachable_pub)]
194    $v fn inner(&self) -> &std::collections::HashMap<String, $t> {
195      &self.0
196    }
197
198    #[must_use]
199    #[allow(unused, unreachable_pub)]
200    /// Returns the number of fields in the map.
201    $v fn len(&self) -> usize {
202      self.0.len()
203    }
204  };
205}
206
207#[cfg(test)]
208mod test {
209  use anyhow::Result;
210
211  #[test]
212  fn map_wrapper() -> Result<()> {
213    #[derive(Default)]
214    struct MyMap(std::collections::HashMap<String, u32>);
215    impl MyMap {
216      fn custom_len(&self) -> usize {
217        self.0.len() * 10
218      }
219      kv_impl! {u32}
220    }
221
222    let mut map = MyMap::default();
223    map.insert("hey", 0);
224
225    assert_eq!(map.custom_len(), 10);
226    Ok(())
227  }
228}