1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
#![warn(missing_docs)] #![warn(missing_doc_code_examples)] //! use std::error::Error; mod tokenizer; mod parser; pub mod structs; pub mod prelude; #[cfg(feature = "nostd")] /// Parses the provided String into an instance of `Content` /// /// The method will deconstruct the provided data, turning it into a special, serialization free structure `Content` /// /// [`content`] the CSV data to parse /// [`delimiter`] The delimiter used in the data, for example a pipe (`|`) or a tab (` `) /// [`has_headers`] If the data's first line contains the titles of each column or not /// /// [`content`]: #parse.content /// [`delimiter`]: #parse.delimiter /// [`has_headers`]: #parse.has_headers /// /// # Examples /// /// Basic usage: /// ```no_run /// use rustsv::prelude::*; /// // Create our input data /// let input: String = "surname,initial,address,phone number\ /// Smith,A,\"14 Made up Drive, Made up City, Ohio\",216-235-3744\ /// Doe,J,\"15 Fake Street, Phonyville, Texas\",210-214-5737".to_string(); /// /// // Parse the `input` into `Content` /// let content: Content = parse(input, ',', true); /// ``` pub fn parse<A>(content: A, delimiter: char, has_headers: bool) -> structs::Content where A: Into<String> { let tree = tokenizer::tokenize(delimiter, content.into()); let body = parser::parse(tree, has_headers); body } #[cfg(feature = "std")] /// Reads a file and parses it into an instance of `Content` /// /// The method takes a path to a file, and then deconstructs the data, turning it into a special, serialization free structure `Content` /// /// [`content`] the CSV data to parse /// [`delimiter`] The delimiter used in the data, for example a pipe (`|`) or a tab (` `) /// [`has_headers`] If the data's first line contains the titles of each column or not /// /// [`content`]: #parse.content /// [`delimiter`]: #parse.delimiter /// [`has_headers`]: #parse.has_headers /// /// # Examples /// /// Basic usage: /// ```no_run /// use rustsv::prelude::*; /// // Parse the `input` into `Content` /// let content: Content = read("./path/to/file.csv", ',', true)?; /// ``` pub fn read<A>(path: A, delimiter: char, has_headers: bool) -> Result<structs::Content, Box<dyn Error>> where A: Into<String> { let file = std::fs::read_to_string(path.into()); return if file.is_ok() { let c = file.unwrap(); Ok(parse(c, delimiter, has_headers)) } else { Err(Box::new(file.unwrap_err())) }; } #[cfg(test)] mod tests { use crate::prelude::*; #[test] // CSV sample file is provided free of charge by EForExcel (http://eforexcel.com/wp/downloads-18-sample-csv-files-data-sets-for-testing-sales/) fn test_parsing() { let csv = crate::parse("Region,Country,Item Type,Sales Channel,Order Priority,Order Date,Order ID,Ship Date,Units Sold,Unit Price,Unit Cost,Total Revenue,Total Cost,Total Profit\nAustralia and Oceania,Tuvalu,Baby Food,Offline,H,5/28/2010,669165933,6/27/2010,9925,255.28,159.42,2533654.00,1582243.50,951410.50\nCentral America and the Caribbean,Grenada,Cereal,Online,C,8/22/2012,963881480,9/15/2012,2804,205.70,117.11,576782.80,328376.44,248406.36", ',', true); assert_eq!(csv[0]["Region"], String::from("Australia and Oceania")); } #[test] // CSV sample file is provided free of charge by EForExcel (http://eforexcel.com/wp/downloads-18-sample-csv-files-data-sets-for-testing-sales/) fn test_parsing_iter() { let csv = crate::parse("Region,Country,Item Type,Sales Channel,Order Priority,Order Date,Order ID,Ship Date,Units Sold,Unit Price,Unit Cost,Total Revenue,Total Cost,Total Profit\nAustralia and Oceania,Tuvalu,Baby Food,Offline,H,5/28/2010,669165933,6/27/2010,9925,255.28,159.42,2533654.00,1582243.50,951410.50\nCentral America and the Caribbean,Grenada,Cereal,Online,C,8/22/2012,963881480,9/15/2012,2804,205.70,117.11,576782.80,328376.44,248406.36", ',', true); assert_eq!(csv[0]["Region"], String::from("Australia and Oceania")); for entry in csv { for reference in entry { println!("{}: {}", reference.0, reference.1); } } } #[test] fn test_random_func() { let input: String = "first,middle,last\ntom,bob,scott".to_string(); let content: Content = parse(input, ',', true); println!("Hello, world! content = {:?} content2 = {:?}", content.get(2).is_some(), content[0]); assert_eq!(1, 1); } }