pub struct TimeRangeBound<T> { /* private fields */ }Expand description
A TimeBound object that is valid for a specified range of time.
The range is given as an argument, as in t1..t2.
The range is always treated as inclusive.
Non-invariant: it is possible for the start to be after the end. In that case, it’s simply never valid: either expired, or too soon, or both.
TimeRangeBound<()> aka TimeRange is sometimes used as a representation of a time range,
for example, the return value from TimeBound::bounds.
use web_time_compat::{SystemTime, SystemTimeExt, Duration};
use tor_checkable::{TimeBound, TimeValidityError, timed::TimeRangeBound};
let now = SystemTime::get();
let one_hour = Duration::new(3600, 0);
// This seven is only valid for another hour!
let seven = TimeRangeBound::new(7_u32, ..now+one_hour);
assert_eq!(seven.if_valid_at(&now).unwrap(), 7);
// That consumed the previous seven. Try another one.
let seven = TimeRangeBound::new(7_u32, ..now+one_hour);
assert_eq!(seven.if_valid_at(&(now+2*one_hour)),
Err(TimeValidityError::Expired(one_hour)));
Implementations§
Source§impl<T> TimeRangeBound<T>
impl<T> TimeRangeBound<T>
Sourcepub fn new<U>(obj: T, range: U) -> Selfwhere
U: RangeBounds<SystemTime>,
pub fn new<U>(obj: T, range: U) -> Selfwhere
U: RangeBounds<SystemTime>,
Construct a new TimeRangeBound object from a given object and range.
Note that we do not distinguish between inclusive and
exclusive bounds: x..y and x..=y are treated the same
here - as an inclusive range.
Use TimeRange::new_range to create a TimeRange aka a TimeRangeBound<()>.
Sourcepub fn new_from_start_end(
obj: T,
start: Option<SystemTime>,
end: Option<SystemTime>,
) -> Self
pub fn new_from_start_end( obj: T, start: Option<SystemTime>, end: Option<SystemTime>, ) -> Self
Construct a new TimeRangeBound object from a given object, start time, and end time.
Sourcepub fn extend_start_bound(self, d: Duration) -> Self
pub fn extend_start_bound(self, d: Duration) -> Self
Adjust this time-range bound to tolerate an initial validity time farther in the past.
Sourcepub fn extend_end_bound(self, d: Duration) -> Self
pub fn extend_end_bound(self, d: Duration) -> Self
Adjust this time-range bound to tolerate an expiration time farther in the future.
Sourcepub fn extend_pre_tolerance(self, d: Duration) -> Self
👎Deprecated: use extend_start_bound instead
pub fn extend_pre_tolerance(self, d: Duration) -> Self
use extend_start_bound instead
Deprecated alias for extend_start_bound
Sourcepub fn extend_tolerance(self, d: Duration) -> Self
👎Deprecated: use extend_end_bound instead
pub fn extend_tolerance(self, d: Duration) -> Self
use extend_end_bound instead
Deprecated alias for extend_end_bound
Sourcepub fn dangerously_map<F, U>(self, f: F) -> TimeRangeBound<U>where
F: FnOnce(T) -> U,
pub fn dangerously_map<F, U>(self, f: F) -> TimeRangeBound<U>where
F: FnOnce(T) -> U,
Consume this TimeRangeBound, and return a new one with the same
bounds, applying f to its protected value.
The caller must ensure that f does not make any assumptions about the
timeliness of the protected value, or leak any of its contents in
an inappropriate way.
Sourcepub fn dangerously_into_parts(self) -> (T, TimeRange)
pub fn dangerously_into_parts(self) -> (T, TimeRange)
Consume this TimeRangeBound, and return its underlying time bounds and object.
The caller takes responsibility for making sure that the bounds are actually checked.
Sourcepub fn dangerously_peek(&self) -> &T
pub fn dangerously_peek(&self) -> &T
Return a reference to the inner object of this TimeRangeBound, without checking the time interval.
The caller takes responsibility for making sure that nothing is actually done with the inner object that would rely on the bounds being correct, until the bounds are (eventually) checked.
Sourcepub fn as_ref(&self) -> TimeRangeBound<&T>
pub fn as_ref(&self) -> TimeRangeBound<&T>
Return a TimeRangeBound containing a reference
This can be useful to call methods like .check_valid_at
without consuming the inner T.
Sourcepub fn as_deref(&self) -> TimeRangeBound<&T::Target>where
T: Deref,
pub fn as_deref(&self) -> TimeRangeBound<&T::Target>where
T: Deref,
Return a TimeRangeBound containing a reference to T’s Deref
Sourcepub fn bounds_start_end(&self) -> (Option<SystemTime>, Option<SystemTime>)
pub fn bounds_start_end(&self) -> (Option<SystemTime>, Option<SystemTime>)
Return the underlying time bounds of this object.
Sourcepub fn intersect_bounds(&mut self, bounds: TimeRange)
pub fn intersect_bounds(&mut self, bounds: TimeRange)
Narrow the bounds of self to the overlap with bounds
If the bounds conflict (ie, if the intersection is empty),
simply yields a TimeRangeBound that is never valid.
(This is unlike tor_basic_utils::rangebounds::RangeBoundsExt::intersect
which is implemented for TimeRange via RangeBounds:
intersect insists on returning a well-formed range,
whereas TimeRangeBound can be empty if start > end.)
Sourcepub fn build_intersect<Error, Logic>(logic: Logic) -> Result<Self, Error>
pub fn build_intersect<Error, Logic>(logic: Logic) -> Result<Self, Error>
Process multiple TimeBounds, intersecting their validity ranges
Within logic, TimeBound::unwrap_with can be used,
for unwrapping TimeBounds.
Those time bounds are accumulated within the TimeRangeBoundBuilder,
and when logic returns, they are applied to its result.
This allows multiple time-bound components of (a Tor protocol element) to be conveniently processed into an overall return value.
The API is intended to prevent accidentally forgetting to check
or process one of the time bounds; TimeRangeBoundBuilder is
an alternative to manual use of dangerously_* and intersect.
§CORRECTNESS
Everything that needs to be bound to the time range must be returned
only as part of the return value from logic.
It is the caller’s responsibility not to smuggle out
values whose validity time has not been checked
out via mutable captures in logic, global variables, etc.
Likewise, if logic returns Err, this must mean that callers don’t treat
the data as valid or successful. I.e. Error must really be an error,
and not be used as a way to smuggle out potentially-out-of-time-range data.
§Example
use humantime::parse_rfc3339;
use tor_checkable::{TimeBound as _, TimeRangeBound};
// Fake document. A real document would involve signature verification too.
struct Data {}
struct FakeDoc { data: Data, sig: TimeRangeBound<()>, }
impl FakeDoc {
fn parse(_dummy: &str) -> TimeRangeBound<Self> {
let t = |s| parse_rfc3339(s).unwrap();
let sig = TimeRangeBound::new((), ..=t("2001-01-01T00:00:01Z"));
let doc = FakeDoc { data: Data {}, sig };
TimeRangeBound::new(doc, ..=t("2000-01-01T00:00:01Z"))
}
}
// Demo usage of TimeBoundRangeBuilder, in verification function
fn parse_verify(input: &str) -> Result<TimeRangeBound<Data>, ()> {
let parsed = FakeDoc::parse(input); // real parser would be fallible
TimeRangeBound::build_intersect(move |times| {
let FakeDoc { data, sig } = parsed.unwrap_with(times);
let _: () = sig.unwrap_with(times); // would verify signature too
Ok(data)
})
}
assert_eq!(
parse_verify("dummy").unwrap().bounds().end(),
Some(parse_rfc3339("2000-01-01T00:00:01Z").unwrap()),
);Source§impl TimeRangeBound<()>
impl TimeRangeBound<()>
Sourcepub fn new_range<U>(range: U) -> Selfwhere
U: RangeBounds<SystemTime>,
pub fn new_range<U>(range: U) -> Selfwhere
U: RangeBounds<SystemTime>,
Create a new TimeRange from a std::ops::RangeBounds
Sourcepub fn apply_to<T>(self, t: T) -> TimeRangeBound<T>
pub fn apply_to<T>(self, t: T) -> TimeRangeBound<T>
Applies this TimeRange to a value, protecting it
Sourcepub fn start(&self) -> Option<SystemTime>
pub fn start(&self) -> Option<SystemTime>
Get the start of the validity period
None means there is no start: the object has been valid forever.
Provided only for TimeRange; to call on a general TimeRangeBound<T>,
write .bounds().start().
Sourcepub fn end(&self) -> Option<SystemTime>
pub fn end(&self) -> Option<SystemTime>
Get the end of the validity period
None means there is no end: the object will been valid forever.
This is normally a mistake.
Provided only for TimeRange; to call on a general TimeRangeBound<T>,
write .bounds().end().
Trait Implementations§
Source§impl<T: Clone> Clone for TimeRangeBound<T>
impl<T: Clone> Clone for TimeRangeBound<T>
Source§fn clone(&self) -> TimeRangeBound<T>
fn clone(&self) -> TimeRangeBound<T>
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl<T: Debug> Debug for TimeRangeBound<T>
impl<T: Debug> Debug for TimeRangeBound<T>
Source§impl<T> RangeBounds<SystemTime> for TimeRangeBound<T>
impl<T> RangeBounds<SystemTime> for TimeRangeBound<T>
Source§impl<T> TimeBound for TimeRangeBound<T>
impl<T> TimeBound for TimeRangeBound<T>
Source§type Inner = T
type Inner = T
TimeBound implementationSource§fn check_valid_at(&self, t: &SystemTime) -> Result<(), TimeValidityError>
fn check_valid_at(&self, t: &SystemTime) -> Result<(), TimeValidityError>
Source§fn dangerously_assume_timely(self) -> T
fn dangerously_assume_timely(self) -> T
Source§fn if_valid_at(self, t: &SystemTime) -> Result<Self::Inner, TimeValidityError>
fn if_valid_at(self, t: &SystemTime) -> Result<Self::Inner, TimeValidityError>
Source§fn if_valid_now(self) -> Result<Self::Inner, TimeValidityError>
fn if_valid_now(self) -> Result<Self::Inner, TimeValidityError>
Source§fn unwrap_with(self, builder: &mut TimeRangeBoundBuilder) -> Self::Inner
fn unwrap_with(self, builder: &mut TimeRangeBoundBuilder) -> Self::Inner
Source§fn check_valid_at_opt(
self,
t: Option<SystemTime>,
) -> Result<Self::Inner, TimeValidityError>
fn check_valid_at_opt( self, t: Option<SystemTime>, ) -> Result<Self::Inner, TimeValidityError>
use check_valid_at
Auto Trait Implementations§
impl<T> Freeze for TimeRangeBound<T>where
T: Freeze,
impl<T> RefUnwindSafe for TimeRangeBound<T>where
T: RefUnwindSafe,
impl<T> Send for TimeRangeBound<T>where
T: Send,
impl<T> Sync for TimeRangeBound<T>where
T: Sync,
impl<T> Unpin for TimeRangeBound<T>where
T: Unpin,
impl<T> UnsafeUnpin for TimeRangeBound<T>where
T: UnsafeUnpin,
impl<T> UnwindSafe for TimeRangeBound<T>where
T: UnwindSafe,
Blanket Implementations§
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more