pub fn with_encoding(self, encoding: &'static Encoding) -> OwnedEncodedString {
EncodedString {
- bytes: self,
+ raw: self,
encoding,
}
}
pub fn as_encoded(&self, encoding: &'static Encoding) -> EncodedString<&BorrowedRawString> {
EncodedString {
encoding,
- bytes: self.borrowed(),
+ raw: self.borrowed(),
}
}
}
impl From<OwnedEncodedString> for OwnedRawString {
fn from(value: OwnedEncodedString) -> Self {
- value.bytes
+ value.raw
}
}
}
}
+pub type OwnedEncodedDatum = EncodedDatum<OwnedEncodedString>;
+pub type BorrowedEncodedDatum<'a> = EncodedDatum<BorrowedEncodedString<'a>>;
+
/// The value of a [Variable](crate::dictionary::Variable), with a string
/// encoding.
#[derive(Clone)]
-pub enum EncodedDatum {
+pub enum EncodedDatum<D = OwnedEncodedString> {
/// A numeric value.
Number(
/// A number, or `None` for the system-missing value.
/// A string value.
String(
/// The value, in the variable's encoding.
- OwnedEncodedString,
+ D,
),
}
-impl EncodedDatum {
- pub fn into_raw(self) -> Datum<OwnedRawString> {
+impl<R> EncodedDatum<EncodedString<R>>
+where
+ R: Borrow<BorrowedRawString>,
+{
+ pub fn into_raw(self) -> Datum<R> {
match self {
EncodedDatum::Number(number) => Datum::Number(number),
- EncodedDatum::String(encoded_string) => Datum::String(encoded_string.into()),
+ EncodedDatum::String(encoded_string) => Datum::String(encoded_string.into_raw()),
}
}
+ /// 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()),
+ }
+ }
+}
+
+impl<D> EncodedDatum<D> {
/// Constructs a new numerical [EncodedDatum] for the system-missing value.
pub const fn sysmis() -> Self {
Self::Number(None)
/// Returns the string inside this datum, or `None` if this is a numeric
/// datum.
- pub fn as_string(&self) -> Option<&OwnedEncodedString> {
+ pub fn as_string(&self) -> Option<&D> {
match self {
Self::Number(_) => None,
Self::String(s) => Some(s),
/// 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 OwnedEncodedString> {
+ pub fn as_string_mut(&mut self) -> Option<&mut D> {
match self {
Self::Number(_) => None,
Self::String(s) => Some(s),
}
}
+ /// Returns the [VarType] corresponding to this datum.
+ pub fn var_type(&self) -> VarType {
+ match self {
+ Self::Number(_) => VarType::Numeric,
+ Self::String(_) => VarType::String,
+ }
+ }
+}
+
+impl EncodedDatum {
/// Resizes this datum to the given `width`. Returns `Ok(())` if
/// successful, if and only if this datum and `width` are both string or
/// both numeric and, for string widths, resizing would not drop any
}
}
- /// 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.
Datum::Number(number) => EncodedDat::Number(*number),
Datum::String(raw_string) => EncodedDat::String(EncodedString {
encoding,
- bytes: raw_string.borrow(),
+ raw: raw_string.borrow(),
}),
}
}
#[derive(Copy, Clone, Debug)]
pub struct EncodedString<R> {
/// The bytes of the string.
- bytes: R,
+ raw: R,
/// The string's encoding.
encoding: &'static Encoding,
R: Borrow<BorrowedRawString>,
{
pub fn new(raw: R, encoding: &'static Encoding) -> Self {
- Self {
- bytes: raw,
- encoding,
- }
+ Self { raw, encoding }
+ }
+
+ pub fn into_raw(self) -> R {
+ self.raw
}
pub fn len(&self) -> usize {
- self.bytes.borrow().len()
+ self.raw.borrow().len()
}
/// Returns this string recoded in UTF-8. Invalid characters will be
/// Returns the bytes in the string, in its encoding.
pub fn as_bytes(&self) -> &[u8] {
- &self.bytes.borrow().0
+ &self.raw.borrow().0
}
/// Compares this string and `other` for equality, ignoring trailing ASCII
R2: Borrow<BorrowedRawString>,
{
self.borrowed()
- .bytes
- .eq_ignore_trailing_spaces(&other.borrowed().bytes)
+ .raw
+ .eq_ignore_trailing_spaces(&other.borrowed().raw)
}
/// Returns the string's [Encoding].
pub fn borrowed<'a>(&'a self) -> EncodedString<&'a BorrowedRawString> {
EncodedString {
encoding: self.encoding,
- bytes: self.bytes.borrow(),
+ raw: self.raw.borrow(),
}
}
/// Returns true if this string is empty.
pub fn is_empty(&self) -> bool {
- self.bytes.borrow().is_empty()
+ self.raw.borrow().is_empty()
}
/// Returns a helper for displaying this string in double quotes.
if !self.as_bytes()[new_len..].iter().all(|b| *b == b' ') {
return Err(());
}
- self.bytes.0.truncate(new_len);
+ self.raw.0.truncate(new_len);
}
Ordering::Equal => (),
- Ordering::Greater => self.bytes.0.extend((self.len()..new_len).map(|_| b' ')),
+ Ordering::Greater => self.raw.0.extend((self.len()..new_len).map(|_| b' ')),
}
Ok(())
}
/// Removes any trailing ASCII spaces.
pub fn trim_end(&mut self) {
- while self.bytes.0.pop_if(|c| *c == b' ').is_some() {}
+ while self.raw.0.pop_if(|c| *c == b' ').is_some() {}
}
}
impl<'a> From<BorrowedEncodedString<'a>> for OwnedEncodedString {
fn from(value: BorrowedEncodedString<'a>) -> Self {
Self {
- bytes: value.bytes.into(),
+ raw: value.raw.into(),
encoding: value.encoding,
}
}
impl From<&str> for OwnedEncodedString {
fn from(value: &str) -> Self {
Self {
- bytes: RawString(value.into()),
+ raw: RawString(value.into()),
encoding: UTF_8,
}
}
impl<'a> From<&'a str> for BorrowedEncodedString<'a> {
fn from(value: &'a str) -> Self {
Self {
- bytes: BorrowedRawString::new(value.as_bytes()),
+ raw: BorrowedRawString::new(value.as_bytes()),
encoding: UTF_8,
}
}
{
fn eq(&self, other: &EncodedString<R2>) -> bool {
// XXX should this consider the encodings?
- self.borrowed().bytes.eq(other.borrowed().bytes)
+ self.borrowed().raw.eq(other.borrowed().raw)
}
}