1 //! Traits that provide format-dependent data for floating parsing algorithms. 2 3 use crate::util::*; 4 5 #[cfg(feature = "correct")] 6 use super::exponent::*; 7 8 /// Private data interface for local utilities. 9 pub(crate) trait FastDataInterfaceImpl<'a>: Sized { 10 /// Get integer component of float. integer(&self) -> &'a [u8]11 fn integer(&self) -> &'a [u8]; 12 13 /// Set integer component of float. set_integer(&mut self, integer: &'a [u8])14 fn set_integer(&mut self, integer: &'a [u8]); 15 16 /// Get fraction component of float. fraction(&self) -> Option<&'a [u8]>17 fn fraction(&self) -> Option<&'a [u8]>; 18 19 /// Set fraction component of float. set_fraction(&mut self, fraction: Option<&'a [u8]>)20 fn set_fraction(&mut self, fraction: Option<&'a [u8]>); 21 22 /// Get exponent component of float. exponent(&self) -> Option<&'a [u8]>23 fn exponent(&self) -> Option<&'a [u8]>; 24 25 /// Set exponent component of float. set_exponent(&mut self, exponent: Option<&'a [u8]>)26 fn set_exponent(&mut self, exponent: Option<&'a [u8]>); 27 28 /// Get raw exponent component of float. raw_exponent(&self) -> i3229 fn raw_exponent(&self) -> i32; 30 31 /// Set raw exponent component of float. set_raw_exponent(&mut self, raw_exponent: i32)32 fn set_raw_exponent(&mut self, raw_exponent: i32); 33 } 34 35 /// Private data interface for local utilities. 36 #[cfg(feature = "correct")] 37 pub(crate) trait SlowDataInterfaceImpl<'a>: Sized { 38 /// Get integer component of float. integer(&self) -> &'a [u8]39 fn integer(&self) -> &'a [u8]; 40 41 /// Set integer component of float. set_integer(&mut self, integer: &'a [u8])42 fn set_integer(&mut self, integer: &'a [u8]); 43 44 /// Get fraction component of float. fraction(&self) -> &'a [u8]45 fn fraction(&self) -> &'a [u8]; 46 47 /// Set fraction component of float. set_fraction(&mut self, fraction: &'a [u8])48 fn set_fraction(&mut self, fraction: &'a [u8]); 49 50 /// Get raw exponent component of float. raw_exponent(&self) -> i3251 fn raw_exponent(&self) -> i32; 52 53 /// Set raw exponent component of float. set_raw_exponent(&mut self, raw_exponent: i32)54 fn set_raw_exponent(&mut self, raw_exponent: i32); 55 } 56 57 // Implement FastDataInterfaceImpl for a default structure. 58 macro_rules! fast_data_interface_impl { 59 ($name:ident) => ( 60 impl<'a> FastDataInterfaceImpl<'a> for $name<'a> { 61 perftools_inline!{ 62 fn integer(&self) -> &'a [u8] { 63 self.integer 64 }} 65 66 perftools_inline!{ 67 fn set_integer(&mut self, integer: &'a [u8]) { 68 self.integer = integer 69 }} 70 71 perftools_inline!{ 72 fn fraction(&self) -> Option<&'a [u8]> { 73 self.fraction 74 }} 75 76 perftools_inline!{ 77 fn set_fraction(&mut self, fraction: Option<&'a [u8]>) { 78 self.fraction = fraction 79 }} 80 81 perftools_inline!{ 82 fn exponent(&self) -> Option<&'a [u8]> { 83 self.exponent 84 }} 85 86 perftools_inline!{ 87 fn set_exponent(&mut self, exponent: Option<&'a [u8]>) { 88 self.exponent = exponent 89 }} 90 91 perftools_inline!{ 92 fn raw_exponent(&self) -> i32 { 93 self.raw_exponent 94 }} 95 96 perftools_inline!{ 97 fn set_raw_exponent(&mut self, raw_exponent: i32) { 98 self.raw_exponent = raw_exponent 99 }} 100 } 101 ); 102 } 103 104 // Implement SlowDataInterfaceImpl for a default structure. 105 #[cfg(feature = "correct")] 106 macro_rules! slow_data_interface_impl { 107 ($name:ident) => ( 108 impl<'a> SlowDataInterfaceImpl<'a> for $name<'a> { 109 perftools_inline!{ 110 fn integer(&self) -> &'a [u8] { 111 self.integer 112 }} 113 114 perftools_inline!{ 115 fn set_integer(&mut self, integer: &'a [u8]) { 116 self.integer = integer 117 }} 118 119 perftools_inline!{ 120 fn fraction(&self) -> &'a [u8] { 121 self.fraction 122 }} 123 124 perftools_inline!{ 125 fn set_fraction(&mut self, fraction: &'a [u8]) { 126 self.fraction = fraction 127 }} 128 129 perftools_inline!{ 130 fn raw_exponent(&self) -> i32 { 131 self.raw_exponent 132 }} 133 134 perftools_inline!{ 135 fn set_raw_exponent(&mut self, raw_exponent: i32) { 136 self.raw_exponent = raw_exponent 137 }} 138 } 139 ); 140 } 141 142 // PUBLIC 143 144 /// Data interface for fast float parsers. 145 pub(crate) trait FastDataInterface<'a>: FastDataInterfaceImpl<'a> { 146 /// Integer digits iterator type. 147 type IntegerIter: ConsumedIterator<Item=&'a u8> + AsPtrIterator<'a, u8>; 148 149 /// Float digits iterator type. 150 type FractionIter: ConsumedIterator<Item=&'a u8> + AsPtrIterator<'a, u8>; 151 152 /// Exponent digits iterator type. 153 type ExponentIter: ConsumedIterator<Item=&'a u8> + AsPtrIterator<'a, u8>; 154 155 /// Associated slow data type. 156 #[cfg(feature = "correct")] 157 type SlowInterface: SlowDataInterface<'a>; 158 159 /// Create new float data from format specification. new(format: NumberFormat) -> Self160 fn new(format: NumberFormat) -> Self; 161 162 // DATA 163 164 /// Iterate over all integer digits. integer_iter(&self) -> Self::IntegerIter165 fn integer_iter(&self) -> Self::IntegerIter; 166 167 /// Iterate over all fraction digits fraction_iter(&self) -> Self::FractionIter168 fn fraction_iter(&self) -> Self::FractionIter; 169 170 /// Iterate over all exponent digits exponent_iter(&self) -> Self::ExponentIter171 fn exponent_iter(&self) -> Self::ExponentIter; 172 173 /// Get the number format. format(&self) -> NumberFormat174 fn format(&self) -> NumberFormat; 175 176 perftools_inline!{ 177 /// Get the mantissa exponent from the raw exponent. 178 #[cfg(feature = "correct")] 179 fn mantissa_exponent(&self, truncated_digits: usize) -> i32 { 180 mantissa_exponent(self.raw_exponent(), self.fraction_iter().count(), truncated_digits) 181 }} 182 183 // EXTRACT 184 185 // Consume integer digits until a non-digit character is found. consume_integer_digits(&self, bytes: &'a [u8], radix: u32) -> (&'a [u8], &'a [u8])186 fn consume_integer_digits(&self, bytes: &'a [u8], radix: u32) -> (&'a [u8], &'a [u8]); 187 188 // Consume fraction digits until a non-digit character is found. consume_fraction_digits(&self, bytes: &'a [u8], radix: u32) -> (&'a [u8], &'a [u8])189 fn consume_fraction_digits(&self, bytes: &'a [u8], radix: u32) -> (&'a [u8], &'a [u8]); 190 191 // Extract the integer substring from the float. 192 perftools_inline!{ 193 fn extract_integer(&mut self, bytes: &'a [u8], radix: u32) 194 -> &'a [u8] 195 { 196 let result = self.consume_integer_digits(bytes, radix); 197 self.set_integer(result.0); 198 result.1 199 }} 200 201 // Extract the fraction substring from the float. 202 // 203 // Preconditions: 204 // `bytes.len()` >= 1 and `bytes[0] == b'.'`. 205 perftools_inline!{ 206 fn extract_fraction(&mut self, bytes: &'a [u8], radix: u32) 207 -> &'a [u8] 208 { 209 let digits = &index!(bytes[1..]); 210 let result = self.consume_fraction_digits(digits, radix); 211 self.set_fraction(Some(result.0)); 212 result.1 213 }} 214 215 // Extract and parse the exponent substring from the float. extract_exponent(&mut self, bytes: &'a [u8], radix: u32) -> &'a [u8]216 fn extract_exponent(&mut self, bytes: &'a [u8], radix: u32) -> &'a [u8]; 217 218 // Validate the extracted mantissa components. validate_mantissa(&self) -> ParseResult<()>219 fn validate_mantissa(&self) -> ParseResult<()>; 220 221 // Validate the extracted exponent component. validate_exponent(&self) -> ParseResult<()>222 fn validate_exponent(&self) -> ParseResult<()>; 223 224 // Validate the extracted exponent depending on the fraction component. validate_exponent_fraction(&self) -> ParseResult<()>225 fn validate_exponent_fraction(&self) -> ParseResult<()>; 226 227 // Validate the extracted exponent sign. validate_exponent_sign(&self) -> ParseResult<()>228 fn validate_exponent_sign(&self) -> ParseResult<()>; 229 230 // Trim leading 0s and digit separators. ltrim_zero(&self, bytes: &'a [u8]) -> (&'a [u8], usize)231 fn ltrim_zero(&self, bytes: &'a [u8]) -> (&'a [u8], usize); 232 233 // Trim leading digit separators. ltrim_separator(&self, bytes: &'a [u8]) -> (&'a [u8], usize)234 fn ltrim_separator(&self, bytes: &'a [u8]) -> (&'a [u8], usize); 235 236 // Trim trailing 0s and digit separators. rtrim_zero(&self, bytes: &'a [u8]) -> (&'a [u8], usize)237 fn rtrim_zero(&self, bytes: &'a [u8]) -> (&'a [u8], usize); 238 239 // Trim trailing digit separators. rtrim_separator(&self, bytes: &'a [u8]) -> (&'a [u8], usize)240 fn rtrim_separator(&self, bytes: &'a [u8]) -> (&'a [u8], usize); 241 242 // Post-process float to trim leading and trailing 0s and digit separators. 243 // This is required for accurate results in the slow-path algorithm, 244 // otherwise, we may incorrect guess the mantissa or scientific exponent. 245 perftools_inline!{ 246 fn trim(&mut self) { 247 self.set_integer(self.ltrim_zero(self.integer()).0); 248 self.set_fraction(self.fraction().map(|x| self.rtrim_zero(x).0)); 249 }} 250 251 perftools_inline!{ 252 /// Extract float subcomponents from input bytes. 253 fn extract(&mut self, bytes: &'a [u8], radix: u32) -> ParseResult<*const u8> { 254 // Parse the integer, aka, the digits preceding any control characters. 255 let mut digits = bytes; 256 digits = self.extract_integer(digits, radix); 257 258 // Parse and validate a fraction, if present. 259 let exp_char = exponent_notation_char(radix).to_ascii_lowercase(); 260 if let Some(&b'.') = digits.first() { 261 digits = self.extract_fraction(digits, radix); 262 } 263 self.validate_mantissa()?; 264 265 // Parse and validate an exponent, if present. 266 if let Some(&c) = digits.first() { 267 if c.to_ascii_lowercase() == exp_char { 268 digits = self.extract_exponent(digits, radix); 269 } 270 } 271 self.validate_exponent()?; 272 self.validate_exponent_fraction()?; 273 self.validate_exponent_sign()?; 274 275 // Trim the remaining digits. 276 self.trim(); 277 278 Ok(digits.as_ptr()) 279 }} 280 281 // TO SLOW DATA 282 283 // Calculate the digit start from the integer and fraction slices. 284 perftools_inline!{ 285 #[cfg(feature = "correct")] 286 fn digits_start(&self) -> usize { 287 // If there are no returned values in the integer iterator 288 // since we've trimmed leading 0s, then we have to trim 289 // leading zeros to get to the start of the significant 290 // digits in the fraction. 291 match self.integer().is_empty() { 292 true => self.ltrim_zero(self.fraction().unwrap_or(&[])).1, 293 false => 0, 294 } 295 }} 296 297 /// Process float data for moderate/slow float parsers. 298 #[cfg(feature = "correct")] to_slow(self, truncated_digits: usize) -> Self::SlowInterface299 fn to_slow(self, truncated_digits: usize) -> Self::SlowInterface; 300 301 // TESTS 302 303 #[cfg(test)] clear(&mut self)304 fn clear(&mut self) { 305 self.set_integer(&[]); 306 self.set_fraction(None); 307 self.set_exponent(None); 308 self.set_raw_exponent(0); 309 } 310 311 /// Check the float state parses the desired data. 312 #[cfg(test)] check_extract(&mut self, digits: &'a [u8], expected: &ParseTestResult<Self>)313 fn check_extract(&mut self, digits: &'a [u8], expected: &ParseTestResult<Self>) { 314 let expected = expected.as_ref(); 315 match self.extract(digits, 10) { 316 Ok(_) => { 317 let expected = expected.unwrap(); 318 assert_eq!(self.integer(), expected.integer()); 319 assert_eq!(self.fraction(), expected.fraction()); 320 assert_eq!(self.exponent(), expected.exponent()); 321 }, 322 Err((c, _)) => assert_eq!(c, *expected.err().unwrap()), 323 } 324 } 325 326 // Run series of tests. 327 #[cfg(test)] run_tests<Iter>(&mut self, tests: Iter) where Iter: Iterator<Item=&'a (&'a str, ParseTestResult<Self>)>, Self: 'a328 fn run_tests<Iter>(&mut self, tests: Iter) 329 where Iter: Iterator<Item=&'a (&'a str, ParseTestResult<Self>)>, 330 Self: 'a 331 { 332 for value in tests { 333 self.check_extract(value.0.as_bytes(), &value.1); 334 self.clear(); 335 } 336 } 337 } 338 339 /// Shared definition for all fast data interfaces. 340 macro_rules! fast_data_interface { 341 ( 342 struct $name:ident, 343 fields => { $( $field:ident : $type:tt, )* }, 344 integer_iter => ( $integer_iter:tt, $integer_iter_fn:ident ), 345 fraction_iter => ( $fraction_iter:tt, $fraction_iter_fn:ident ), 346 exponent_iter => ( $exponent_iter:tt, $exponent_iter_fn:ident ), 347 format => $format:expr, 348 slow_interface => $slow_interface:tt, 349 consume_integer_digits => $consume_integer_digits:expr, 350 consume_fraction_digits => $consume_fraction_digits:expr, 351 extract_exponent => $extract_exponent:expr, 352 validate_mantissa => $validate_mantissa:expr, 353 validate_exponent => $validate_exponent:expr, 354 validate_exponent_fraction => $validate_exponent_fraction:expr, 355 validate_exponent_sign => $validate_exponent_sign:expr, 356 ltrim_zero => $ltrim_zero:ident, 357 ltrim_separator => $ltrim_separator:ident, 358 rtrim_zero => $rtrim_zero:ident, 359 rtrim_separator => $rtrim_separator:ident, 360 new => $($new:tt)* 361 ) => ( 362 pub(crate) struct $name<'a> { 363 $( $field : $type, )* 364 integer: &'a [u8], 365 fraction: Option<&'a [u8]>, 366 exponent: Option<&'a [u8]>, 367 raw_exponent: i32 368 } 369 370 fast_data_interface_impl!($name); 371 372 impl<'a> FastDataInterface<'a> for $name<'a> { 373 type IntegerIter = $integer_iter<'a>; 374 type FractionIter = $fraction_iter<'a>; 375 type ExponentIter = $exponent_iter<'a>; 376 377 #[cfg(feature = "correct")] 378 type SlowInterface = $slow_interface<'a>; 379 380 perftools_inline!{ 381 #[allow(unused_variables)] 382 $($new)* 383 } 384 385 // DATA 386 387 perftools_inline!{ 388 fn integer_iter(&self) -> Self::IntegerIter { 389 $integer_iter_fn(self.integer, self.format().digit_separator()) 390 }} 391 392 perftools_inline!{ 393 fn fraction_iter(&self) -> Self::FractionIter { 394 let fraction = self.fraction.unwrap_or(&[]); 395 $fraction_iter_fn(fraction, self.format().digit_separator()) 396 }} 397 398 perftools_inline!{ 399 fn exponent_iter(&self) -> Self::ExponentIter { 400 let exponent = self.exponent.unwrap_or(&[]); 401 $exponent_iter_fn(exponent, self.format().digit_separator()) 402 }} 403 404 perftools_inline!{ 405 fn format(&self) -> NumberFormat { 406 $format(self) 407 }} 408 409 perftools_inline!{ 410 fn consume_integer_digits(&self, digits: &'a [u8], radix: u32) 411 -> (&'a [u8], &'a [u8]) 412 { 413 $consume_integer_digits(digits, radix, self.format()) 414 }} 415 416 perftools_inline!{ 417 fn consume_fraction_digits(&self, digits: &'a [u8], radix: u32) 418 -> (&'a [u8], &'a [u8]) 419 { 420 $consume_fraction_digits(digits, radix, self.format()) 421 }} 422 423 perftools_inline!{ 424 fn extract_exponent(&mut self, bytes: &'a [u8], radix: u32) -> &'a [u8] 425 { 426 $extract_exponent(self, bytes, radix, self.format()) 427 }} 428 429 perftools_inline!{ 430 fn validate_mantissa(&self) -> ParseResult<()> { 431 $validate_mantissa(self) 432 }} 433 434 perftools_inline!{ 435 fn validate_exponent(&self) -> ParseResult<()> { 436 $validate_exponent(self) 437 }} 438 439 perftools_inline!{ 440 fn validate_exponent_fraction(&self) -> ParseResult<()> { 441 $validate_exponent_fraction(self) 442 }} 443 444 perftools_inline!{ 445 fn validate_exponent_sign(&self) -> ParseResult<()> { 446 $validate_exponent_sign(self) 447 }} 448 449 perftools_inline!{ 450 fn ltrim_zero(&self, bytes: &'a [u8]) -> (&'a [u8], usize) { 451 $ltrim_zero(bytes, self.format().digit_separator()) 452 }} 453 454 perftools_inline!{ 455 fn ltrim_separator(&self, bytes: &'a [u8]) -> (&'a [u8], usize) { 456 $ltrim_separator(bytes, self.format().digit_separator()) 457 }} 458 459 perftools_inline!{ 460 fn rtrim_zero(&self, bytes: &'a [u8]) -> (&'a [u8], usize) { 461 $rtrim_zero(bytes, self.format().digit_separator()) 462 }} 463 464 perftools_inline!{ 465 fn rtrim_separator(&self, bytes: &'a [u8]) -> (&'a [u8], usize) { 466 $rtrim_separator(bytes, self.format().digit_separator()) 467 }} 468 469 // TO SLOW DATA 470 471 #[cfg(feature = "correct")] 472 perftools_inline!{ 473 fn to_slow(self, truncated_digits: usize) -> Self::SlowInterface { 474 let digits_start = self.digits_start(); 475 Self::SlowInterface { 476 $( $field: self.$field, )* 477 digits_start, 478 truncated_digits, 479 integer: self.integer, 480 fraction: self.fraction.unwrap_or(&[]), 481 raw_exponent: self.raw_exponent 482 } 483 }} 484 } 485 ); 486 } 487 488 /// Data interface for moderate/slow float parsers. 489 #[cfg(feature = "correct")] 490 pub(crate) trait SlowDataInterface<'a>: SlowDataInterfaceImpl<'a> { 491 /// Integer digits iterator type. 492 type IntegerIter: ConsumedIterator<Item=&'a u8> + AsPtrIterator<'a, u8>; 493 494 /// Float digits iterator type. 495 type FractionIter: ConsumedIterator<Item=&'a u8> + AsPtrIterator<'a, u8>; 496 497 /// Iterate over all integer digits. integer_iter(&self) -> Self::IntegerIter498 fn integer_iter(&self) -> Self::IntegerIter; 499 500 perftools_inline!{ 501 /// Get number of all integer digits. 502 fn integer_digits(&self) -> usize { 503 self.integer_iter().count() 504 }} 505 506 /// Iterate over all fraction digits fraction_iter(&self) -> Self::FractionIter507 fn fraction_iter(&self) -> Self::FractionIter; 508 509 perftools_inline!{ 510 /// Get number of all fraction digits. 511 fn fraction_digits(&self) -> usize { 512 self.fraction_iter().count() 513 }} 514 515 /// Iterate over significant fraction digits. significant_fraction_iter(&self) -> Self::FractionIter516 fn significant_fraction_iter(&self) -> Self::FractionIter; 517 518 perftools_inline!{ 519 /// Get number of significant fraction digits. 520 fn significant_fraction_digits(&self) -> usize { 521 self.significant_fraction_iter().count() 522 }} 523 524 perftools_inline!{ 525 /// Get the number of digits in the mantissa. 526 /// Cannot overflow, since this is based off a single usize input string. 527 fn mantissa_digits(&self) -> usize { 528 self.integer_digits() + self.significant_fraction_digits() 529 }} 530 531 /// Get the number format. format(&self) -> NumberFormat532 fn format(&self) -> NumberFormat; 533 534 /// Get index to start of significant digits in the fraction. digits_start(&self) -> usize535 fn digits_start(&self) -> usize; 536 537 /// Get number of truncated digits. truncated_digits(&self) -> usize538 fn truncated_digits(&self) -> usize; 539 540 perftools_inline!{ 541 /// Get the mantissa exponent from the raw exponent. 542 fn mantissa_exponent(&self) -> i32 { 543 mantissa_exponent(self.raw_exponent(), self.fraction_digits(), self.truncated_digits()) 544 }} 545 546 perftools_inline!{ 547 /// Get the scientific exponent from the raw exponent. 548 fn scientific_exponent(&self) -> i32 { 549 scientific_exponent(self.raw_exponent(), self.integer_digits(), self.digits_start()) 550 }} 551 } 552 553 /// Shared definition for all slow data interfaces. 554 macro_rules! slow_data_interface { 555 ( 556 struct $name:ident, 557 fields => { $( $field:ident : $type:tt, )* }, 558 integer_iter => ( $integer_iter:tt, $integer_iter_fn:ident ), 559 fraction_iter => ( $fraction_iter:tt, $fraction_iter_fn:ident ), 560 format => $format:expr 561 ) => ( 562 #[cfg(feature = "correct")] 563 pub(crate) struct $name<'a> { 564 $( $field : $type, )* 565 integer: &'a [u8], 566 fraction: &'a [u8], 567 digits_start: usize, 568 truncated_digits: usize, 569 raw_exponent: i32 570 } 571 572 #[cfg(feature = "correct")] 573 slow_data_interface_impl!($name); 574 575 #[cfg(feature = "correct")] 576 impl<'a> SlowDataInterface<'a> for $name<'a> { 577 type IntegerIter = $integer_iter<'a>; 578 type FractionIter = $fraction_iter<'a>; 579 580 // DATA 581 582 perftools_inline!{ 583 fn integer_iter(&self) -> Self::IntegerIter { 584 $integer_iter_fn(self.integer, self.format().digit_separator()) 585 }} 586 587 perftools_inline!{ 588 fn fraction_iter(&self) -> Self::FractionIter { 589 $fraction_iter_fn(self.fraction, self.format().digit_separator()) 590 }} 591 592 perftools_inline!{ 593 fn significant_fraction_iter(&self) -> Self::FractionIter { 594 let fraction = &index!(self.fraction[self.digits_start..]); 595 $fraction_iter_fn(fraction, self.format().digit_separator()) 596 }} 597 598 perftools_inline!{ 599 fn format(&self) -> NumberFormat { 600 $format(self) 601 }} 602 603 perftools_inline!{ 604 fn digits_start(&self) -> usize { 605 self.digits_start 606 }} 607 608 perftools_inline!{ 609 fn truncated_digits(&self) -> usize { 610 self.truncated_digits 611 }} 612 } 613 ); 614 } 615 616 /// Shared definition for all data interfaces. 617 macro_rules! data_interface { 618 ( 619 struct $fast:ident, 620 struct $slow:ident, 621 fields => { $( $field:ident : $type:tt, )* }, 622 integer_iter => ( $integer_iter:tt, $integer_iter_fn:ident ), 623 fraction_iter => ( $fraction_iter:tt, $fraction_iter_fn:ident ), 624 exponent_iter => ( $exponent_iter:tt, $exponent_iter_fn:ident ), 625 format => $format:expr, 626 consume_integer_digits => $consume_integer_digits:expr, 627 consume_fraction_digits => $consume_fraction_digits:expr, 628 extract_exponent => $extract_exponent:expr, 629 validate_mantissa => $validate_mantissa:expr, 630 validate_exponent => $validate_exponent:expr, 631 validate_exponent_fraction => $validate_exponent_fraction:expr, 632 validate_exponent_sign => $validate_exponent_sign:expr, 633 ltrim_zero => $ltrim_zero:ident, 634 ltrim_separator => $ltrim_separator:ident, 635 rtrim_zero => $rtrim_zero:ident, 636 rtrim_separator => $rtrim_separator:ident, 637 new => $($new:tt)* 638 ) => ( 639 fast_data_interface!( 640 struct $fast, 641 fields => { $( $field : $type , )* }, 642 integer_iter => ($integer_iter, $integer_iter_fn), 643 fraction_iter => ($fraction_iter, $fraction_iter_fn), 644 exponent_iter => ($exponent_iter, $exponent_iter_fn), 645 format => $format, 646 slow_interface => $slow, 647 consume_integer_digits => $consume_integer_digits, 648 consume_fraction_digits => $consume_fraction_digits, 649 extract_exponent => $extract_exponent, 650 validate_mantissa => $validate_mantissa, 651 validate_exponent => $validate_exponent, 652 validate_exponent_fraction => $validate_exponent_fraction, 653 validate_exponent_sign => $validate_exponent_sign, 654 ltrim_zero => $ltrim_zero, 655 ltrim_separator => $ltrim_separator, 656 rtrim_zero => $rtrim_zero, 657 rtrim_separator => $rtrim_separator, 658 new => $($new)* 659 ); 660 661 slow_data_interface!( 662 struct $slow, 663 fields => { $( $field : $type , )* }, 664 integer_iter => ($integer_iter, $integer_iter_fn), 665 fraction_iter => ($fraction_iter, $fraction_iter_fn), 666 format => $format 667 ); 668 ); 669 } 670