diff --git a/Cargo.lock b/Cargo.lock
index c29c7bcd52798de204f44c3e9b4ab8c6b18dd82f..b7e6f585782cb2a28d22fca5186e9b68d767dfd9 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -11,6 +11,12 @@ dependencies = [
  "memchr",
 ]
 
+[[package]]
+name = "anyhow"
+version = "1.0.97"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f"
+
 [[package]]
 name = "atty"
 version = "0.2.14"
@@ -62,6 +68,7 @@ dependencies = [
 name = "collective"
 version = "0.1.2"
 dependencies = [
+ "anyhow",
  "clap",
  "figment",
  "lazy_static",
diff --git a/Cargo.toml b/Cargo.toml
index 5fcbcac10ac5bac30bce9495fd10eb905b30c979..2096c2928d9b222fcd636b3721074590088ab13c 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -20,4 +20,7 @@ default = ["config-yaml", "config-json", "thread", "xdg"]
 config-yaml = ["figment/yaml"]
 config-json = ["figment/json"]
 thread = ["lazy_static"]
-xdg = ["dep:xdg"]
\ No newline at end of file
+xdg = ["dep:xdg"]
+
+[dev-dependencies]
+anyhow = "1.0.97"
diff --git a/rustfmt.toml b/rustfmt.toml
index 08e342cbe335ccdb9cf2246c083594a1e4552a13..458b56f90900456e7d76d7fadbb7f2859a0544d2 100644
--- a/rustfmt.toml
+++ b/rustfmt.toml
@@ -1 +1 @@
-format_code_in_doc_comments = true
\ No newline at end of file
+#format_code_in_doc_comments = true
diff --git a/src/rangemap.rs b/src/rangemap.rs
index 8c587167f7f86e5cd9b873a515fdfa449f8a3c46..2d5466856e627469c494a0e348ee45c84f501bc8 100644
--- a/src/rangemap.rs
+++ b/src/rangemap.rs
@@ -1,4 +1,7 @@
-use std::collections::BTreeMap;
+use std::{
+    collections::BTreeMap,
+    ops::{Index, IndexMut},
+};
 
 use thiserror::Error;
 
@@ -57,6 +60,32 @@ impl<RK: Ord + Copy, V> RangeMap<RK, V> {
         Ok(())
     }
 
+    /// Looks up a value at the specified range
+    ///
+    /// If the range does not match, `None` is returned.
+    pub fn get(&self, key: (RK, RK)) -> Option<&V> {
+        if let Some(entry) = self.ranges.get(&key.0) {
+            if entry.0 == key.1 {
+                return Some(&entry.1);
+            }
+        }
+
+        None
+    }
+
+    /// Looks up a mutable value at the specified range
+    ///
+    /// If the range does not match, `None` is returned.
+    pub fn get_mut(&mut self, key: (RK, RK)) -> Option<&mut V> {
+        if let Some(entry) = self.ranges.get_mut(&key.0) {
+            if entry.0 == key.1 {
+                return Some(&mut entry.1);
+            }
+        }
+
+        None
+    }
+
     /// Looks up a value at the specified key
     ///
     /// If the key is within an existing range, the matching value is
@@ -109,6 +138,36 @@ impl<RK: Ord + Copy, V> Default for RangeMap<RK, V> {
     }
 }
 
+impl<RK: Ord + Copy, V> Index<(RK, RK)> for RangeMap<RK, V> {
+    type Output = V;
+
+    fn index(&self, index: (RK, RK)) -> &Self::Output {
+        let entry = self.ranges.index(&index.0);
+
+        if entry.0 != index.1 {
+            panic!("no entry found for key");
+        }
+
+        &entry.1
+    }
+}
+
+impl<RK: Ord + Copy, V> IndexMut<(RK, RK)> for RangeMap<RK, V> {
+    fn index_mut(&mut self, index: (RK, RK)) -> &mut Self::Output {
+        let entry = self.ranges.get_mut(&index.0);
+
+        if let Some(entry) = entry {
+            if entry.0 != index.1 {
+                panic!("no entry found for key");
+            }
+
+            &mut entry.1
+        } else {
+            panic!("no entry found for key")
+        }
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use crate::rangemap::RangeMapError;
@@ -187,4 +246,19 @@ mod tests {
 
         assert_eq!(rm.insert(41, 20, "A"), Err(RangeMapError::InvalidRange));
     }
+
+    #[test]
+    pub fn test_index_mut() -> anyhow::Result<()> {
+        let mut rm: RangeMap<i64, &str> = RangeMap::new();
+
+        rm.insert(1, 200, "hello")?;
+
+        assert_eq!(rm[(1, 200)], "hello");
+
+        rm[(1, 200)] = "world";
+
+        assert_eq!(rm[(1, 200)], "world");
+
+        Ok(())
+    }
 }