Skip to content

Commit c35c72d

Browse files
committed
Marking the 'from_parts_unchecked' method as unsafe.
1 parent 3a6a78c commit c35c72d

File tree

5 files changed

+39
-35
lines changed

5 files changed

+39
-35
lines changed

src/number.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,16 @@ impl Number {
5050
///
5151
/// ```
5252
/// # use json::number::Number;
53-
/// let pi = Number::from_parts_unchecked(true, 3141592653589793, -15);
53+
/// let pi = unsafe { Number::from_parts_unchecked(true, 3141592653589793, -15) };
5454
///
5555
/// assert_eq!(pi, 3.141592653589793);
5656
/// ```
57+
///
58+
/// While this method is marked unsafe, it doesn't actually perform any unsafe operations.
59+
/// THe goal of the 'unsafe' is to deter from using this method in favor of its safe equivalent
60+
/// `from_parts`, at least in context when the associated performance cost is negligible.
5761
#[inline]
58-
pub fn from_parts_unchecked(positive: bool, mantissa: u64, exponent: i16) -> Self {
62+
pub unsafe fn from_parts_unchecked(positive: bool, mantissa: u64, exponent: i16) -> Self {
5963
Number {
6064
category: positive as u8,
6165
exponent: exponent,
@@ -81,7 +85,7 @@ impl Number {
8185
exponent += 1;
8286
mantissa /= 10;
8387
}
84-
Number::from_parts_unchecked(positive, mantissa, exponent)
88+
unsafe { Number::from_parts_unchecked(positive, mantissa, exponent) }
8589
}
8690

8791
/// Reverse to `from_parts` - obtain parts from an existing `Number`.

src/parser.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,7 @@ macro_rules! expect_fraction {
323323

324324
loop {
325325
if $parser.is_eof() {
326-
result = Number::from_parts_unchecked(true, $num, $e);
326+
result = unsafe { Number::from_parts_unchecked(true, $num, $e) };
327327
break;
328328
}
329329
let ch = $parser.read_byte();
@@ -352,7 +352,7 @@ macro_rules! expect_fraction {
352352
break;
353353
}
354354
_ => {
355-
result = Number::from_parts_unchecked(true, $num, $e);
355+
result = unsafe { Number::from_parts_unchecked(true, $num, $e) };
356356
break;
357357
}
358358
}
@@ -568,7 +568,7 @@ impl<'a> Parser<'a> {
568568
let mut e = 0i16;
569569
loop {
570570
if self.is_eof() {
571-
return Ok(Number::from_parts_unchecked(true, num, e));
571+
return Ok(unsafe { Number::from_parts_unchecked(true, num, e) });
572572
}
573573
let ch = self.read_byte();
574574
match ch {
@@ -593,7 +593,7 @@ impl<'a> Parser<'a> {
593593
}
594594
}
595595

596-
Ok(Number::from_parts_unchecked(true, num, e))
596+
Ok(unsafe { Number::from_parts_unchecked(true, num, e) })
597597
}
598598

599599
// Called in the rare case that a number with `e` notation has been
@@ -631,7 +631,7 @@ impl<'a> Parser<'a> {
631631
}
632632
}
633633

634-
Ok(Number::from_parts_unchecked(true, num, (big_e.saturating_add(e * sign))))
634+
Ok(unsafe { Number::from_parts_unchecked(true, num, (big_e.saturating_add(e * sign))) })
635635
}
636636

637637
// Parse away!

tests/number.rs

+22-22
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,12 @@ fn is_nan() {
1212
#[test]
1313
fn is_zero() {
1414
assert!(Number::from(0).is_zero());
15-
assert!(Number::from_parts_unchecked(true, 0, 0).is_zero());
16-
assert!(Number::from_parts_unchecked(true, 0, 100).is_zero());
17-
assert!(Number::from_parts_unchecked(true, 0, -100).is_zero());
18-
assert!(Number::from_parts_unchecked(false, 0, 0).is_zero());
19-
assert!(Number::from_parts_unchecked(false, 0, 100).is_zero());
20-
assert!(Number::from_parts_unchecked(false, 0, -100).is_zero());
15+
assert!(unsafe { Number::from_parts_unchecked(true, 0, 0).is_zero() });
16+
assert!(unsafe { Number::from_parts_unchecked(true, 0, 100).is_zero() });
17+
assert!(unsafe { Number::from_parts_unchecked(true, 0, -100).is_zero() });
18+
assert!(unsafe { Number::from_parts_unchecked(false, 0, 0).is_zero() });
19+
assert!(unsafe { Number::from_parts_unchecked(false, 0, 100).is_zero() });
20+
assert!(unsafe { Number::from_parts_unchecked(false, 0, -100).is_zero() });
2121
assert!(!Number::from(f64::NAN).is_zero());
2222
}
2323

@@ -30,66 +30,66 @@ fn is_empty() {
3030
#[test]
3131
fn eq() {
3232
assert_eq!(
33-
Number::from_parts_unchecked(true, 500, 0),
34-
Number::from_parts_unchecked(true, 500, 0)
33+
unsafe { Number::from_parts_unchecked(true, 500, 0) },
34+
unsafe { Number::from_parts_unchecked(true, 500, 0) }
3535
);
3636
}
3737

3838
#[test]
3939
fn eq_normalize_left_positive() {
4040
assert_eq!(
41-
Number::from_parts_unchecked(true, 5, 2),
42-
Number::from_parts_unchecked(true, 500, 0)
41+
unsafe { Number::from_parts_unchecked(true, 5, 2) },
42+
unsafe { Number::from_parts_unchecked(true, 500, 0) }
4343
);
4444
}
4545

4646
#[test]
4747
fn eq_normalize_left_negative() {
4848
assert_eq!(
49-
Number::from_parts_unchecked(true, 5, -2),
50-
Number::from_parts_unchecked(true, 500, -4)
49+
unsafe { Number::from_parts_unchecked(true, 5, -2) },
50+
unsafe { Number::from_parts_unchecked(true, 500, -4) }
5151
);
5252
}
5353

5454
#[test]
5555
fn eq_normalize_right_positive() {
5656
assert_eq!(
57-
Number::from_parts_unchecked(true, 500, 0),
58-
Number::from_parts_unchecked(true, 5, 2)
57+
unsafe { Number::from_parts_unchecked(true, 500, 0) },
58+
unsafe { Number::from_parts_unchecked(true, 5, 2) }
5959
);
6060
}
6161

6262
#[test]
6363
fn eq_normalize_right_negative() {
6464
assert_eq!(
65-
Number::from_parts_unchecked(true, 500, -4),
66-
Number::from_parts_unchecked(true, 5, -2)
65+
unsafe { Number::from_parts_unchecked(true, 500, -4) },
66+
unsafe { Number::from_parts_unchecked(true, 5, -2) }
6767
);
6868
}
6969

7070
#[test]
7171
fn from_small_float() {
72-
assert_eq!(Number::from(0.05), Number::from_parts_unchecked(true, 5, -2));
72+
assert_eq!(Number::from(0.05), unsafe { Number::from_parts_unchecked(true, 5, -2) });
7373
}
7474

7575
#[test]
7676
fn from_very_small_float() {
77-
assert_eq!(Number::from(5e-50), Number::from_parts_unchecked(true, 5, -50));
77+
assert_eq!(Number::from(5e-50), unsafe { Number::from_parts_unchecked(true, 5, -50) });
7878
}
7979

8080
#[test]
8181
fn from_big_float() {
82-
assert_eq!(Number::from(500), Number::from_parts_unchecked(true, 500, 0));
82+
assert_eq!(Number::from(500), unsafe { Number::from_parts_unchecked(true, 500, 0) });
8383
}
8484

8585
#[test]
8686
fn from_very_big_float() {
87-
assert_eq!(Number::from(5e50), Number::from_parts_unchecked(true, 5, 50));
87+
assert_eq!(Number::from(5e50), unsafe { Number::from_parts_unchecked(true, 5, 50) });
8888
}
8989

9090
#[test]
9191
fn into_very_small_float() {
92-
let number = Number::from_parts_unchecked(true, 2225073858507201136, -326);
92+
let number = unsafe { Number::from_parts_unchecked(true, 2225073858507201136, -326) };
9393

9494
assert_eq!(f64::from(number), 2.225073858507201e-308);
9595
}
@@ -124,5 +124,5 @@ fn as_fixed_point_i64() {
124124

125125
#[test]
126126
fn convert_f64_precision() {
127-
assert_eq!(Number::from_parts_unchecked(true, 4750000000000001, -18), 0.004750000000000001);
127+
assert_eq!(unsafe { Number::from_parts_unchecked(true, 4750000000000001, -18) }, 0.004750000000000001);
128128
}

tests/parse.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,14 @@ fn parse_very_long_float() {
4747
assert_eq!(parsed.as_f64().unwrap(), 2.225073858507201e-308);
4848

4949
// Exhausts u64
50-
assert_eq!(parsed, Number::from_parts_unchecked(true, 2225073858507201136, -326));
50+
assert_eq!(parsed, unsafe { Number::from_parts_unchecked(true, 2225073858507201136, -326) });
5151
}
5252

5353
#[test]
5454
fn parse_very_long_exponent() {
5555
let parsed = parse("1e999999999999999999999999999999999999999999999999999999999999").unwrap();
5656

57-
assert_eq!(parsed, Number::from_parts_unchecked(true, 1, 32767));
57+
assert_eq!(parsed, unsafe { Number::from_parts_unchecked(true, 1, 32767) });
5858
}
5959

6060
#[test]

tests/print_dec.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,19 @@ use json::number::Number;
44

55
#[test]
66
fn issue_107() {
7-
let n = Number::from_parts_unchecked(true, 1, -32768);
7+
let n = unsafe { Number::from_parts_unchecked(true, 1, -32768) };
88
assert_eq!(format!("{}", n), "1e-32768");
99
}
1010

1111
#[test]
1212
fn issue_108_exponent_positive() {
13-
let n = Number::from_parts_unchecked(true, 10_000_000_000_000_000_001, -18);
13+
let n = unsafe { Number::from_parts_unchecked(true, 10_000_000_000_000_000_001, -18) };
1414
assert_eq!(format!("{}", n), "1.0000000000000000001e+1");
1515
}
1616

1717
#[test]
1818
fn issue_108_exponent_0() {
19-
let n = Number::from_parts_unchecked(true, 10_000_000_000_000_000_001, -19);
19+
let n = unsafe { Number::from_parts_unchecked(true, 10_000_000_000_000_000_001, -19) };
2020
assert_eq!(format!("{}", n), "1.0000000000000000001");
2121
}
2222

0 commit comments

Comments
 (0)