impl<'a> Eq for EncodedDat<'a> {}
+pub type OwnedDatum = Datum<RawString>;
+pub type BorrowedDatum<'a> = Datum<&'a RawStr>;
+
/// The value of a [Variable](crate::dictionary::Variable).
#[derive(Clone)]
-pub enum Datum<B>
-where
- B: Borrow<RawStr>,
-{
+pub enum Datum<B> {
/// A numeric value.
Number(
/// A number, or `None` for the system-missing value.
impl<B> Debug for Datum<B>
where
- B: Borrow<RawStr> + Debug,
+ B: Debug,
{
fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
match self {
impl<B> Serialize for Datum<B>
where
- B: Borrow<RawStr> + Serialize,
+ B: Serialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
}
}
-impl<B> PartialEq for Datum<B>
+impl<B, B2> PartialEq<Datum<B2>> for Datum<B>
where
B: Borrow<RawStr>,
+ B2: Borrow<RawStr>,
{
- fn eq(&self, other: &Self) -> bool {
+ fn eq(&self, other: &Datum<B2>) -> bool {
match (self, other) {
- (Self::Number(Some(l0)), Self::Number(Some(r0))) => {
+ (Self::Number(Some(l0)), Datum::Number(Some(r0))) => {
OrderedFloat(*l0) == OrderedFloat(*r0)
}
- (Self::Number(None), Self::Number(None)) => true,
- (Self::String(l0), Self::String(r0)) => l0.borrow() == r0.borrow(),
+ (Self::Number(None), Datum::Number(None)) => true,
+ (Self::String(l0), Datum::String(r0)) => l0.borrow() == r0.borrow(),
_ => false,
}
}
impl<B> Eq for Datum<B> where B: Borrow<RawStr> {}
-impl<B> PartialOrd for Datum<B>
+impl<B, B2> PartialOrd<Datum<B2>> for Datum<B>
where
B: Borrow<RawStr>,
+ B2: Borrow<RawStr>,
{
- fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
- Some(self.cmp(other))
+ fn partial_cmp(&self, other: &Datum<B2>) -> Option<Ordering> {
+ Some(match (self, other) {
+ (Self::Number(a), Datum::Number(b)) => match (a, b) {
+ (None, None) => Ordering::Equal,
+ (None, Some(_)) => Ordering::Less,
+ (Some(_), None) => Ordering::Greater,
+ (Some(a), Some(b)) => a.total_cmp(b),
+ },
+ (Self::Number(_), Datum::String(_)) => Ordering::Less,
+ (Self::String(_), Datum::Number(_)) => Ordering::Greater,
+ (Self::String(a), Datum::String(b)) => a.borrow().cmp(b.borrow()),
+ })
}
}
B: Borrow<RawStr>,
{
fn cmp(&self, other: &Self) -> Ordering {
- match (self, other) {
- (Self::Number(a), Self::Number(b)) => match (a, b) {
- (None, None) => Ordering::Equal,
- (None, Some(_)) => Ordering::Less,
- (Some(_), None) => Ordering::Greater,
- (Some(a), Some(b)) => a.total_cmp(b),
- },
- (Self::Number(_), Self::String(_)) => Ordering::Less,
- (Self::String(_), Self::Number(_)) => Ordering::Greater,
- (Self::String(a), Self::String(b)) => a.borrow().cmp(b.borrow()),
- }
+ self.partial_cmp(other).unwrap()
}
}
}
}
-impl<B> Datum<B>
-where
- B: Borrow<RawStr>,
-{
+impl<B> Datum<B> {
/// Constructs a new numerical [Datum] for the system-missing value.
pub const fn sysmis() -> Self {
Self::Number(None)
}
}
+ /// Returns the [VarType] corresponding to this datum.
+ pub fn var_type(&self) -> VarType {
+ match self {
+ Self::Number(_) => VarType::Numeric,
+ Self::String(_) => VarType::String,
+ }
+ }
+}
+
+impl<B> Datum<B>
+where
+ B: Borrow<RawStr>,
+{
/// Returns the string inside this datum, or `None` if this is a numeric
/// datum.
pub fn as_string(&self) -> Option<&RawStr> {
}
}
- /// Returns the [VarType] corresponding to this datum.
- pub fn var_type(&self) -> VarType {
- match self {
- Self::Number(_) => VarType::Numeric,
- Self::String(_) => VarType::String,
- }
- }
-
/// Returns the [VarWidth] corresponding to this datum.
pub fn width(&self) -> VarWidth {
match self {
Self::String(s) => VarWidth::String(s.borrow().len().try_into().unwrap()),
}
}
+
+ /// Compares this datum and `other` for equality, ignoring trailing ASCII
+ /// spaces in either, if they are both strings, for the purpose of
+ /// comparison.
+ pub fn eq_ignore_trailing_spaces<B2>(&self, other: &Datum<B2>) -> bool
+ where
+ B2: Borrow<RawStr>,
+ {
+ match (self, other) {
+ (Self::String(a), Datum::String(b)) => a.borrow().eq_ignore_trailing_spaces(b.borrow()),
+ _ => self == other,
+ }
+ }
}
impl Datum<RawString> {
}
}
- /// Compares this datum and `other` for equality, ignoring trailing ASCII
- /// spaces in either, if they are both strings, for the purpose of
- /// comparison.
- pub fn eq_ignore_trailing_spaces<B2>(&self, other: &Datum<RawString>) -> bool {
- match (self, other) {
- (Self::String(a), Self::String(b)) => a.eq_ignore_trailing_spaces(b),
- _ => self == other,
- }
- }
-
/// Removes trailing ASCII spaces from this datum, if it is a string.
pub fn trim_end(&mut self) {
match self {
use crate::{
calendar::{days_in_month, is_leap_year},
- data::{Datum, EncodedStr},
+ data::{Datum, EncodedStr, OwnedDatum},
endian::Endian,
format::{
parse::{ParseError, ParseErrorKind, Sign},
.with_settings(&settings)
.parse(&formatted)
.unwrap();
- assert_eq!(parsed, Datum::Number(Some(expected as f64)));
+ assert_eq!(parsed, OwnedDatum::Number(Some(expected as f64)));
}
}
assert_eq!(parsed, expected);
}
}
- assert_eq!(parser.parse(".").unwrap(), Datum::Number(None));
- assert_eq!(parser.parse("",).unwrap(), Datum::Number(None));
+ assert_eq!(parser.parse(".").unwrap(), OwnedDatum::Number(None));
+ assert_eq!(parser.parse("",).unwrap(), OwnedDatum::Number(None));
}
#[test]
assert_eq!(parsed, number as f64, "formatted as {formatted:?}");
}
}
- assert_eq!(parser.parse(".").unwrap(), Datum::Number(None));
+ assert_eq!(parser.parse(".").unwrap(), OwnedDatum::Number(None));
let parser = Type::Z.parser(UTF_8).with_implied_decimals(1);
for number in -999i32..=999 {