Решение на CSV Filter от Мартин Великов

Обратно към всички решения

Към профила на Мартин Великов

Резултати

  • 0 точки от тестове
  • 0 бонус точки
  • 0 точки общо
  • 0 успешни тест(а)
  • 0 неуспешни тест(а)

Код

fn main() {
}
use std::io::{self, Read, BufRead, BufReader};
pub fn skip_next(input: &str, target: char) -> Option<&str> {
let input_helper = &input[..];
let mut chars = input.chars();
match input_helper.starts_with(target) {
true => {
let (_, last) = input.split_at(chars.next().unwrap().len_utf8());
Some(last) },
false => None,
}
}
pub fn take_until(input: &str, target: char) -> (&str, &str) {
let input2 = input.clone();
let input_iter=input.char_indices();
let mut index = 0;
for c in input_iter {
if c.1 == target {
index = c.0;
break;
}
}
let result = input.split_at(index);
let helper_element = input2.chars().next();
if result.1 == input && helper_element.is_none() == false && helper_element.unwrap() != target {
(input,"")
}else {
result
}
}
pub fn take_and_skip(input: &str, target: char) -> Option<(&str, &str)> {
let tuple_of_strings = take_until(input, target);
match tuple_of_strings.1 {
"" => None,
_ => {
if skip_next(tuple_of_strings.1, target).is_none() == false {
Some((tuple_of_strings.0, skip_next(tuple_of_strings.1, target).unwrap()))
} else {
None
}
},
}
}
#[derive(Debug)]
pub enum CsvError {
IO(std::io::Error),
ParseError(String),
InvalidHeader(String),
InvalidRow(String),
InvalidColumn(String),
}
use std::collections::HashMap;
type Row = HashMap<String, String>;
pub struct Csv<R: BufRead> {
pub columns: Vec<String>,
reader: R,
selection: Option<Box<dyn Fn(&Row) -> Result<bool, CsvError>>>,
}
use std::io::Write;
impl<R: BufRead> Csv<R> {
pub fn new(mut reader: R) -> Result<Self, CsvError> {
let mut buf = String::new();
let x = reader.read_line(&mut buf);
if x.is_ok() {
if x.unwrap() == 0 {
return Err(CsvError::InvalidHeader("No columns!".to_string()));
} else {
let first_line:String = String::from(buf);
&first_line.trim();
if first_line.starts_with("\"") {
return Err(CsvError::InvalidHeader("No columns!".to_string()));
}
let vec: Vec<&str> = first_line.split(',').map(|word| word.trim()).collect();
let mut temp_vec : Vec<String>=Vec::new();
for column in vec {
temp_vec.push(String::from(column));
}
let mut equal_columns : bool = false;
let mut i = 0;
let mut j : usize;
while i < temp_vec.len()-1 && equal_columns == false {
j=i+1;
while j < temp_vec.len() && equal_columns == false {
if temp_vec[i] == temp_vec[j] {
equal_columns = true;
}
j=j+1;
}
i=i+1;
}
match equal_columns {
true => return Err(CsvError::InvalidHeader("Equal columns".to_string())),
false => {
println!("{:?}", temp_vec);
let newCSV = Self {columns: temp_vec,
reader:reader,
selection: Some(Box::new(|_row|Ok(true))) };return Ok(newCSV);},
};
}
}else{
return Err(CsvError::IO(io::Error::new(io::ErrorKind::Other, "read_line error")));
}
}
pub fn parse_line(&mut self, line: &str) -> Result<Row, CsvError> {
println!("{:?}", line);
let mut trimmed_line = line.trim();
// println!("{:?}", &line.trim());
if !trimmed_line.starts_with("\"") {
return Err(CsvError::InvalidRow("Invalid Row".to_string()));
}
let mut map: HashMap<String, String> = HashMap::new();
let mut buf = String::new();
let mut stack:Vec<char> = Vec::new();
let mut quotes = 0;
let mut number_of_column = 0;
for c in trimmed_line.chars() {
if c!='\"' && quotes == 1 && !stack.is_empty() {
buf.push(c);
}else if c == '\"' && quotes == 1 {
stack.pop();
quotes-=1;
map.insert(String::from(self.columns[number_of_column].clone()), String::from(buf.clone()));
number_of_column+=1;
buf.clear();
} else if c == '\"' && quotes < 1 {
stack.push(c);
quotes = quotes +1;
}
}
if quotes == 0 && number_of_column == self.columns.len() {
return Ok(map);
}else {
return Err(CsvError::InvalidRow("Invalid Row".to_string()));
}
}
}

Лог от изпълнението

Compiling solution v0.1.0 (/tmp/d20210111-1538662-ge5asc/solution)
warning: unused imports: `BufReader`, `Read`
 --> src/lib.rs:5:21
  |
5 | use std::io::{self, Read, BufRead, BufReader};
  |                     ^^^^           ^^^^^^^^^
  |
  = note: `#[warn(unused_imports)]` on by default

warning: unused import: `std::io::Write`
  --> src/lib.rs:81:5
   |
81 | use std::io::Write;
   |     ^^^^^^^^^^^^^^

warning: variable does not need to be mutable
   --> src/lib.rs:135:12
    |
135 |        let mut trimmed_line = line.trim();
    |            ----^^^^^^^^^^^^
    |            |
    |            help: remove this `mut`
    |
    = note: `#[warn(unused_mut)]` on by default

warning: function is never used: `main`
 --> src/lib.rs:1:4
  |
1 | fn main() {     
  |    ^^^^
  |
  = note: `#[warn(dead_code)]` on by default

warning: field is never read: `reader`
  --> src/lib.rs:77:5
   |
77 |     reader: R,
   |     ^^^^^^^^^

warning: field is never read: `selection`
  --> src/lib.rs:78:5
   |
78 |     selection: Option<Box<dyn Fn(&Row) -> Result<bool, CsvError>>>,
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

warning: variable `newCSV` should have a snake case name
   --> src/lib.rs:121:21
    |
121 |                 let newCSV = Self {columns: temp_vec,
    |                     ^^^^^^ help: convert the identifier to snake case: `new_csv`
    |
    = note: `#[warn(non_snake_case)]` on by default

warning: 7 warnings emitted

error[E0599]: no method named `next` found for struct `solution::Csv<BufReader<&[u8]>>` in the current scope
  --> tests/solution_test.rs:70:23
   |
70 |         let row = csv.next().unwrap().unwrap();
   |                       ^^^^ method not found in `solution::Csv<BufReader<&[u8]>>`

error[E0599]: no method named `next` found for struct `solution::Csv<BufReader<&[u8]>>` in the current scope
  --> tests/solution_test.rs:76:21
   |
76 |         assert!(csv.next().is_none());
   |                     ^^^^ method not found in `solution::Csv<BufReader<&[u8]>>`

error[E0599]: no method named `map` found for struct `solution::Csv<BufReader<&[u8]>>` in the current scope
   --> tests/solution_test.rs:195:34
    |
195 |         let filtered_names = csv.map(|row| row.unwrap()["name"].clone()).collect::<Vec<_>>();
    |                                  ^^^ method not found in `solution::Csv<BufReader<&[u8]>>`
    | 
   ::: /tmp/d20210111-1538662-ge5asc/solution/src/lib.rs:75:1
    |
75  | pub struct Csv<R: BufRead> {
    | -------------------------- doesn't satisfy `solution::Csv<BufReader<&[u8]>>: Iterator`
    |
    = note: the method `map` exists but the following trait bounds were not satisfied:
            `solution::Csv<BufReader<&[u8]>>: Iterator`
            which is required by `&mut solution::Csv<BufReader<&[u8]>>: Iterator`

error[E0599]: no method named `write_to` found for struct `solution::Csv<BufReader<&[u8]>>` in the current scope
   --> tests/solution_test.rs:234:13
    |
234 |         csv.write_to(&mut output).unwrap();
    |             ^^^^^^^^ method not found in `solution::Csv<BufReader<&[u8]>>`

error[E0599]: no method named `apply_selection` found for struct `solution::Csv<BufReader<&[u8]>>` in the current scope
   --> tests/solution_test.rs:260:13
    |
260 |         csv.apply_selection(|row| Ok(row["name"].contains(".")));
    |             ^^^^^^^^^^^^^^^ method not found in `solution::Csv<BufReader<&[u8]>>`

error[E0599]: no method named `write_to` found for struct `solution::Csv<BufReader<&[u8]>>` in the current scope
   --> tests/solution_test.rs:263:13
    |
263 |         csv.write_to(&mut output).unwrap();
    |             ^^^^^^^^ method not found in `solution::Csv<BufReader<&[u8]>>`

error[E0599]: no method named `write_to` found for struct `solution::Csv<BufReader<&[u8]>>` in the current scope
   --> tests/solution_test.rs:285:13
    |
285 |         csv.write_to(&mut output).unwrap();
    |             ^^^^^^^^ method not found in `solution::Csv<BufReader<&[u8]>>`

error[E0599]: no method named `next` found for struct `solution::Csv<BufReader<&[u8]>>` in the current scope
   --> tests/solution_test.rs:180:17
    |
180 |     assert!(csv.next().is_none());
    |                 ^^^^ method not found in `solution::Csv<BufReader<&[u8]>>`

error[E0599]: no method named `apply_selection` found for struct `solution::Csv<BufReader<&[u8]>>` in the current scope
   --> tests/solution_test.rs:211:9
    |
211 |     csv.apply_selection(|row| {
    |         ^^^^^^^^^^^^^^^ method not found in `solution::Csv<BufReader<&[u8]>>`

error[E0599]: no method named `map` found for struct `solution::Csv<BufReader<&[u8]>>` in the current scope
   --> tests/solution_test.rs:218:30
    |
218 |     let filtered_names = csv.map(|row| row.unwrap()["name"].clone()).collect::<Vec<_>>();
    |                              ^^^ method not found in `solution::Csv<BufReader<&[u8]>>`
    | 
   ::: /tmp/d20210111-1538662-ge5asc/solution/src/lib.rs:75:1
    |
75  | pub struct Csv<R: BufRead> {
    | -------------------------- doesn't satisfy `solution::Csv<BufReader<&[u8]>>: Iterator`
    |
    = note: the method `map` exists but the following trait bounds were not satisfied:
            `solution::Csv<BufReader<&[u8]>>: Iterator`
            which is required by `&mut solution::Csv<BufReader<&[u8]>>: Iterator`

error: aborting due to 10 previous errors

For more information about this error, try `rustc --explain E0599`.
error: could not compile `solution`

To learn more, run the command again with --verbose.

История (2 версии и 0 коментара)

Мартин качи първо решение на 11.01.2021 13:23 (преди над 4 години)

Мартин качи решение на 11.01.2021 16:29 (преди над 4 години)

-fn main() {
-
+fn main() {
+
}
use std::io::{self, Read, BufRead, BufReader};
pub fn skip_next(input: &str, target: char) -> Option<&str> {
let input_helper = &input[..];
let mut chars = input.chars();
match input_helper.starts_with(target) {
true => {
let (_, last) = input.split_at(chars.next().unwrap().len_utf8());
Some(last) },
false => None,
}
}
pub fn take_until(input: &str, target: char) -> (&str, &str) {
let input2 = input.clone();
let input_iter=input.char_indices();
let mut index = 0;
for c in input_iter {
if c.1 == target {
index = c.0;
break;
}
}
let result = input.split_at(index);
let helper_element = input2.chars().next();
if result.1 == input && helper_element.is_none() == false && helper_element.unwrap() != target {
(input,"")
}else {
result
}
}
pub fn take_and_skip(input: &str, target: char) -> Option<(&str, &str)> {
let tuple_of_strings = take_until(input, target);
match tuple_of_strings.1 {
"" => None,
_ => {
if skip_next(tuple_of_strings.1, target).is_none() == false {
Some((tuple_of_strings.0, skip_next(tuple_of_strings.1, target).unwrap()))
} else {
None
}
},
}
}
#[derive(Debug)]
pub enum CsvError {
IO(std::io::Error),
ParseError(String),
InvalidHeader(String),
InvalidRow(String),
InvalidColumn(String),
}
use std::collections::HashMap;
type Row = HashMap<String, String>;
pub struct Csv<R: BufRead> {
pub columns: Vec<String>,
reader: R,
selection: Option<Box<dyn Fn(&Row) -> Result<bool, CsvError>>>,
}
use std::io::Write;
impl<R: BufRead> Csv<R> {
pub fn new(mut reader: R) -> Result<Self, CsvError> {
let mut buf = String::new();
let x = reader.read_line(&mut buf);
if x.is_ok() {
if x.unwrap() == 0 {
return Err(CsvError::InvalidHeader("No columns!".to_string()));
} else {
let first_line:String = String::from(buf);
- first_line.trim();
+ &first_line.trim();
if first_line.starts_with("\"") {
return Err(CsvError::InvalidHeader("No columns!".to_string()));
}
let vec: Vec<&str> = first_line.split(',').map(|word| word.trim()).collect();
let mut temp_vec : Vec<String>=Vec::new();
for column in vec {
temp_vec.push(String::from(column));
}
let mut equal_columns : bool = false;
let mut i = 0;
let mut j : usize;
while i < temp_vec.len()-1 && equal_columns == false {
j=i+1;
while j < temp_vec.len() && equal_columns == false {
if temp_vec[i] == temp_vec[j] {
equal_columns = true;
}
j=j+1;
}
i=i+1;
}
match equal_columns {
true => return Err(CsvError::InvalidHeader("Equal columns".to_string())),
false => {
-
+ println!("{:?}", temp_vec);
let newCSV = Self {columns: temp_vec,
reader:reader,
selection: Some(Box::new(|_row|Ok(true))) };return Ok(newCSV);},
};
}
}else{
return Err(CsvError::IO(io::Error::new(io::ErrorKind::Other, "read_line error")));
}
+ }
+
+
+ pub fn parse_line(&mut self, line: &str) -> Result<Row, CsvError> {
+ println!("{:?}", line);
+ let mut trimmed_line = line.trim();
+ // println!("{:?}", &line.trim());
+ if !trimmed_line.starts_with("\"") {
+ return Err(CsvError::InvalidRow("Invalid Row".to_string()));
+ }
+ let mut map: HashMap<String, String> = HashMap::new();
+ let mut buf = String::new();
+ let mut stack:Vec<char> = Vec::new();
+ let mut quotes = 0;
+ let mut number_of_column = 0;
+
+ for c in trimmed_line.chars() {
+
+ if c!='\"' && quotes == 1 && !stack.is_empty() {
+ buf.push(c);
+ }else if c == '\"' && quotes == 1 {
+ stack.pop();
+ quotes-=1;
+ map.insert(String::from(self.columns[number_of_column].clone()), String::from(buf.clone()));
+ number_of_column+=1;
+ buf.clear();
+ } else if c == '\"' && quotes < 1 {
+ stack.push(c);
+ quotes = quotes +1;
+ }
+
+
+ }
+ if quotes == 0 && number_of_column == self.columns.len() {
+ return Ok(map);
+ }else {
+ return Err(CsvError::InvalidRow("Invalid Row".to_string()));
+ }
}
}