fn from_str()

in arrow-cast/src/parse.rs [1162:1215]


    fn from_str(s: &str) -> Result<Self, Self::Err> {
        match s.split_once('.') {
            Some((integer, frac))
                if frac.len() <= INTERVAL_PRECISION as usize
                    && !frac.is_empty()
                    && !frac.starts_with('-') =>
            {
                // integer will be "" for values like ".5"
                // and "-" for values like "-.5"
                let explicit_neg = integer.starts_with('-');
                let integer = if integer.is_empty() || integer == "-" {
                    Ok(0)
                } else {
                    integer.parse::<i64>().map_err(|_| {
                        ArrowError::ParseError(format!("Failed to parse {s} as interval amount"))
                    })
                }?;

                let frac_unscaled = frac.parse::<i64>().map_err(|_| {
                    ArrowError::ParseError(format!("Failed to parse {s} as interval amount"))
                })?;

                // scale fractional part by interval precision
                let frac = frac_unscaled * 10_i64.pow(INTERVAL_PRECISION - frac.len() as u32);

                // propagate the sign of the integer part to the fractional part
                let frac = if integer < 0 || explicit_neg {
                    -frac
                } else {
                    frac
                };

                let result = Self { integer, frac };

                Ok(result)
            }
            Some((_, frac)) if frac.starts_with('-') => Err(ArrowError::ParseError(format!(
                "Failed to parse {s} as interval amount"
            ))),
            Some((_, frac)) if frac.len() > INTERVAL_PRECISION as usize => {
                Err(ArrowError::ParseError(format!(
                    "{s} exceeds the precision available for interval amount"
                )))
            }
            Some(_) | None => {
                let integer = s.parse::<i64>().map_err(|_| {
                    ArrowError::ParseError(format!("Failed to parse {s} as interval amount"))
                })?;

                let result = Self { integer, frac: 0 };
                Ok(result)
            }
        }
    }