work
[pspp] / rust / src / format.rs
index 81f50ba0ba23946add74c29ebaff9fdbaf4b1ad0..857c05e67f16490ea4dc7b7ac55ee3e21816469a 100644 (file)
@@ -5,7 +5,7 @@ use std::{
 
 use thiserror::Error as ThisError;
 
-use crate::raw::VarType;
+use crate::raw::{VarType, self};
 
 #[derive(ThisError, Debug)]
 pub enum Error {
@@ -175,10 +175,10 @@ pub enum Format {
 
 pub const MAX_STRING: Width = 32767;
 
-type Width = u16;
-type SignedWidth = i16;
+pub type Width = u16;
+pub type SignedWidth = i16;
 
-type Decimals = u8;
+pub type Decimals = u8;
 
 impl Format {
     pub fn max_width(self) -> Width {
@@ -404,6 +404,13 @@ 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 fixed_from(source: &UncheckedSpec) -> Self {
         let UncheckedSpec { format, w, d } = *source;
         let (min, max) = format.width_range().into_inner();
@@ -430,7 +437,7 @@ impl Spec {
         self.format.var_type()
     }
 
-    pub fn check_width_compatibility(self, variable: Option<&str>, w: Width) -> Result<(), Error> {
+    pub fn check_width_compatibility(self, variable: Option<&str>, w: Width) -> Result<Self, Error> {
         self.format.check_type_compatibility(variable, self.var_type())?;
         let expected_width = self.var_width();
         if w != expected_width {
@@ -455,7 +462,7 @@ impl Spec {
                 })
             }
         } else {
-            Ok(())
+            Ok(self)
         }
     }
 }
@@ -553,14 +560,15 @@ pub struct UncheckedSpec {
     pub d: Decimals,
 }
 
-impl TryFrom<u32> for UncheckedSpec {
+impl TryFrom<raw::Spec> for UncheckedSpec {
     type Error = Error;
 
-    fn try_from(source: u32) -> Result<Self, Self::Error> {
-        let raw_format = (source >> 16) as u16;
+    fn try_from(raw: raw::Spec) -> Result<Self, Self::Error> {
+        let raw = raw.0;
+        let raw_format = (raw >> 16) as u16;
         let format = raw_format.try_into()?;
-        let w = ((source >> 8) & 0xff) as Width;
-        let d = (source & 0xff) as Decimals;
+        let w = ((raw >> 8) & 0xff) as Width;
+        let d = (raw & 0xff) as Decimals;
         Ok(Self { format, w, d })
     }
 }