1use crate::TryLock;
6use pdk_core::classy::extract::context::ConfigureContext;
7use pdk_core::classy::extract::{Extract, FromContext};
8use pdk_core::classy::{Clock, SharedData};
9use pdk_core::policy_context::api::Metadata;
10use std::convert::Infallible;
11use std::rc::Rc;
12use std::time::Duration;
13
14const DEFAULT_EXPIRATION: Duration = Duration::from_secs(60);
15
16pub struct LockBuilder {
18 clock: Rc<dyn Clock>,
19 shared_data: Rc<dyn SharedData>,
20 expiration: Duration,
21 prefix: String,
22}
23
24impl FromContext<ConfigureContext> for LockBuilder {
37 type Error = Infallible;
38
39 fn from_context(context: &ConfigureContext) -> Result<Self, Self::Error> {
40 let clock: Rc<dyn Clock> = context.extract()?;
41 let shared_data: Rc<dyn SharedData> = context.extract()?;
42 let metadata: Metadata = context.extract()?;
43 Ok(LockBuilder {
44 clock,
45 shared_data,
46 expiration: DEFAULT_EXPIRATION,
47 prefix: format!(
48 "isolated-lock-{}-{}",
49 metadata.policy_metadata.policy_name, metadata.policy_metadata.policy_namespace
50 ),
51 })
52 }
53}
54
55impl LockBuilder {
56 #[allow(clippy::new_ret_no_self)]
62 pub fn new(&self, lock_id: String) -> LockBuilderInstance {
63 LockBuilderInstance {
64 clock: Rc::clone(&self.clock),
65 shared_data: Rc::clone(&self.shared_data),
66 expiration: self.expiration,
67 prefix: self.prefix.clone(),
68 key: lock_id,
69 }
70 }
71}
72
73pub struct LockBuilderInstance {
76 clock: Rc<dyn Clock>,
77 shared_data: Rc<dyn SharedData>,
78 expiration: Duration,
79 prefix: String,
80 key: String,
81}
82
83impl LockBuilderInstance {
84 pub fn expiration(mut self, expiration: Duration) -> Self {
87 self.expiration = expiration;
88 self
89 }
90
91 pub fn shared(mut self) -> Self {
94 self.prefix = "shared-lock".to_string();
95 self
96 }
97
98 pub fn build(self) -> TryLock {
100 TryLock::new(
101 format!("{}-{}", self.prefix, self.key),
102 self.expiration,
103 self.clock,
104 self.shared_data,
105 )
106 }
107}