pub trait AsRange {
type PreciseValue: PartialEq + PartialOrd;
type Range;
// Required methods
fn is_precise(&self) -> bool;
fn earliest(&self) -> Result<Self::PreciseValue, Error>;
fn latest(&self) -> Result<Self::PreciseValue, Error>;
fn range(&self) -> Result<Self::Range, Error>;
// Provided method
fn exact(&self) -> Result<Self::PreciseValue, Error> { ... }
}
Expand description
The DICOM protocol accepts date (DA) / time (TM) / date-time (DT) values with null components.
Imprecise values are to be handled as ranges.
This trait is implemented by date / time structures with partial precision.
AsRange::is_precise() method will check if the given value has full precision. If so, it can be converted with AsRange::exact() to a precise value. If not, AsRange::range() will yield a date / time / date-time range.
Please note that precision does not equal validity. A precise ‘YYYYMMDD’ DicomDate can still fail to produce a valid chrono::NaiveDate
§Examples
use chrono::{NaiveDate, NaiveTime};
use dicom_core::value::{AsRange, DicomDate, DicomTime, DateRange, TimeRange};
let dicom_date = DicomDate::from_ym(2010,1)?;
assert_eq!(dicom_date.is_precise(), false);
assert_eq!(
Some(dicom_date.earliest()?),
NaiveDate::from_ymd_opt(2010,1,1)
);
assert_eq!(
Some(dicom_date.latest()?),
NaiveDate::from_ymd_opt(2010,1,31)
);
let dicom_time = DicomTime::from_hm(10,0)?;
assert_eq!(
dicom_time.range()?,
TimeRange::from_start_to_end(NaiveTime::from_hms(10, 0, 0),
NaiveTime::from_hms_micro_opt(10, 0, 59, 999_999).unwrap())?
);
// only a time with 6 digits second fraction is considered precise
assert!(dicom_time.exact().is_err());
let primitive = PrimitiveValue::from("199402");
// This is the fastest way to get to a useful date value, but it fails not only for invalid
// dates but for imprecise ones as well.
assert!(primitive.to_naive_date().is_err());
// Take intermediate steps:
// Retrieve a DicomDate.
// The parser now checks for basic year and month value ranges here.
// But, it would not detect invalid dates like 30th of february etc.
let dicom_date : DicomDate = primitive.to_date()?;
// as we have a valid DicomDate value, let's check if it's precise.
if dicom_date.is_precise(){
// no components are missing, we can proceed by calling .exact()
// which calls the `chrono` library
let precise_date: NaiveDate = dicom_date.exact()?;
}
else{
// day / month are missing, no need to call the expensive .exact() method - it will fail
// retrieve the earliest possible value directly from DicomDate
let earliest: NaiveDate = dicom_date.earliest()?;
// or convert the date to a date range instead
let date_range: DateRange = dicom_date.range()?;
if let Some(start) = date_range.start(){
// the range has a given lower date bound
}
}
Required Associated Types§
type PreciseValue: PartialEq + PartialOrd
type Range
Required Methods§
Sourcefn is_precise(&self) -> bool
fn is_precise(&self) -> bool
returns true if value has all possible date / time components
Sourcefn earliest(&self) -> Result<Self::PreciseValue, Error>
fn earliest(&self) -> Result<Self::PreciseValue, Error>
Returns the earliest possible value from a partial precision structure.
Missing components default to 1 (days, months) or 0 (hours, minutes, …)
If structure contains invalid combination of DateComponent
s, it fails.
Sourcefn latest(&self) -> Result<Self::PreciseValue, Error>
fn latest(&self) -> Result<Self::PreciseValue, Error>
Returns the latest possible value from a partial precision structure.
If structure contains invalid combination of DateComponent
s, it fails.
Provided Methods§
Sourcefn exact(&self) -> Result<Self::PreciseValue, Error>
fn exact(&self) -> Result<Self::PreciseValue, Error>
Returns a corresponding precise value, if the partial precision structure has full accuracy.