Skip to main content

tower_acc/
classifier.rs

1/// Inspects the result of a service call to determine whether the outcome
2/// should be treated as a *server error* for concurrency-control purposes.
3///
4/// By default ([`DefaultClassifier`]), any `Err` variant is considered a server
5/// error. Implement this trait to distinguish client errors, expected failures,
6/// or successful-but-bad responses (e.g. HTTP 503) from true server errors.
7pub trait Classifier<T, E> {
8    fn is_server_error(&self, result: &Result<T, E>) -> bool;
9}
10
11/// Blanket impl: any closure `Fn(&Result<T, E>) -> bool` works as a classifier.
12impl<F, T, E> Classifier<T, E> for F
13where
14    F: Fn(&Result<T, E>) -> bool,
15{
16    fn is_server_error(&self, result: &Result<T, E>) -> bool {
17        (self)(result)
18    }
19}
20
21/// The default classifier: treats every `Err` as a server error.
22///
23/// This preserves the original behavior where `result.is_err()` was used
24/// directly.
25#[derive(Clone, Debug, Default)]
26pub struct DefaultClassifier;
27
28impl<T, E> Classifier<T, E> for DefaultClassifier {
29    fn is_server_error(&self, result: &Result<T, E>) -> bool {
30        result.is_err()
31    }
32}