Advertisement
Guest User

Untitled

a guest
Oct 17th, 2019
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.99 KB | None | 0 0
  1. use std::io::{BufReader, BufRead, Error};
  2. use std::num::ParseIntError;
  3. use std::fmt;
  4.  
  5. #[derive(Debug)]
  6. enum ParseError {
  7. IoError(Error),
  8. ParseIntError(ParseIntError),
  9. UnexpectedEndOfLine,
  10. }
  11. impl std::error::Error for ParseError { }
  12. impl fmt::Display for ParseError {
  13. fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
  14. match self {
  15. ParseError::IoError(err) => fmt::Display::fmt(err, f),
  16. ParseError::ParseIntError(err) => fmt::Display::fmt(err, f),
  17. ParseError::UnexpectedEndOfLine => write!(f, "Unexpected end of line."),
  18. }
  19. }
  20. }
  21. impl From<Error> for ParseError {
  22. fn from(err: Error) -> ParseError {
  23. ParseError::IoError(err)
  24. }
  25. }
  26. impl From<ParseIntError> for ParseError {
  27. fn from(err: ParseIntError) -> ParseError {
  28. ParseError::ParseIntError(err)
  29. }
  30. }
  31.  
  32. struct Parser<R: BufRead> {
  33. input: R,
  34. line_buf: String,
  35. }
  36.  
  37. #[derive(Debug, PartialEq, Eq)]
  38. struct LogEntry<'a> {
  39. first: &'a str,
  40. second: &'a str,
  41. third: &'a str,
  42. brackets: &'a str,
  43. quotes_1: &'a str,
  44. int1: u32,
  45. int2: u32,
  46. quotes_2: &'a str,
  47. quotes_3: &'a str,
  48. }
  49.  
  50. #[inline]
  51. fn next_char(buf: &[u8], b: u8, i: &mut usize) -> Result<usize, ParseError> {
  52. while let Some(b2) = buf.get(*i) {
  53. *i += 1;
  54. if b == *b2 {
  55. return Ok(*i);
  56. }
  57. }
  58. Err(ParseError::UnexpectedEndOfLine)
  59. }
  60.  
  61. impl<R: BufRead> Parser<R> {
  62. pub fn new(input: R) -> Self {
  63. Self {
  64. input,
  65. line_buf: String::new(),
  66. }
  67. }
  68. pub fn next_entry(&mut self) -> Result<Option<LogEntry>, ParseError> {
  69. self.line_buf.clear();
  70. if self.input.read_line(&mut self.line_buf)? == 0 {
  71. return Ok(None);
  72. }
  73.  
  74. let mut i = 0;
  75. let first_space = next_char(self.line_buf.as_bytes(), b' ', &mut i)?;
  76. let second_space = next_char(self.line_buf.as_bytes(), b' ', &mut i)?;
  77. let third_space = next_char(self.line_buf.as_bytes(), b' ', &mut i)?;
  78. let start_paren = next_char(self.line_buf.as_bytes(), b'[', &mut i)?;
  79. let end_paren = next_char(self.line_buf.as_bytes(), b']', &mut i)?;
  80. let quote_1_s = next_char(self.line_buf.as_bytes(), b'"', &mut i)?;
  81. let quote_1_e = next_char(self.line_buf.as_bytes(), b'"', &mut i)?;
  82. i += 1;
  83. let i1_end = next_char(self.line_buf.as_bytes(), b' ', &mut i)?;
  84. let i2_end = next_char(self.line_buf.as_bytes(), b' ', &mut i)?;
  85. let quote_2_s = next_char(self.line_buf.as_bytes(), b'"', &mut i)?;
  86. let quote_2_e = next_char(self.line_buf.as_bytes(), b'"', &mut i)?;
  87. let quote_3_s = next_char(self.line_buf.as_bytes(), b'"', &mut i)?;
  88. let quote_3_e = next_char(self.line_buf.as_bytes(), b'"', &mut i)?;
  89.  
  90. Ok(Some(LogEntry {
  91. first: &self.line_buf[..first_space-1],
  92. second: &self.line_buf[first_space..second_space-1],
  93. third: &self.line_buf[second_space..third_space-1],
  94. brackets: &self.line_buf[start_paren..end_paren-1],
  95. quotes_1: &self.line_buf[quote_1_s..quote_1_e-1],
  96. int1: self.line_buf[quote_1_e+1..i1_end-1].parse()?,
  97. int2: self.line_buf[i1_end..i2_end-1].parse()?,
  98. quotes_2: &self.line_buf[quote_2_s..quote_2_e-1],
  99. quotes_3: &self.line_buf[quote_3_s..quote_3_e-1],
  100. }))
  101. }
  102. }
  103.  
  104. fn main() {
  105. let stdin = std::io::stdin();
  106. let mut parser = Parser::new(BufReader::new(stdin.lock()));
  107.  
  108. // To test it I created a file with 64000 lines of this:
  109. // abc def akd [weioru] "ASDEWR AQcc" 39278432 1023834 "x7v7cx 3" "kasodi"
  110. let expected = LogEntry {
  111. first: "abc",
  112. second: "def",
  113. third: "akd",
  114. brackets: "weioru",
  115. quotes_1: "ASDEWR AQcc",
  116. int1: 39278432,
  117. int2: 1023834,
  118. quotes_2: "x7v7cx 3",
  119. quotes_3: "kasodi",
  120. };
  121.  
  122. while let Some(entry) = parser.next_entry().unwrap() {
  123. assert_eq!(expected, entry);
  124. println!("{}", parser.line_buf);
  125. }
  126.  
  127. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement