1use hitbox::{
4 CachePolicy, CacheableRequest, Extractor, KeyPart, Predicate, RequestCachePolicy,
5 predicate::PredicateResult,
6};
7
8use crate::KeyExtract;
9
10#[derive(Clone, Debug)]
19pub struct Arg<T> {
20 name: &'static str,
21 value: T,
22}
23
24impl<T> Arg<T> {
25 pub fn new(name: &'static str, value: T) -> Self {
27 Self { name, value }
28 }
29
30 pub fn value(&self) -> &T {
32 &self.value
33 }
34
35 pub fn into_value(self) -> T {
37 self.value
38 }
39}
40
41impl<T: KeyExtract> KeyExtract for Arg<T> {
42 fn extract(&self) -> Vec<KeyPart> {
43 let inner = self.value.extract();
44 if inner.len() == 1 {
45 inner.into_iter().map(|p| p.with_key(self.name)).collect()
46 } else {
47 inner.into_iter().map(|p| p.prefixed(self.name)).collect()
48 }
49 }
50}
51
52#[derive(Clone, Debug)]
60pub struct Skipped<T>(T);
61
62impl<T> Skipped<T> {
63 pub fn new(value: T) -> Self {
65 Self(value)
66 }
67
68 pub fn value(&self) -> &T {
70 &self.0
71 }
72
73 pub fn into_value(self) -> T {
75 self.0
76 }
77}
78
79impl<T> KeyExtract for Skipped<T> {
80 fn extract(&self) -> Vec<KeyPart> {
81 vec![]
82 }
83}
84
85#[derive(Clone, Debug)]
91pub struct Args<T>(pub T);
92
93impl<T> Args<T> {
94 pub fn new(inner: T) -> Self {
96 Self(inner)
97 }
98
99 pub fn into_inner(self) -> T {
101 self.0
102 }
103}
104
105macro_rules! impl_cacheable_request_for_args {
108 () => {
109 impl CacheableRequest for Args<()> {
110 async fn cache_policy<P, E>(self, predicates: P, extractors: E) -> RequestCachePolicy<Self>
111 where
112 P: Predicate<Subject = Self> + Send + Sync,
113 E: Extractor<Subject = Self> + Send + Sync,
114 {
115 match predicates.check(self).await {
116 PredicateResult::Cacheable(subject) => {
117 let (subject, key) = extractors.get(subject).await.into_cache_key();
118 CachePolicy::Cacheable(hitbox::CacheablePolicyData::new(key, subject))
119 }
120 PredicateResult::NonCacheable(subject) => CachePolicy::NonCacheable(subject),
121 }
122 }
123 }
124 };
125 ($($T:ident),+) => {
126 impl<$($T: Send + Sync + 'static),+> CacheableRequest for Args<($($T,)+)> {
127 async fn cache_policy<P, E>(self, predicates: P, extractors: E) -> RequestCachePolicy<Self>
128 where
129 P: Predicate<Subject = Self> + Send + Sync,
130 E: Extractor<Subject = Self> + Send + Sync,
131 {
132 match predicates.check(self).await {
133 PredicateResult::Cacheable(subject) => {
134 let (subject, key) = extractors.get(subject).await.into_cache_key();
135 CachePolicy::Cacheable(hitbox::CacheablePolicyData::new(key, subject))
136 }
137 PredicateResult::NonCacheable(subject) => CachePolicy::NonCacheable(subject),
138 }
139 }
140 }
141 };
142}
143
144impl_cacheable_request_for_args!();
145impl_cacheable_request_for_args!(T0);
146impl_cacheable_request_for_args!(T0, T1);
147impl_cacheable_request_for_args!(T0, T1, T2);
148impl_cacheable_request_for_args!(T0, T1, T2, T3);
149impl_cacheable_request_for_args!(T0, T1, T2, T3, T4);
150impl_cacheable_request_for_args!(T0, T1, T2, T3, T4, T5);
151impl_cacheable_request_for_args!(T0, T1, T2, T3, T4, T5, T6);
152impl_cacheable_request_for_args!(T0, T1, T2, T3, T4, T5, T6, T7);
153impl_cacheable_request_for_args!(T0, T1, T2, T3, T4, T5, T6, T7, T8);
154impl_cacheable_request_for_args!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9);
155impl_cacheable_request_for_args!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10);
156impl_cacheable_request_for_args!(T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11);