From: Ben Pfaff Date: Fri, 25 Jul 2025 01:55:12 +0000 (-0700) Subject: start generalizing datum X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=06fa8142a423de49295150f7441f02a502b7d7d8;p=pspp start generalizing datum --- diff --git a/rust/pspp/src/data.rs b/rust/pspp/src/data.rs index 9a84123de8..38510e6b74 100644 --- a/rust/pspp/src/data.rs +++ b/rust/pspp/src/data.rs @@ -73,12 +73,6 @@ impl RawString { EncodedStr::new(&self.0, encoding) } - /// Returns true if this raw string can be resized to `len` bytes without - /// dropping non-space characters. - pub fn is_resizable(&self, new_len: usize) -> bool { - new_len >= self.len() || self.0[new_len..].iter().all(|b| *b == b' ') - } - /// Extends or shortens this [RawString] to exactly `len` bytes. If the /// string needs to be extended, does so by appending spaces. /// @@ -216,6 +210,12 @@ impl RawStr { } } + /// Returns true if this raw string can be resized to `len` bytes without + /// dropping non-space characters. + pub fn is_resizable(&self, new_len: usize) -> bool { + new_len >= self.len() || self.0[new_len..].iter().all(|b| *b == b' ') + } + /// Returns the string's length in bytes. pub fn len(&self) -> usize { self.0.len() @@ -602,7 +602,10 @@ where } } -impl Datum { +impl Datum +where + B: Borrow, +{ /// Constructs a new numerical [Datum] for the system-missing value. pub const fn sysmis() -> Self { Self::Number(None) @@ -619,13 +622,45 @@ impl Datum { /// Returns the string inside this datum, or `None` if this is a numeric /// datum. - pub fn as_string(&self) -> Option<&RawString> { + pub fn as_string(&self) -> Option<&RawStr> { match self { Self::Number(_) => None, - Self::String(s) => Some(s), + Self::String(s) => Some(s.borrow()), + } + } + + /// Returns true if this datum can be resized to the given `width` without + /// loss, which is true only if this datum and `width` are both string or + /// both numeric and, for string widths, if resizing would not drop any + /// non-space characters. + pub fn is_resizable(&self, width: VarWidth) -> bool { + match (self, width) { + (Self::Number(_), VarWidth::Numeric) => true, + (Self::String(s), VarWidth::String(new_width)) => { + s.borrow().is_resizable(new_width as usize) + } + _ => false, + } + } + + /// 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::Number(_) => VarWidth::Numeric, + Self::String(s) => VarWidth::String(s.borrow().len().try_into().unwrap()), } } +} +impl Datum { /// Returns the string inside this datum as a mutable borrow, or `None` if /// this is a numeric datum. pub fn as_string_mut(&mut self) -> Option<&mut RawString> { @@ -642,18 +677,6 @@ impl Datum { } } - /// Returns true if this datum can be resized to the given `width` without - /// loss, which is true only if this datum and `width` are both string or - /// both numeric and, for string widths, if resizing would not drop any - /// non-space characters. - pub fn is_resizable(&self, width: VarWidth) -> bool { - match (self, width) { - (Self::Number(_), VarWidth::Numeric) => true, - (Self::String(s), VarWidth::String(new_width)) => s.is_resizable(new_width as usize), - _ => false, - } - } - /// Resizes this datum to the given `width`. Returns an error, without /// modifying the datum, if [is_resizable](Self::is_resizable) would return /// false. @@ -672,22 +695,6 @@ impl Datum { } } - /// 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::Number(_) => VarWidth::Numeric, - Self::String(s) => VarWidth::String(s.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.