google_cloud_spanner/
timestamp_bound.rs1use crate::model::transaction_options::read_only::TimestampBound as ReadOnlyTimestampBound;
16use std::fmt::Debug;
17
18#[derive(Clone, Debug)]
35pub struct TimestampBound(pub(crate) ReadOnlyTimestampBound);
36
37impl TimestampBound {
38 pub fn strong() -> Self {
45 Self(ReadOnlyTimestampBound::Strong(true))
46 }
47
48 pub fn read_timestamp<T>(timestamp: T) -> Self
54 where
55 T: TryInto<wkt::Timestamp>,
56 T::Error: Debug,
57 {
58 Self::try_read_timestamp(timestamp).expect("timestamp out of range")
59 }
60
61 pub fn try_read_timestamp<T>(timestamp: T) -> Result<Self, T::Error>
67 where
68 T: TryInto<wkt::Timestamp>,
69 {
70 let timestamp = timestamp.try_into()?;
71 Ok(Self(ReadOnlyTimestampBound::ReadTimestamp(Box::new(
72 timestamp,
73 ))))
74 }
75
76 pub fn min_read_timestamp<T>(timestamp: T) -> Self
83 where
84 T: TryInto<wkt::Timestamp>,
85 T::Error: Debug,
86 {
87 Self::try_min_read_timestamp(timestamp).expect("timestamp out of range")
88 }
89
90 pub fn try_min_read_timestamp<T>(timestamp: T) -> Result<Self, T::Error>
96 where
97 T: TryInto<wkt::Timestamp>,
98 {
99 let timestamp = timestamp.try_into()?;
100 Ok(Self(ReadOnlyTimestampBound::MinReadTimestamp(Box::new(
101 timestamp,
102 ))))
103 }
104
105 pub fn exact_staleness<T>(duration: T) -> Self
112 where
113 T: TryInto<wkt::Duration>,
114 T::Error: Debug,
115 {
116 Self::try_exact_staleness(duration).expect("duration out of range")
117 }
118
119 pub fn try_exact_staleness<T>(duration: T) -> Result<Self, T::Error>
125 where
126 T: TryInto<wkt::Duration>,
127 {
128 let duration = duration.try_into()?;
129 Ok(Self(ReadOnlyTimestampBound::ExactStaleness(Box::new(
130 duration,
131 ))))
132 }
133
134 pub fn max_staleness<T>(duration: T) -> Self
141 where
142 T: TryInto<wkt::Duration>,
143 T::Error: Debug,
144 {
145 Self::try_max_staleness(duration).expect("duration out of range")
146 }
147
148 pub fn try_max_staleness<T>(duration: T) -> Result<Self, T::Error>
154 where
155 T: TryInto<wkt::Duration>,
156 {
157 let duration = duration.try_into()?;
158 Ok(Self(ReadOnlyTimestampBound::MaxStaleness(Box::new(
159 duration,
160 ))))
161 }
162}
163
164#[cfg(test)]
165mod tests {
166 use super::*;
167 use std::time::Duration;
168 use time::macros::datetime;
169
170 #[test]
171 fn test_auto_traits() {
172 static_assertions::assert_impl_all!(TimestampBound: Clone, Debug, Send, Sync);
173 }
174
175 #[test]
176 fn test_strong() {
177 let bound = TimestampBound::strong();
178 assert!(matches!(bound.0, ReadOnlyTimestampBound::Strong(true)));
179 }
180
181 #[test]
182 fn test_read_timestamp_methods() {
183 let ts = datetime!(2026-03-09 18:00:00 UTC);
184
185 let read = TimestampBound::read_timestamp(ts);
187 assert!(matches!(
188 read.0,
189 ReadOnlyTimestampBound::ReadTimestamp(ref t) if t.seconds() == ts.unix_timestamp() && t.nanos() == ts.nanosecond() as i32
190 ));
191
192 let try_read = TimestampBound::try_read_timestamp(ts).expect("valid OffsetDateTime");
193 assert!(matches!(
194 try_read.0,
195 ReadOnlyTimestampBound::ReadTimestamp(ref t) if t.seconds() == ts.unix_timestamp() && t.nanos() == ts.nanosecond() as i32
196 ));
197
198 let wkt_ts = wkt::Timestamp::try_from(ts).expect("valid wkt timestamp");
200 let read = TimestampBound::read_timestamp(wkt_ts);
201 assert!(matches!(
202 read.0,
203 ReadOnlyTimestampBound::ReadTimestamp(ref t) if t.seconds() == ts.unix_timestamp() && t.nanos() == ts.nanosecond() as i32
204 ));
205
206 let try_read = TimestampBound::try_read_timestamp(wkt_ts).expect("valid wkt timestamp");
207 assert!(matches!(
208 try_read.0,
209 ReadOnlyTimestampBound::ReadTimestamp(ref t) if t.seconds() == ts.unix_timestamp() && t.nanos() == ts.nanosecond() as i32
210 ));
211
212 let system_time = std::time::SystemTime::from(ts);
214 let read = TimestampBound::read_timestamp(system_time);
215 assert!(matches!(
216 read.0,
217 ReadOnlyTimestampBound::ReadTimestamp(ref t) if t.seconds() == ts.unix_timestamp() && t.nanos() == ts.nanosecond() as i32
218 ));
219
220 let try_read = TimestampBound::try_read_timestamp(system_time).expect("valid SystemTime");
221 assert!(matches!(
222 try_read.0,
223 ReadOnlyTimestampBound::ReadTimestamp(ref t) if t.seconds() == ts.unix_timestamp() && t.nanos() == ts.nanosecond() as i32
224 ));
225 }
226
227 #[test]
228 fn test_min_read_timestamp_methods() {
229 let ts = datetime!(2026-03-09 18:00:00 UTC);
230
231 let min_read = TimestampBound::min_read_timestamp(ts);
233 assert!(matches!(
234 min_read.0,
235 ReadOnlyTimestampBound::MinReadTimestamp(ref t) if t.seconds() == ts.unix_timestamp() && t.nanos() == ts.nanosecond() as i32
236 ));
237
238 let try_min_read =
239 TimestampBound::try_min_read_timestamp(ts).expect("valid OffsetDateTime");
240 assert!(matches!(
241 try_min_read.0,
242 ReadOnlyTimestampBound::MinReadTimestamp(ref t) if t.seconds() == ts.unix_timestamp() && t.nanos() == ts.nanosecond() as i32
243 ));
244
245 let wkt_ts = wkt::Timestamp::try_from(ts).expect("valid wkt timestamp");
247 let min_read = TimestampBound::min_read_timestamp(wkt_ts);
248 assert!(matches!(
249 min_read.0,
250 ReadOnlyTimestampBound::MinReadTimestamp(ref t) if t.seconds() == ts.unix_timestamp() && t.nanos() == ts.nanosecond() as i32
251 ));
252
253 let try_min_read =
254 TimestampBound::try_min_read_timestamp(wkt_ts).expect("valid wkt timestamp");
255 assert!(matches!(
256 try_min_read.0,
257 ReadOnlyTimestampBound::MinReadTimestamp(ref t) if t.seconds() == ts.unix_timestamp() && t.nanos() == ts.nanosecond() as i32
258 ));
259
260 let system_time = std::time::SystemTime::from(ts);
262 let min_read = TimestampBound::min_read_timestamp(system_time);
263 assert!(matches!(
264 min_read.0,
265 ReadOnlyTimestampBound::MinReadTimestamp(ref t) if t.seconds() == ts.unix_timestamp() && t.nanos() == ts.nanosecond() as i32
266 ));
267
268 let try_min_read =
269 TimestampBound::try_min_read_timestamp(system_time).expect("valid SystemTime");
270 assert!(matches!(
271 try_min_read.0,
272 ReadOnlyTimestampBound::MinReadTimestamp(ref t) if t.seconds() == ts.unix_timestamp() && t.nanos() == ts.nanosecond() as i32
273 ));
274 }
275
276 #[test]
277 fn test_exact_staleness_methods() {
278 let d = Duration::from_secs(60);
279
280 let exact = TimestampBound::exact_staleness(d);
282 assert!(matches!(
283 exact.0,
284 ReadOnlyTimestampBound::ExactStaleness(ref t) if t.seconds() == 60 && t.nanos() == 0
285 ));
286
287 let try_exact = TimestampBound::try_exact_staleness(d).expect("valid std::time::Duration");
288 assert!(matches!(
289 try_exact.0,
290 ReadOnlyTimestampBound::ExactStaleness(ref t) if t.seconds() == 60 && t.nanos() == 0
291 ));
292
293 let wkt_d = wkt::Duration::try_from(d).expect("valid wkt duration");
295 let exact = TimestampBound::exact_staleness(wkt_d);
296 assert!(matches!(
297 exact.0,
298 ReadOnlyTimestampBound::ExactStaleness(ref t) if t.seconds() == 60 && t.nanos() == 0
299 ));
300
301 let try_exact = TimestampBound::try_exact_staleness(wkt_d).expect("valid wkt::Duration");
302 assert!(matches!(
303 try_exact.0,
304 ReadOnlyTimestampBound::ExactStaleness(ref t) if t.seconds() == 60 && t.nanos() == 0
305 ));
306 }
307
308 #[test]
309 fn test_max_staleness_methods() {
310 let d = Duration::from_secs(120);
311
312 let max = TimestampBound::max_staleness(d);
314 assert!(matches!(
315 max.0,
316 ReadOnlyTimestampBound::MaxStaleness(ref t) if t.seconds() == 120 && t.nanos() == 0
317 ));
318
319 let try_max = TimestampBound::try_max_staleness(d).expect("valid std::time::Duration");
320 assert!(matches!(
321 try_max.0,
322 ReadOnlyTimestampBound::MaxStaleness(ref t) if t.seconds() == 120 && t.nanos() == 0
323 ));
324
325 let wkt_d = wkt::Duration::try_from(d).expect("valid wkt duration");
327 let max = TimestampBound::max_staleness(wkt_d);
328 assert!(matches!(
329 max.0,
330 ReadOnlyTimestampBound::MaxStaleness(ref t) if t.seconds() == 120 && t.nanos() == 0
331 ));
332
333 let try_max = TimestampBound::try_max_staleness(wkt_d).expect("valid wkt::Duration");
334 assert!(matches!(
335 try_max.0,
336 ReadOnlyTimestampBound::MaxStaleness(ref t) if t.seconds() == 120 && t.nanos() == 0
337 ));
338 }
339}