X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=rust%2Fsrc%2Fformat.rs;h=34798ed65af54c5072f717de94381fdd74827414;hb=3aadbf4b5339a293cafa3b0e5f0529d8818ad81d;hp=857c05e67f16490ea4dc7b7ac55ee3e21816469a;hpb=1bb9fba87b1caa260ea79c40c7dcdddf55cad33a;p=pspp diff --git a/rust/src/format.rs b/rust/src/format.rs index 857c05e67f..34798ed65a 100644 --- a/rust/src/format.rs +++ b/rust/src/format.rs @@ -5,11 +5,14 @@ use std::{ use thiserror::Error as ThisError; -use crate::raw::{VarType, self}; +use crate::{ + cooked::VarWidth, + raw::{self, VarType}, +}; #[derive(ThisError, Debug)] pub enum Error { - #[error("Unknown format type {value}")] + #[error("Unknown format type {value}.")] UnknownFormat { value: u16 }, #[error("Output format {0} specifies width {}, but {} requires an even width.", .0.w, .0.format)] @@ -36,12 +39,6 @@ pub enum Error { #[error("Numeric variable is not compatible with string format {0}.")] UnnamedVariableNotCompatibleWithStringFormat(Format), - #[error("String variable {variable} is not compatible with numeric format {format}.")] - NamedVariableNotCompatibleWithNumericFormat { variable: String, format: Format }, - - #[error("Numeric variable {variable} is not compatible with string format {format}.")] - NamedVariableNotCompatibleWithStringFormat { variable: String, format: Format }, - #[error("String variable {variable} with width {width} is not compatible with format {bad_spec}. Use format {good_spec} instead.")] NamedStringVariableBadSpecWidth { variable: String, @@ -173,8 +170,6 @@ pub enum Format { AHex, } -pub const MAX_STRING: Width = 32767; - pub type Width = u16; pub type SignedWidth = i16; @@ -185,8 +180,8 @@ impl Format { match self { Self::P | Self::PK | Self::PIBHex | Self::RBHex => 16, Self::IB | Self::PIB | Self::RB => 8, - Self::A => MAX_STRING, - Self::AHex => MAX_STRING * 2, + Self::A => 32767, + Self::AHex => 32767 * 2, _ => 40, } } @@ -305,36 +300,20 @@ impl Format { pub fn var_type(self) -> VarType { match self { Self::A | Self::AHex => VarType::String, - _ => VarType::Number, + _ => VarType::Numeric, } } - pub fn check_type_compatibility( - self, - variable: Option<&str>, - var_type: VarType, - ) -> Result<(), Error> { + /// Checks whether this format is valid for a variable with the given + /// `var_type`. + pub fn check_type_compatibility(self, var_type: VarType) -> Result<(), Error> { let my_type = self.var_type(); match (my_type, var_type) { - (VarType::Number, VarType::String) => { - if let Some(variable) = variable { - Err(Error::NamedVariableNotCompatibleWithNumericFormat { - variable: variable.into(), - format: self, - }) - } else { - Err(Error::UnnamedVariableNotCompatibleWithNumericFormat(self)) - } + (VarType::Numeric, VarType::String) => { + Err(Error::UnnamedVariableNotCompatibleWithNumericFormat(self)) } - (VarType::String, VarType::Number) => { - if let Some(variable) = variable { - Err(Error::NamedVariableNotCompatibleWithStringFormat { - variable: variable.into(), - format: self, - }) - } else { - Err(Error::UnnamedVariableNotCompatibleWithStringFormat(self)) - } + (VarType::String, VarType::Numeric) => { + Err(Error::UnnamedVariableNotCompatibleWithStringFormat(self)) } _ => Ok(()), } @@ -404,10 +383,18 @@ impl Spec { self.d } - pub fn default_for_width(w: Width) -> Self { - match w { - 0 => Spec { format: Format::F, w: 8, d: 2 }, - _ => Spec { format: Format::A, w: w, d: 0 }, + pub fn default_for_width(var_width: VarWidth) -> Self { + match var_width { + VarWidth::Numeric => Spec { + format: Format::F, + w: 8, + d: 2, + }, + VarWidth::String(w) => Spec { + format: Format::A, + w, + d: 0, + }, } } @@ -425,11 +412,11 @@ impl Spec { Self { format, w, d } } - pub fn var_width(self) -> Width { + pub fn var_width(self) -> VarWidth { match self.format { - Format::A => self.w, - Format::AHex => self.w / 2, - _ => 0, + Format::A => VarWidth::String(self.w), + Format::AHex => VarWidth::String(self.w / 2), + _ => VarWidth::Numeric, } } @@ -437,33 +424,30 @@ impl Spec { self.format.var_type() } - pub fn check_width_compatibility(self, variable: Option<&str>, w: Width) -> Result { - self.format.check_type_compatibility(variable, self.var_type())?; - let expected_width = self.var_width(); - if w != expected_width { - let bad_spec = self; - let good_spec = if self.format == Format::A { - Spec { w, ..self } - } else { - Spec { w: w * 2, ..self } - }; - if let Some(variable) = variable { - Err(Error::NamedStringVariableBadSpecWidth { - variable: variable.into(), - width: w, - bad_spec, - good_spec, - }) - } else { - Err(Error::UnnamedStringVariableBadSpecWidth { + /// Checks whether this format specification is valid for a variable with + /// width `var_width`. + pub fn check_width_compatibility(self, var_width: VarWidth) -> Result { + // Verify that the format is right for the variable's type. + self.format + .check_type_compatibility(var_width.into())?; + + if let VarWidth::String(w) = var_width { + if var_width != self.var_width() { + let bad_spec = self; + let good_spec = if self.format == Format::A { + Spec { w, ..self } + } else { + Spec { w: w * 2, ..self } + }; + return Err(Error::UnnamedStringVariableBadSpecWidth { width: w, bad_spec, good_spec, - }) + }); } - } else { - Ok(self) } + + Ok(self) } }