summaryrefslogtreecommitdiffstats
path: root/src/tools/rust-analyzer/crates/limit
diff options
context:
space:
mode:
Diffstat (limited to 'src/tools/rust-analyzer/crates/limit')
-rw-r--r--src/tools/rust-analyzer/crates/limit/Cargo.toml11
-rw-r--r--src/tools/rust-analyzer/crates/limit/src/lib.rs69
2 files changed, 80 insertions, 0 deletions
diff --git a/src/tools/rust-analyzer/crates/limit/Cargo.toml b/src/tools/rust-analyzer/crates/limit/Cargo.toml
new file mode 100644
index 000000000..893db436d
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/limit/Cargo.toml
@@ -0,0 +1,11 @@
+[package]
+name = "limit"
+version = "0.0.0"
+description = "TBD"
+license = "MIT OR Apache-2.0"
+edition = "2021"
+rust-version = "1.57"
+
+[features]
+tracking = []
+default = ["tracking"]
diff --git a/src/tools/rust-analyzer/crates/limit/src/lib.rs b/src/tools/rust-analyzer/crates/limit/src/lib.rs
new file mode 100644
index 000000000..d6a706a7c
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/limit/src/lib.rs
@@ -0,0 +1,69 @@
+//! limit defines a struct to enforce limits.
+
+#![warn(rust_2018_idioms, unused_lifetimes, semicolon_in_expressions_from_macros)]
+
+#[cfg(feature = "tracking")]
+use std::sync::atomic::AtomicUsize;
+
+/// Represents a struct used to enforce a numerical limit.
+pub struct Limit {
+ upper_bound: usize,
+ #[cfg(feature = "tracking")]
+ max: AtomicUsize,
+}
+
+impl Limit {
+ /// Creates a new limit.
+ #[inline]
+ pub const fn new(upper_bound: usize) -> Self {
+ Self {
+ upper_bound,
+ #[cfg(feature = "tracking")]
+ max: AtomicUsize::new(0),
+ }
+ }
+
+ /// Creates a new limit.
+ #[inline]
+ #[cfg(feature = "tracking")]
+ pub const fn new_tracking(upper_bound: usize) -> Self {
+ Self {
+ upper_bound,
+ #[cfg(feature = "tracking")]
+ max: AtomicUsize::new(1),
+ }
+ }
+
+ /// Gets the underlying numeric limit.
+ #[inline]
+ pub const fn inner(&self) -> usize {
+ self.upper_bound
+ }
+
+ /// Checks whether the given value is below the limit.
+ /// Returns `Ok` when `other` is below `self`, and `Err` otherwise.
+ #[inline]
+ pub fn check(&self, other: usize) -> Result<(), ()> {
+ if other > self.upper_bound {
+ Err(())
+ } else {
+ #[cfg(feature = "tracking")]
+ loop {
+ use std::sync::atomic::Ordering;
+ let old_max = self.max.load(Ordering::Relaxed);
+ if other <= old_max || old_max == 0 {
+ break;
+ }
+ if self
+ .max
+ .compare_exchange_weak(old_max, other, Ordering::Relaxed, Ordering::Relaxed)
+ .is_ok()
+ {
+ eprintln!("new max: {}", other);
+ }
+ }
+
+ Ok(())
+ }
+ }
+}