#[derive(Debug, Clone, PartialEq, Eq)]
pub struct Scope {
pub(crate) prefix: Vec<u8>,
pub(crate) writer: String,
pub(crate) fallback: Option<String>,
}
impl Scope {
#[must_use]
pub fn new(prefix: Vec<u8>, writer: String) -> Self {
Self { prefix, writer, fallback: None }
}
#[must_use]
pub fn with_fallback(mut self, fallback: String) -> Self {
self.fallback = Some(fallback);
self
}
#[must_use]
pub fn prefix(&self) -> &[u8] {
&self.prefix
}
#[must_use]
pub fn writer(&self) -> &str {
&self.writer
}
#[must_use]
pub fn fallback(&self) -> Option<&str> {
self.fallback.as_deref()
}
#[must_use]
pub fn matches(&self, key: &[u8]) -> bool {
key.starts_with(&self.prefix)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn matches_starts_with() {
let s = Scope::new(b"app:billing:".to_vec(), "w1".to_string());
assert!(s.matches(b"app:billing:invoice:42"));
assert!(s.matches(b"app:billing:"));
assert!(!s.matches(b"app:auth:user:1"));
assert!(!s.matches(b"app:billin")); }
#[test]
fn with_fallback_sets_fallback() {
let s = Scope::new(b"p:".to_vec(), "w".to_string()).with_fallback("f".to_string());
assert_eq!(s.fallback(), Some("f"));
}
#[test]
fn empty_prefix_matches_anything() {
let s = Scope::new(Vec::new(), "w".to_string());
assert!(s.matches(b"anything"));
assert!(s.matches(b""));
}
}