diff --git a/dpts-core/src/csv.rs b/dpts-core/src/csv/mod.rs similarity index 52% rename from dpts-core/src/csv.rs rename to dpts-core/src/csv/mod.rs index 651c112..3a14503 100644 --- a/dpts-core/src/csv.rs +++ b/dpts-core/src/csv/mod.rs @@ -1,53 +1,29 @@ +mod reader; +mod record; +mod table; +mod writer; + +pub use reader::CsvReader; +pub use record::CsvRecord; +pub use table::CsvTable; +pub use writer::CsvWriter; + +use crate::error::Error; + use chrono::{DateTime, NaiveDateTime}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; - -#[derive(Debug, Deserialize, PartialEq, Serialize)] -pub struct CsvRecord{ - pub timestamp: NaiveDateTime, - #[serde(with = "string_to_escape")] - pub comment: String, - pub tag: String, - pub count: i32, -} - -pub mod string_to_escape { - use serde::{Deserialize, Deserializer, Serializer}; - - pub fn deserialize<'de, D>(d: D) -> Result - where D: Deserializer<'de> - { - Ok(String::deserialize(d)? - .replace("\\n", "\n") - .replace("\\t", "\t") - .replace("\\\"", "\"") - .replace("\\\\", "\\") - ) - } - pub fn serialize(s: &str, serializer: S) -> Result - where S: Serializer - { - serializer.serialize_str(&s - - .replace("\n", "\\n") - .replace("\t", "\\t") - .replace("\"", "\\\"") - .replace("\\", "\\\\") - ) - } -} - - - #[cfg(test)] pub mod tests { use super::*; use chrono::{NaiveDate, NaiveTime}; const RECORD_CSV:&str = r#"timestamp,comment,tag,count -2025-05-01T12:34:56,test\ntest,test,1"#; +2025-05-01T12:34:56,"test +test",test,1 +"#; - fn get_record_struct() -> Vec{ + fn get_records() -> Vec{ vec![CsvRecord { timestamp: NaiveDate::from_ymd_opt(2025, 5, 1) .unwrap().and_hms_micro_opt(12, 34, 56, 0).unwrap(), @@ -58,16 +34,6 @@ test".to_owned(), }] } - #[test] - fn serialize_string() { - - } - - #[test] - fn deserialize_string() { - - } - #[test] fn deserialize_record() { println!("{:?}", RECORD_CSV); @@ -84,14 +50,18 @@ test".to_owned(), let record: CsvRecord = raw_record.deserialize(Some(&headers)).unwrap(); records.push(record); } - assert_eq!(records, get_record_struct()); + assert_eq!(records, get_records()); } #[test] fn serialize_record() { - todo!() + let buf : Vec = Vec::new(); + let mut wtr = csv::Writer::from_writer(buf); + for record in get_records().into_iter() { + wtr.serialize(record).unwrap(); + } + wtr.flush().unwrap(); + assert_eq!(RECORD_CSV, &String::from_utf8(wtr.into_inner().unwrap()).unwrap()) } - - } \ No newline at end of file diff --git a/dpts-core/src/csv/reader.rs b/dpts-core/src/csv/reader.rs new file mode 100644 index 0000000..e8b27bc --- /dev/null +++ b/dpts-core/src/csv/reader.rs @@ -0,0 +1,9 @@ +pub struct CsvReader { + inner: T, +} + +impl CsvReader { + pub fn into_inner(self) -> T { + self.inner + } +} diff --git a/dpts-core/src/csv/record.rs b/dpts-core/src/csv/record.rs new file mode 100644 index 0000000..a182316 --- /dev/null +++ b/dpts-core/src/csv/record.rs @@ -0,0 +1,19 @@ +use chrono::{DateTime, NaiveDateTime}; +use serde::{Deserialize, Deserializer, Serialize, Serializer}; + + + +#[derive(Debug, Deserialize, PartialEq, Serialize)] +pub struct CsvRecord{ + pub timestamp: NaiveDateTime, + pub comment: String, + pub tag: String, + pub count: i32, +} + +impl TryFrom for CsvRecord{ + type Error = crate::error::Error; + fn try_from(model: crate::entity::RecordDetailModel) -> Result { + todo!() + } +} \ No newline at end of file diff --git a/dpts-core/src/csv/table.rs b/dpts-core/src/csv/table.rs new file mode 100644 index 0000000..4f475c4 --- /dev/null +++ b/dpts-core/src/csv/table.rs @@ -0,0 +1,19 @@ +use crate::error::Error; +use super::CsvRecord; +pub struct CsvTable{ + inner: Vec +} + +impl CsvTable { + pub fn into_inner(self) -> Vec { + self.inner + } +} + +impl From> for CsvTable { + fn from(v: Vec) -> Self { + Self { + inner: v, + } + } +} \ No newline at end of file diff --git a/dpts-core/src/csv/writer.rs b/dpts-core/src/csv/writer.rs new file mode 100644 index 0000000..e8f46bc --- /dev/null +++ b/dpts-core/src/csv/writer.rs @@ -0,0 +1,9 @@ +pub struct CsvWriter { + inner: T +} + +impl CsvWriter { + pub fn into_inner(self) -> T { + self.inner + } +} \ No newline at end of file