difftreelog
fix align std.format output with standard jsonnet changes
in: master
4 files changed
crates/jrsonnet-evaluator/src/evaluate/operator.rsdiffbeforeafterboth225 if v2.get() < 0.0 {225 if v2.get() < 0.0 {226 bail!("shift by negative exponent")226 bail!("shift by negative exponent")227 }227 }228 let base = v1.truncate_for_bitwise()?;228 let exp = ((v2.get() as i64) & 63) as u32;229 let exp = v2.truncate_for_bitwise()? % 64;230231 if exp >= 1 && base >= (1i64 << (63 - exp as u32)) {232 bail!("left shift would overflow")233 }229 Val::try_num((v1.get() as i64).wrapping_shl(exp) as f64)?234 Val::try_num(base.wrapping_shl(exp as u32) as f64)?230 }235 }231 (Num(v1), Rhs, Num(v2)) => {236 (Num(v1), Rhs, Num(v2)) => {232 if v2.get() < 0.0 {237 if v2.get() < 0.0 {233 bail!("shift by negative exponent")238 bail!("shift by negative exponent")234 }239 }235 let exp = ((v2.get() as i64) & 63) as u32;240 let exp = ((v2.get() as i64) & 63) as u32;236 Val::try_num((v1.get() as i64).wrapping_shr(exp) as f64)?241 Val::try_num(v1.truncate_for_bitwise()?.wrapping_shr(exp) as f64)?237 }242 }238243239 // Bigint X Bigint244 // Bigint X Bigintcrates/jrsonnet-evaluator/src/stdlib/format.rsdiffbeforeafterboth137#[derive(Debug, PartialEq, Eq)]137#[derive(Debug, PartialEq, Eq)]138pub enum Width {138pub enum Width {139 Star,139 Star,140 Fixed(usize),140 Fixed(u16),141}141}142pub fn try_parse_field_width(str: &str) -> ParseResult<'_, Width> {142pub fn try_parse_field_width(str: &str) -> ParseResult<'_, Width> {143 if str.is_empty() {143 if str.is_empty() {147 if bytes[0] == b'*' {147 if bytes[0] == b'*' {148 return Ok((Width::Star, &str[1..]));148 return Ok((Width::Star, &str[1..]));149 }149 }150 let mut out: usize = 0;150 let mut out: u16 = 0;151 let mut digits = 0;151 let mut digits = 0;152 while let Some(digit) = (bytes[digits] as char).to_digit(10) {152 while let Some(digit) = (bytes[digits] as char).to_digit(10) {153 out *= 10;153 out *= 10;154 out += digit as usize;154 out += digit as u16;155 digits += 1;155 digits += 1;156 if digits == bytes.len() {156 if digits == bytes.len() {157 return Err(TruncatedFormatCode);157 return Err(TruncatedFormatCode);299#[inline]299#[inline]300pub fn render_integer(300pub fn render_integer(301 out: &mut String,301 out: &mut String,302 neg: bool,302 iv: f64,303 iv: f64,303 padding: usize,304 padding: u16,304 precision: usize,305 precision: u16,305 blank: bool,306 blank: bool,306 sign: bool,307 sign: bool,307 radix: i64,308 radix: i64,308 prefix: &str,309 zero_prefix: &str,310 prefix_in_padding: bool,309 caps: bool,311 caps: bool,310) {312) {313 debug_assert!(iv >= 0.0, "render_integer receives sign using arg");311 let iv = iv.floor() as i64;314 let iv = iv.floor() as i64;312 // Digit char indexes in reverse order, i.e315 // Digit char indexes in reverse order, i.e313 // for radix = 16 and n = 12f: [15, 2, 1]316 // for radix = 16 and n = 12f: [15, 2, 1]322 }325 }323 nums326 nums324 };327 };325 let neg = iv < 0;326 #[allow(clippy::bool_to_int_with_if)]328 #[allow(clippy::bool_to_int_with_if)]327 let zp = padding.saturating_sub(if neg || blank || sign { 1 } else { 0 });329 let zp = padding.saturating_sub(if neg || blank || sign { 1 } else { 0 });330331 let pref_len = zero_prefix.len() as u16;328 let zp2 = zp332 let zp2 = zp333 .saturating_sub(if !prefix_in_padding { pref_len } else { 0 })329 .max(precision)334 .max(precision)330 .saturating_sub(prefix.len() + digits.len());335 .saturating_sub(if prefix_in_padding { pref_len } else { 0 } + digits.len() as u16);331336332 if neg {337 if neg {333 out.push('-');338 out.push('-');337 out.push(' ');342 out.push(' ');338 }343 }339344340 out.reserve(zp2);345 out.reserve(zp2 as usize);346 if iv != 0 {347 out.push_str(zero_prefix);348 }341 for _ in 0..zp2 {349 for _ in 0..zp2 {342 out.push('0');350 out.push('0');343 }351 }344 out.push_str(prefix);345352346 for digit in digits.into_iter().rev() {353 for digit in digits.into_iter().rev() {347 let ch = NUMBERS[digit as usize] as char;354 let ch = NUMBERS[digit as usize] as char;351358352pub fn render_decimal(359pub fn render_decimal(353 out: &mut String,360 out: &mut String,361 neg: bool,354 iv: f64,362 iv: f64,355 padding: usize,363 padding: u16,356 precision: usize,364 precision: u16,357 blank: bool,365 blank: bool,358 sign: bool,366 sign: bool,359) {367) {360 render_integer(out, iv, padding, precision, blank, sign, 10, "", false);368 render_integer(369 out, neg, iv, padding, precision, blank, sign, 10, "", false, false,370 );361}371}362pub fn render_octal(372pub fn render_octal(363 out: &mut String,373 out: &mut String,374 neg: bool,364 iv: f64,375 iv: f64,365 padding: usize,376 padding: u16,366 precision: usize,377 precision: u16,367 alt: bool,378 alt: bool,368 blank: bool,379 blank: bool,369 sign: bool,380 sign: bool,370) {381) {371 render_integer(382 render_integer(372 out,383 out,384 neg,373 iv,385 iv,374 padding,386 padding,375 precision,387 precision,376 blank,388 blank,377 sign,389 sign,378 8,390 8,379 if alt && iv != 0.0 { "0" } else { "" },391 if alt && iv != 0.0 { "0" } else { "" },392 true,380 false,393 false,381 );394 );382}395}385pub fn render_hexadecimal(398pub fn render_hexadecimal(386 out: &mut String,399 out: &mut String,387 iv: f64,400 iv: f64,388 padding: usize,401 padding: u16,389 precision: usize,402 precision: u16,390 alt: bool,403 alt: bool,391 blank: bool,404 blank: bool,392 sign: bool,405 sign: bool,393 caps: bool,406 caps: bool,394) {407) {395 render_integer(408 render_integer(396 out,409 out,397 iv,410 iv < 0.0,411 iv.abs(),398 padding,412 padding,399 precision,413 precision,400 blank,414 blank,405 (true, false) => "0x",419 (true, false) => "0x",406 (false, _) => "",420 (false, _) => "",407 },421 },422 false,408 caps,423 caps,409 );424 );410}425}413pub fn render_float(428pub fn render_float(414 out: &mut String,429 out: &mut String,415 n: f64,430 n: f64,416 mut padding: usize,431 mut padding: u16,417 precision: usize,432 precision: u16,418 blank: bool,433 blank: bool,419 sign: bool,434 sign: bool,420 ensure_pt: bool,435 ensure_pt: bool,421 trailing: bool,436 trailing: bool,422) {437) {438 // Represent the rounded number as an integer * 1/10**prec.439 // Note that it can also be equal to 10**prec and we'll need to carry440 // over to the wholes. We operate on the absolute numbers, so that we441 // don't have trouble with the rounding direction.442 let denominator = 10.0f64.powi(precision as i32);443 let numerator = n.abs() * denominator + 0.5;444 let whole = (numerator / denominator).floor();445 let frac = numerator.floor() % denominator;446423 #[allow(clippy::bool_to_int_with_if)]447 #[allow(clippy::bool_to_int_with_if)]424 let dot_size = if precision == 0 && !ensure_pt { 0 } else { 1 };448 let dot_size = if precision == 0 && !ensure_pt { 0 } else { 1 };425 padding = padding.saturating_sub(dot_size + precision);449 padding = padding.saturating_sub(dot_size + precision);426 render_decimal(out, n.floor(), padding, 0, blank, sign);450 render_decimal(out, n < 0.0, whole, padding, 0, blank, sign);427 if precision == 0 {451 if precision == 0 {428 if ensure_pt {452 if ensure_pt {429 out.push('.');453 out.push('.');430 }454 }431 return;455 return;432 }456 }433 let frac = n434 .fract()435 .mul_add(10.0_f64.powf(precision as f64), 0.5)436 .floor();437 if trailing || frac > 0.0 {457 if trailing || frac > 0.0 {438 out.push('.');458 out.push('.');439 let mut frac_str = String::new();459 let mut frac_str = String::new();440 render_decimal(&mut frac_str, frac, precision, 0, false, false);460 render_decimal(&mut frac_str, false, frac, precision, 0, false, false);441 let mut trim = frac_str.len();461 let mut trim = frac_str.len();442 if !trailing {462 if !trailing {443 for b in frac_str.as_bytes().iter().rev() {463 for b in frac_str.as_bytes().iter().rev() {458pub fn render_float_sci(478pub fn render_float_sci(459 out: &mut String,479 out: &mut String,460 n: f64,480 n: f64,461 mut padding: usize,481 mut padding: u16,462 precision: usize,482 precision: u16,463 blank: bool,483 blank: bool,464 sign: bool,484 sign: bool,465 ensure_pt: bool,485 ensure_pt: bool,466 trailing: bool,486 trailing: bool,467 caps: bool,487 caps: bool,468) {488) {469 let exponent = n.log10().floor();489 let exponent = if n == 0.0 {490 0.0491 } else {492 n.abs().log10().floor()493 };494470 let mantissa = if exponent as i16 == -324 {495 let mantissa = if exponent as i16 == -324 {471 n * 10.0 / 10.0_f64.powf(exponent + 1.0)496 n * 10.0 / 10.0_f64.powf(exponent + 1.0)472 } else {497 } else {473 n / 10.0_f64.powf(exponent)498 n / 10.0_f64.powf(exponent)474 };499 };475 let mut exponent_str = String::new();500 let mut exponent_str = String::new();476 render_decimal(&mut exponent_str, exponent, 3, 0, false, true);501 render_decimal(502 &mut exponent_str,503 exponent < 0.0,504 exponent.abs(),505 3,506 0,507 false,508 true,509 );477510478 // +1 for e511 // +1 for e479 padding = padding.saturating_sub(exponent_str.len() + 1);512 padding = padding.saturating_sub(exponent_str.len() as u16 + 1);480513481 render_float(514 render_float(482 out, mantissa, padding, precision, blank, sign, ensure_pt, trailing,515 out, mantissa, padding, precision, blank, sign, ensure_pt, trailing,490 out: &mut String,523 out: &mut String,491 value: &Val,524 value: &Val,492 code: &Code<'_>,525 code: &Code<'_>,493 width: usize,526 width: u16,494 precision: Option<usize>,527 precision: Option<u16>,495) -> Result<()> {528) -> Result<()> {496 let clfags = &code.cflags;529 let clfags = &code.cflags;497 let (fpprec, iprec) = precision.map_or((6, 0), |v| (v, v));530 let (fpprec, iprec) = precision.map_or((6, 0), |v| (v, v));510 let value = f64::from_untyped(value.clone())?;543 let value = f64::from_untyped(value.clone())?;511 render_decimal(544 render_decimal(512 &mut tmp_out,545 &mut tmp_out,513 value,546 value <= -1.0,547 value.abs(),514 padding,548 padding,515 iprec,549 iprec,516 clfags.blank,550 clfags.blank,521 let value = f64::from_untyped(value.clone())?;555 let value = f64::from_untyped(value.clone())?;522 render_octal(556 render_octal(523 &mut tmp_out,557 &mut tmp_out,524 value,558 value <= -1.0,559 value.abs(),525 padding,560 padding,526 iprec,561 iprec,527 clfags.alt,562 clfags.alt,589 code.caps,624 code.caps,590 );625 );591 } else {626 } else {592 let digits_before_pt = 1.max(exponent as usize + 1);627 let digits_before_pt = 1.max(exponent as u16 + 1);593 render_float(628 render_float(594 &mut tmp_out,629 &mut tmp_out,595 value,630 value,628 ConvTypeV::Percent => tmp_out.push('%'),663 ConvTypeV::Percent => tmp_out.push('%'),629 };664 };630665631 let padding = width.saturating_sub(tmp_out.len());666 let padding = width.saturating_sub(tmp_out.len() as u16);632667633 if !clfags.left {668 if !clfags.left {634 for _ in 0..padding {669 for _ in 0..padding {663 }698 }664 let value = &values[0];699 let value = &values[0];665 values = &values[1..];700 values = &values[1..];666 usize::from_untyped(value.clone())?701 u16::from_untyped(value.clone())?667 }702 }668 Width::Fixed(n) => n,703 Width::Fixed(n) => n,669 };704 };674 }709 }675 let value = &values[0];710 let value = &values[0];676 values = &values[1..];711 values = &values[1..];677 Some(usize::from_untyped(value.clone())?)712 Some(u16::from_untyped(value.clone())?)678 }713 }679 Some(Width::Fixed(n)) => Some(n),714 Some(Width::Fixed(n)) => Some(n),680 None => None,715 None => None,crates/jrsonnet-evaluator/src/typed/conversions.rsdiffbeforeafterboth120 }120 }121}121}122122123pub const MAX_SAFE_INTEGER: f64 = ((1u64 << (f64::MANTISSA_DIGITS + 1)) - 1) as f64;123pub const MAX_SAFE_INTEGER: f64 = ((1u64 << (f64::MANTISSA_DIGITS)) - 1) as f64;124pub const MIN_SAFE_INTEGER: f64 = -MAX_SAFE_INTEGER;124pub const MIN_SAFE_INTEGER: f64 = (-((1i64 << (f64::MANTISSA_DIGITS)) - 1)) as f64;125125126macro_rules! impl_int {126macro_rules! impl_int {127 ($($ty:ty)*) => {$(127 ($($ty:ty)*) => {$(crates/jrsonnet-evaluator/src/val.rsdiffbeforeafterboth22 function::FuncVal,22 function::FuncVal,23 gc::WithCapacityExt as _,23 gc::WithCapacityExt as _,24 manifest::{ManifestFormat, ToStringFormat},24 manifest::{ManifestFormat, ToStringFormat},25 typed::BoundedUsize,25 typed::{BoundedUsize, MAX_SAFE_INTEGER, MIN_SAFE_INTEGER},26 ObjValue, Result, Unbound, WeakObjValue,26 ObjValue, Result, Unbound, WeakObjValue,27};27};2828418 pub const fn get(&self) -> f64 {418 pub const fn get(&self) -> f64 {419 self.0419 self.0420 }420 }421 pub(crate) fn truncate_for_bitwise(&self) -> Result<i64> {422 if self.0 < MIN_SAFE_INTEGER || self.0 > dbg!(MAX_SAFE_INTEGER) {423 bail!("numberic value outside of safe integer range for bitwise operation");424 }425 Ok(self.0 as i64)426 }421}427}422impl PartialEq for NumValue {428impl PartialEq for NumValue {423 fn eq(&self, other: &Self) -> bool {429 fn eq(&self, other: &Self) -> bool {490 type Error = ConvertNumValueError;496 type Error = ConvertNumValueError;491 #[inline]497 #[inline]492 fn try_from(value: $ty) -> Result<Self, ConvertNumValueError> {498 fn try_from(value: $ty) -> Result<Self, ConvertNumValueError> {493 use crate::typed::conversions::{MIN_SAFE_INTEGER, MAX_SAFE_INTEGER};494 let value = value as f64;499 let value = value as f64;495 if value < MIN_SAFE_INTEGER {500 if value < MIN_SAFE_INTEGER {496 return Err(ConvertNumValueError::Underflow)501 return Err(ConvertNumValueError::Underflow)