From: Ben Pfaff Date: Fri, 25 Jul 2025 14:47:48 +0000 (-0700) Subject: work on datum X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=47af79fc7d0fe6a488fd271487716cbd2d05b107;p=pspp work on datum --- diff --git a/rust/pspp/src/data.rs b/rust/pspp/src/data.rs index 38510e6b74..b907fc513e 100644 --- a/rust/pspp/src/data.rs +++ b/rust/pspp/src/data.rs @@ -498,12 +498,12 @@ impl<'a> PartialEq for EncodedDat<'a> { impl<'a> Eq for EncodedDat<'a> {} +pub type OwnedDatum = Datum; +pub type BorrowedDatum<'a> = Datum<&'a RawStr>; + /// The value of a [Variable](crate::dictionary::Variable). #[derive(Clone)] -pub enum Datum -where - B: Borrow, -{ +pub enum Datum { /// A numeric value. Number( /// A number, or `None` for the system-missing value. @@ -518,7 +518,7 @@ where impl Debug for Datum where - B: Borrow + Debug, + B: Debug, { fn fmt(&self, f: &mut Formatter) -> std::fmt::Result { match self { @@ -531,7 +531,7 @@ where impl Serialize for Datum where - B: Borrow + Serialize, + B: Serialize, { fn serialize(&self, serializer: S) -> Result where @@ -544,17 +544,18 @@ where } } -impl PartialEq for Datum +impl PartialEq> for Datum where B: Borrow, + B2: Borrow, { - fn eq(&self, other: &Self) -> bool { + fn eq(&self, other: &Datum) -> 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, } } @@ -562,12 +563,23 @@ where impl Eq for Datum where B: Borrow {} -impl PartialOrd for Datum +impl PartialOrd> for Datum where B: Borrow, + B2: Borrow, { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) + fn partial_cmp(&self, other: &Datum) -> Option { + 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()), + }) } } @@ -576,17 +588,7 @@ where B: Borrow, { 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() } } @@ -602,10 +604,7 @@ where } } -impl Datum -where - B: Borrow, -{ +impl Datum { /// Constructs a new numerical [Datum] for the system-missing value. pub const fn sysmis() -> Self { Self::Number(None) @@ -620,6 +619,19 @@ where } } + /// Returns the [VarType] corresponding to this datum. + pub fn var_type(&self) -> VarType { + match self { + Self::Number(_) => VarType::Numeric, + Self::String(_) => VarType::String, + } + } +} + +impl Datum +where + B: Borrow, +{ /// Returns the string inside this datum, or `None` if this is a numeric /// datum. pub fn as_string(&self) -> Option<&RawStr> { @@ -643,14 +655,6 @@ where } } - /// 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 { @@ -658,6 +662,19 @@ where 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(&self, other: &Datum) -> bool + where + B2: Borrow, + { + match (self, other) { + (Self::String(a), Datum::String(b)) => a.borrow().eq_ignore_trailing_spaces(b.borrow()), + _ => self == other, + } + } } impl Datum { @@ -695,16 +712,6 @@ impl Datum { } } - /// 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(&self, other: &Datum) -> 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 { diff --git a/rust/pspp/src/format/parse.rs b/rust/pspp/src/format/parse.rs index e423dc98cf..b3fb59a64d 100644 --- a/rust/pspp/src/format/parse.rs +++ b/rust/pspp/src/format/parse.rs @@ -920,7 +920,7 @@ mod test { use crate::{ calendar::{days_in_month, is_leap_year}, - data::{Datum, EncodedStr}, + data::{Datum, EncodedStr, OwnedDatum}, endian::Endian, format::{ parse::{ParseError, ParseErrorKind, Sign}, @@ -1230,7 +1230,7 @@ mod test { .with_settings(&settings) .parse(&formatted) .unwrap(); - assert_eq!(parsed, Datum::Number(Some(expected as f64))); + assert_eq!(parsed, OwnedDatum::Number(Some(expected as f64))); } } @@ -1608,8 +1608,8 @@ mod test { 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] @@ -1698,7 +1698,7 @@ mod 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 {